Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
Bug 87490 - chmod memory leak
Summary: chmod memory leak
Status: RESOLVED FIXED
Alias: None
Product: Gentoo Linux
Classification: Unclassified
Component: [OLD] Core system (show other bugs)
Hardware: AMD64 Linux
: High normal (vote)
Assignee: Gentoo's Team for Core System packages
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-03-31 19:25 UTC by Joshua Hoblitt
Modified: 2005-08-29 17:29 UTC (History)
0 users

See Also:
Package list:
Runtime testing required: ---


Attachments
coreutils-5.2.1-fts_read-double-free.patch (coreutils-5.2.1-fts_read-double-free.patch,1.43 KB, patch)
2005-08-05 15:41 UTC, Martin Schlemmer (RETIRED)
Details | Diff
coreutils-5.2.1-fts_read-double-free.patch (coreutils-5.2.1-fts_read-double-free.patch,1.38 KB, patch)
2005-08-05 15:52 UTC, Martin Schlemmer (RETIRED)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joshua Hoblitt 2005-03-31 19:25:20 UTC
mkdir foo
cd foo
chmod 600 .*
chmod: fts_read failed: Permission denied
*** glibc detected *** double free or corruption (!prev): 0x000000000050b340 ***Aborted

chmoding '.' to 600 is certainly a Bad Thing{TM} but that's a pretty awful failure mode...



Reproducible: Always
Steps to Reproduce:
1.
2.
3.




