Skip site navigation (1)Skip section navigation (2)
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>