Date: Wed, 29 Jul 1998 10:30:00 -0700 (PDT) From: dag-erli@ifi.uio.no (Dag-Erling Coidan =?iso-8859-1?Q?Sm=F8rgrav?= ) To: freebsd-bugs@FreeBSD.ORG Subject: Re: bin/7393: nailed Message-ID: <199807291730.KAA19962@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/7393; it has been noted by GNATS. From: dag-erli@ifi.uio.no (Dag-Erling Coidan =?iso-8859-1?Q?Sm=F8rgrav?= ) To: jhicks@glenatl.glenayre.com Cc: freebsd-gnats-submit@freebsd.org Subject: Re: bin/7393: nailed Date: 29 Jul 1998 19:29:44 +0200 On line 224 in /usr/src/usr.bin/du/du.c, there is the following piece of code which handles the -c flag: if (cflag) { p = savedp->fts_parent; (void) printf("%ld\ttotal\n", howmany(p->fts_number, blocksize)); } It relies on the fact that the code in the while loop above saves the value of p in savedp at every iteration, so that at the end of it, savedp points to the FTSENT for the last entry in the root directory (i.e. the one passed on the command line), and savedp->fts_parent points to FTSENT for the root directory itself. However, this assumption is incorrect. The problem arises when du traverses the root directory the second time, i.e. on the way down. fts_read() notices a) that it's on the way down, and b) that there's nothing left to do. Because of a) it frees the current FTSENT, and because of b) it frees the parent (root) FTSENT as well, on line 403 in /usr/src/lib/libc/gen/fts.c: /* Move up to the parent node. */ p = tmp->fts_parent; free(tmp); if (p->fts_level == FTS_ROOTPARENTLEVEL) { /* * Done; free everything up and set errno to 0 so the user * can distinguish between error and EOF. */ free(p); errno = 0; return (sp->fts_cur = NULL); } This means that the -c code in du.c tries to dereference a garbage pointer which even if it were not garbage *points* to garbage. Since there's no more malloc() activity after the last fts_read() until the end of the program, this kinda works - unless you have J in your malloc options, since in that case free() will overwrite the freed memory with garbage, to catch bugs like this one :) Conclusion: the -c option to du is broken as designed, since it relies on the contents of dynamically allocated memory which has been released. Now, off to write a fix for this. DES -- Dag-Erling Smørgrav - dag-erli@ifi.uio.no To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807291730.KAA19962>