Package: libc6
Version: 2.7-18

I have found that getservbyname() can corrupt the caller's stack when looking
up information in NIS.

Given the following simple program:

#include <stdio.h>
#include <netdb.h>

int main(void) {
    char **a;
    struct servent *entry = getservbyname("afsprot", NULL);
    if (entry == NULL) {
        printf("No entry found for afsprot\n");
        return 1;
    }
    printf("Service: %s\n\tPort: %d/%s\n", entry->s_name, ntohs(entry->s_port), 
entry->s_proto);
    if (entry->s_aliases && *(entry->s_aliases)) {
        printf("\tAliases:");
        for (a=entry->s_aliases; *a; a++) {
            printf(" %s", *a);
        }
    }
    return 0;
}

and a line
        service: db files nis
in /etc/nsswitch.conf,

I get the valgrind errors in the first attachment (valgrind.out).

An affected application is aklog (from the openafs-krb5 package; I'm building
an OpenAFS 1.4.8 version of that package). In this case, the program segfaults
with a very similar valgrind trace (aklog.out). It terminates successfully
if I invoke aklog with the -noprdb option, which bypasses the getservbyname()
call.

That the stack is smashed can also be verified in gdb. This kept me from
getting a backtrace from gdb. An strace, however, confirms that the crash
occurs in getservbyname() code.
==32343== Memcheck, a memory error detector.
==32343== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==32343== Using LibVEX rev 1854, a library for dynamic binary translation.
==32343== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==32343== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation 
framework.
==32343== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==32343== For more details, rerun with: -v
==32343== 
==32343== Invalid read of size 4
==32343==    at 0x4015847: (within /lib/ld-2.7.so)
==32343==    by 0x4153131: (within /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x400DA15: (within /lib/ld-2.7.so)
==32343==    by 0x41532F4: __libc_dlopen_mode (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x412B6DF: __nss_lookup_function (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x412B7CF: (within /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x412D565: __nss_services_lookup (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x4133D98: getservbyname_r (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x4133AFD: getservbyname (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x8048429: main (in /home/gelato/src/experiments/AFS/a.out)
==32343==  Address 0x419532c is 44 bytes inside a block of size 46 alloc'd
==32343==    at 0x4022D6E: malloc (vg_replace_malloc.c:207)
==32343==    by 0x400DB23: (within /lib/ld-2.7.so)
==32343==    by 0x4008555: (within /lib/ld-2.7.so)
==32343==    by 0x4011B46: (within /lib/ld-2.7.so)
==32343==    by 0x400DA15: (within /lib/ld-2.7.so)
==32343==    by 0x401154D: (within /lib/ld-2.7.so)
==32343==    by 0x4153131: (within /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x400DA15: (within /lib/ld-2.7.so)
==32343==    by 0x41532F4: __libc_dlopen_mode (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x412B6DF: __nss_lookup_function (in /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x412B7CF: (within /lib/i686/cmov/libc-2.7.so)
==32343==    by 0x412D565: __nss_services_lookup (in /lib/i686/cmov/libc-2.7.so)
Service: afsprot
        Port: 7002/udp
==32343== 
==32343== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 34 from 3)
==32343== malloc/free: in use at exit: 0 bytes in 0 blocks.
==32343== malloc/free: 74 allocs, 74 frees, 24,186 bytes allocated.
==32343== For counts of detected errors, rerun with: -v
==32343== All heap blocks were freed -- no leaks are possible.
==32333== Memcheck, a memory error detector.
==32333== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==32333== Using LibVEX rev 1854, a library for dynamic binary translation.
==32333== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==32333== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation 
framework.
==32333== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==32333== For more details, rerun with: -v
==32333== 
==32333== Invalid read of size 4
==32333==    at 0x4015847: (within /lib/ld-2.7.so)
==32333==    by 0x422A131: (within /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x400DA15: (within /lib/ld-2.7.so)
==32333==    by 0x422A2F4: __libc_dlopen_mode (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x42026DF: __nss_lookup_function (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x42027CF: (within /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x4204565: __nss_services_lookup (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x420AD98: getservbyname_r (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x420AAFD: getservbyname (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x80590FB: (within /usr/bin/aklog)
==32333==    by 0x8059721: (within /usr/bin/aklog)
==32333==    by 0x804DCD5: (within /usr/bin/aklog)
==32333==  Address 0x42d775c is 44 bytes inside a block of size 46 alloc'd
==32333==    at 0x4022D6E: malloc (vg_replace_malloc.c:207)
==32333==    by 0x400DB23: (within /lib/ld-2.7.so)
==32333==    by 0x4008555: (within /lib/ld-2.7.so)
==32333==    by 0x4011B46: (within /lib/ld-2.7.so)
==32333==    by 0x400DA15: (within /lib/ld-2.7.so)
==32333==    by 0x401154D: (within /lib/ld-2.7.so)
==32333==    by 0x422A131: (within /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x400DA15: (within /lib/ld-2.7.so)
==32333==    by 0x422A2F4: __libc_dlopen_mode (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x42026DF: __nss_lookup_function (in /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x42027CF: (within /lib/i686/cmov/libc-2.7.so)
==32333==    by 0x4204565: __nss_services_lookup (in /lib/i686/cmov/libc-2.7.so)
==32333== Warning: client switching stacks?  SP change: 0xBEABFB4C --> 
0x4D08186C
==32333==          to suppress, use: --max-stackframe=1906565856 or greater
==32333== 
==32333== Process terminating with default action of signal 11 (SIGSEGV)
==32333==  Access not within mapped region at address 0x4D081868
==32333==    at 0x8075C6B: (within /usr/bin/aklog)
==32333== 
==32333== Process terminating with default action of signal 11 (SIGSEGV)
==32333==  Access not within mapped region at address 0x4D081864
==32333==    at 0x401D200: _vgnU_freeres (vg_preloaded.c:56)
==32333== 
==32333== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 50 from 3)
==32333== malloc/free: in use at exit: 336,444 bytes in 579 blocks.
==32333== malloc/free: 817 allocs, 238 frees, 486,062 bytes allocated.
==32333== For counts of detected errors, rerun with: -v
==32333== searching for pointers to 579 not-freed blocks.
==32333== checked 626,900 bytes.
==32333== 
==32333== LEAK SUMMARY:
==32333==    definitely lost: 79 bytes in 5 blocks.
==32333==      possibly lost: 0 bytes in 0 blocks.
==32333==    still reachable: 336,365 bytes in 574 blocks.
==32333==         suppressed: 0 bytes in 0 blocks.
==32333== Rerun with --leak-check=full to see details of leaked memory.

Reply via email to