Re: getgrouplist segfault?



Hello,

On Wed, 6 Jul 2005, Anton Monroe wrote:

> Pavel Tsekov told me how to do a backtrace.  Using cvs HEAD as of July 5,
> I did
> (as a normal user)
>     ./autogen.sh CFLAGS="-g -O0" --prefix=/mc
>     make
> (as root)
>     make install
>     gdb /test/bin/mc | tee gdb.root.out
>
> which produced this:
>
> =================================================================
> GNU gdb 20010316
> Copyright 2001 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 "i386-suse-linux"...
> (gdb) r
> Starting program: /mc/bin/mc
>
> Program received signal SIGSEGV, Segmentation fault.
> 0x4013bb29 in chunk_free () from /lib/libc.so.6
> (gdb) bt full
> #0  0x4013bb29 in chunk_free () from /lib/libc.so.6
> No symbol table info available.
> #1  0x4013b9a3 in free () from /lib/libc.so.6
> No symbol table info available.
> #2  0x4002efa3 in g_free () from /usr/lib/libglib-1.2.so.0
> No symbol table info available.
> #3  0x080906a7 in init_groups () at utilunix.c:107
> 	groups = (gid_t *) 0x8104f98
> 	ng = 7
> 	newgroups = (gid_t *) 0x8105020
> 	i = 135277456
> 	pwd = (struct passwd *) 0x401e9bd0
> 	grp = (struct group *) 0x401e9a88
> #4  0x08076ff9 in main (argc=1, argv=0xbffff824) at main.c:2143
> 	show_change_notice = 0
> #5  0x400e47ee in __libc_start_main () from /lib/libc.so.6

The backtrace indicates heap corruption. I've looked at the init_groups()
and it seems ok AFAICT. The crash happens in the following block of code
inside init_groups():

        if (getgrouplist (pwd->pw_name, pwd->pw_gid, groups, &ng) == -1) {
            newgroups = g_new (gid_t, ng);
            if (newgroups != NULL) {
                g_free (groups); <--- Crashes in this calls
                groups = newgroups;
                getgrouplist (pwd->pw_name, pwd->pw_gid, groups, &ng);
            } else
                ng = 1;
        }

It doesn't go further (the for loop or beyond) since the value of `i' is
still uninitialized as it can be seen from the backtrace.

Now looking at the manpage of `getgrouplist' I noticed this:

[...]
BUGS
       The glibc 2.3.2 implementation of this function is broken: it
       overwrites memory when the actual number of groups  is  larger
       than *ngroups.
[...]

So the next question to ask is - what version of glibc are you using ?



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]