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>
index | next in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807291730.KAA19962>