Portage 2.0.51.19 (default-linux/amd64/2005.0, gcc-3.4.3,
glibc-2.3.4.20041102-r1, 2.6.7-gentoo-r6 x86_64)
=================================================================
System uname: 2.6.7-gentoo-r6 x86_64 AMD Athlon(tm) 64 Processor 3200+
Gentoo Base System version 1.4.16
Python:              dev-lang/python-2.2.3-r5,dev-lang/python-2.3.4-r1 [2.3.4
(#1, Feb 12 2005, 12:15:38)]
distcc 2.18.3 x86_64-pc-linux-gnu (protocols 1 and 2) (default port 3632) [disabled]
dev-lang/python:     2.2.3-r5, 2.3.4-r1
sys-devel/autoconf:  2.59-r6, 2.13
sys-devel/automake:  1.5, 1.7.9-r1, 1.6.3, 1.8.5-r3, 1.4_p6, 1.9.4
sys-devel/binutils:  2.15.92.0.2-r1
sys-devel/libtool:   1.5.10-r4
virtual/os-headers:  2.6.8.1-r4
ACCEPT_KEYWORDS="amd64"
AUTOCLEAN="yes"
CFLAGS="-march=x86-64 -O2 -pipe"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc /usr/kde/2/share/config /usr/kde/3.1/share/config
/usr/kde/3.2/share/config /usr/kde/3.3/env /usr/kde/3.3/share/config
/usr/kde/3.3/shutdown /usr/kde/3/share/config /usr/lib/X11/xkb
/usr/lib/mozilla/defaults/pref /usr/share/config
/usr/share/texmf/dvipdfm/config/ /usr/share/texmf/dvips/config/
/usr/share/texmf/tex/generic/config/ /usr/share/texmf/tex/platex/config/
/usr/share/texmf/xdvi/ /var/qmail/control"
CONFIG_PROTECT_MASK="/etc/gconf /etc/init.d /etc/terminfo /etc/env.d"
CXXFLAGS="-march=x86-64 -O2 -pipe"
DISTDIR="/usr/portage/distfiles"
FEATURES="autoaddcvs autoconfig distlocks sandbox"
GENTOO_MIRRORS="http://gentoo.mirrors.pair.com/ ftp://gentoo.mirrors.pair.com/
ftp://ibiblio.org/pub/Linux/distributions/gentoo/"
MAKEOPTS="-j2"
PKGDIR="/usr/portage/packages"
PORTAGE_TMPDIR="/var/tmp"
PORTDIR="/usr/portage"
SYNC="rsync://rsync.namerica.gentoo.org/gentoo-portage"
USE="amd64 X acpi alsa arts bash-completion berkdb bitmap-fonts cdr crypt cups
curl dvd dvdr esd fam flac font-server fortran gdbm gif gnome gnome2 gpm
gstreamer gtk gtk2 imap imlib ipv6 jp2 jpeg ldap libwww lzw lzw-tiff mikmod
motif mozilla mp3 mysql ncurses nls nptl oggvorbis opengl oss pam pdflib perl
pic png python readline sdl slang ssl tcpd tetex tiff truetype truetype-fonts
type1-fonts usb userlocales xinerama xml xml2 xmms xpm xrandr xv zlib"
Unset:  ASFLAGS, CBUILD, CTARGET, LANG, LC_ALL, LDFLAGS, PORTDIR_OVERLAY
Comment 1 SpanKY gentoo-dev 2005-04-01 16:50:34 UTC
which version of coreutils ?  5.2.1-r5 works for me ...

root@vapier 0 ~ # mkdir foo
root@vapier 0 ~ # cd foo
root@vapier 0 foo # chmod 600 .*
root@vapier 0 foo # ls -al
total 8
drw-------   2 root root 4096 Apr  1 19:50 .
drw-------  67 root root 4096 Apr  1 19:50 ..
Comment 2 Joshua Hoblitt 2005-04-02 13:50:03 UTC
I was on 5.2.1-r4 (I thought I had reported that in the orginal bug).  I just upgraded to 5.2.1-r5 and I still get:

chmod: fts_read failed: Permission denied
*** glibc detected *** double free or corruption (!prev): 0x000000000050a340 ***Aborted

Are you on amd64 too?
Comment 3 SpanKY gentoo-dev 2005-04-03 09:53:40 UTC
yes :/

and i'm using same CFLAGS, but glibc-2.3.5.2005xxxx ...
Comment 4 Joshua Hoblitt 2005-05-21 12:47:59 UTC
Well, glibc > 2.3.4.2005* is masked on amd64.  What should we do with this bug?
Comment 5 Danny van Dyk (RETIRED) gentoo-dev 2005-06-21 12:59:16 UTC
Works for me in a stable chroot with hese packages:

coreutils-5.2.1-r4
glibc-2.3.4.20041102

nemo / # mkdir foo
nemo / # cd foo
nemo foo # chmod 600 .*
nemo foo # MALLOC_CHECK_=2 chmod 600 .*
nemo foo # ls -al .
total 8
drw-------   2 root root 4096 Jun 21 13:17 .
drw-------  19 root root 4096 Jun 21 13:17 ..
Comment 6 Matt Galloway 2005-08-01 15:13:26 UTC
I also get the same problem with "glibc detected" error message. I'll take a
look at some code tomorrow to try and track it down. I'm using the following
versions:

coreutils-5.2.1-r6
glibc-2.3.5-r1
Comment 7 Martin Schlemmer (RETIRED) gentoo-dev 2005-08-05 15:26:50 UTC
Bug seems to be actually valid:

-----
GNU gdb 6.3
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-pc-linux-gnu"...Using host libthread_db
library "/lib/libthread_db.so.1".

(gdb) r 0600 .*
Starting program: /usr/bin/chmod 0600 .*
/usr/bin/chmod: fts_read failed: Permission denied
*** glibc detected *** /usr/bin/chmod: double free or corruption (!prev):
0x000000000050b2e0 ***
======= Backtrace: =========
/lib/libc.so.6[0x3000d6c893]
/lib/libc.so.6(__libc_free+0x6c)[0x3000d6d39c]
/usr/bin/chmod(fts_close+0x26)[0x402326]
/usr/bin/chmod[0x401a1f]
/lib/libc.so.6(__libc_start_main+0xf6)[0x3000d1cdf6]
/usr/bin/chmod[0x4014e9]
======= Memory map: ========
00400000-00409000 r-xp 00000000 fe:04 9093600                            /bin/chmod
00509000-0050a000 rw-p 00009000 fe:04 9093600                            /bin/chmod
0050a000-0052b000 rw-p 0050a000 00:00 0                                  [heap]
3000000000-300001a000 r-xp 00000000 fe:04 16340933                      
/lib64/ld-2.3.90.so
300011a000-300011b000 r--p 0001a000 fe:04 16340933                      
/lib64/ld-2.3.90.so
300011b000-300011d000 rw-p 0001b000 fe:04 16340933                      
/lib64/ld-2.3.90.so
3000d00000-3000e26000 r-xp 00000000 fe:04 16340934                      
/lib64/libc-2.3.90.so
3000e26000-3000f25000 ---p 00126000 fe:04 16340934                      
/lib64/libc-2.3.90.so
3000f25000-3000f28000 r--p 00125000 fe:04 16340934                      
/lib64/libc-2.3.90.so
3000f28000-3000f2c000 rw-p 00128000 fe:04 16340934                      
/lib64/libc-2.3.90.so
3000f2c000-3000f30000 rw-p 3000f2c000 00:00 0
3004700000-300470d000 r-xp 00000000 fe:04 5341549                       
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.0.1/libgcc_s.so.1
300470d000-300480c000 ---p 0000d000 fe:04 5341549                       
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.0.1/libgcc_s.so.1
300480c000-300480d000 rw-p 0000c000 fe:04 5341549                       
/usr/lib64/gcc/x86_64-pc-linux-gnu/4.0.1/libgcc_s.so.1
2aaaaaac7000-2aaaaaac9000 rw-p 2aaaaaac7000 00:00 0
2aaaaab00000-2aaaaab21000 rw-p 2aaaaab00000 00:00 0
2aaaaab21000-2aaaaac00000 ---p 2aaaaab21000 00:00 0
7fffffb72000-7fffffb87000 rw-p 7fffffb72000 00:00 0                      [stack]
ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0                  [vdso]

Program received signal SIGABRT, Aborted.
0x0000003000d30c3a in raise () from /lib/libc.so.6
(gdb) bt
#0  0x0000003000d30c3a in raise () from /lib/libc.so.6
#1  0x0000003000d31fa0 in abort () from /lib/libc.so.6
#2  0x0000003000d673bf in __fsetlocking () from /lib/libc.so.6
#3  0x0000003000d6c893 in malloc_usable_size () from /lib/libc.so.6
#4  0x0000003000d6d39c in free () from /lib/libc.so.6
#5  0x0000000000402326 in fts_close (sp=0x50a030) at fts.c:446
#6  0x0000000000401a1f in main (argc=5284000, argv=0x50a0a0) at chmod.c:257
(gdb) 
-----

Which is this bit in lib/fts.c:
-----
        /*
         * This still works if we haven't read anything -- the dummy structure
         * points to the root list, so we step through to the end of the root
         * list which has a valid parent pointer.
         */
        if (sp->fts_cur) {
                for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
                        freep = p;
                        p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
                        free(freep);                         <--- *** HERE ***
                }
                free(p);
        }
-----

The bit in src/chmod.c looks like:
-----
static int
process_files (char **files, int bit_flags, const struct mode_change *changes)
{
  int fail = 0;

  FTS *fts = xfts_open (files, bit_flags, NULL);

  while (1)
    {
      FTSENT *ent;

      ent = fts_read (fts);
      if (ent == NULL)
        {
          if (errno != 0)
            {
              /* FIXME: try to give a better message  */
              error (0, errno, _("fts_read failed"));
              fail = 1;
            }
          break;
        }

      fail |= process_file (fts, ent, changes);
    }

  /* Ignore failure, since the only way it can do so is in failing to
     return to the original directory, and since we're about to exit,
     that doesn't matter.  */
  fts_close (fts);                                   <--- *** HERE ***

  return fail;
}
-----

I have checked if calling xfts_open(), then directly calling fts_close() have
this effect, but not so.  So it seems like fts_read() somehow screws up the
linked list ... 

I am still trying to figure out why this is.
Comment 8 Martin Schlemmer (RETIRED) gentoo-dev 2005-08-05 15:41:06 UTC
Created attachment 65199 [details, diff]
coreutils-5.2.1-fts_read-double-free.patch

Got it.

Code in lib/fts.c looks like this:

-----
602 next:   tmp = p;
603	    if ((p = p->fts_link) != NULL) {
604		    free(tmp);
605
606		    /*
607		     * If reached the top, return to the original directory (or

608		     * the root of the tree), and load the paths for the next
root.
609		    */
610		    if (p->fts_level == FTS_ROOTLEVEL) {
611			    if (FCHDIR(sp, sp->fts_rfd)) {
612				    SET(FTS_STOP);
613				    sp->fts_cur=p;
614				    return (NULL);
615			    }
616			    fts_load(sp, p);
617			    if (p->fts_info == FTS_D)
618				    ENTER_DIR (sp, p, "8");
619			    return (sp->fts_cur = p);
620		    }
----

Basically we free() set 'p = p->fts_link' on line 603, and then free the
old 'p' on line 604, but then if we fail to fchdir() on line 611,  we do
not update 'sp->fts_cur' ...  Thus update 'sp->fts_cur' before we return
NULL on line 614.  (bug #87490)
Comment 9 Martin Schlemmer (RETIRED) gentoo-dev 2005-08-05 15:44:54 UTC
Joshua/Matt, can you guys please test the patch in comment #8 ?
Comment 10 Martin Schlemmer (RETIRED) gentoo-dev 2005-08-05 15:52:19 UTC
Created attachment 65200 [details, diff]
coreutils-5.2.1-fts_read-double-free.patch

Bah, update the comments (remove line I added), and add spaces between the
added line's '='.
Comment 11 Joshua Hoblitt 2005-08-21 18:47:28 UTC
I applied the patch in comment #10 to sys-apps/coreutils-5.2.1-r6.

$ mkdir foo
$ cd foo
$ chmod 600 .*
chmod: fts_read failed: Permission denied

Congratulations on tracking that one down!  The error message isn't very helpful
unless your glibc dev but it's certainly better than an abort().
Comment 12 SpanKY gentoo-dev 2005-08-29 17:29:33 UTC
sent upstream and added to coreutils-5.2.1-r7