Red Hat Bugzilla – Bug 499305
Memory leak in libc when nsswitch.conf is in compat mode
Last modified: 2016-11-24 07:20:55 EST
This bug has been reproduced on RHEL4, RHEL5 and F10.
Steps to reproduce this issue:
Add a an entry begining with the "+" sympbol in /etc/passwd:
# grep ^+ /etc/passwd
Change nsswitch to use compat for passwd:
# grep compat /etc/nsswitch.conf
# compat Use NIS on compat mode
Compile this test:
# cat memleak_repro.c
uid_t myid = 800120545;
getpwuid( myid );
# gcc -g -o memleak_repro memleak_repro.c
Run it under Valgrind:
# /local/opt/twwgs/valgrind323/bin/valgrind --leak-check=full ./memleak_repro
==18634== Memcheck, a memory error detector.
==18634== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==18634== Using LibVEX rev 1732, a library for dynamic binary translation.
==18634== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==18634== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==18634== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==18634== For more details, rerun with: -v
==18634== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 9 from 4)
==18634== malloc/free: in use at exit: 292 bytes in 11 blocks.
==18634== malloc/free: 84 allocs, 73 frees, 27,827 bytes allocated.
==18634== For counts of detected errors, rerun with: -v
==18634== searching for pointers to 11 not-freed blocks.
==18634== checked 62,848 bytes.
==18634== 292 (52 direct, 240 indirect) bytes in 1 blocks are definitely lost in loss record 1 of 3
==18634== at 0x4904D9E: malloc (vg_replace_malloc.c:149)
==18634== by 0x33AF1D65BE: nss_parse_service_list (in /lib64/tls/libc-2.3.4.so)
==18634== by 0x33AF1D6C8C: __nss_database_lookup (in /lib64/tls/libc-2.3.4.so)
==18634== by 0x4B1853A: ???
==18634== by 0x33AF18EE9D: getpwuid_r@@GLIBC_2.2.5 (in /lib64/tls/libc-2.3.4.so)
==18634== by 0x33AF18E7FC: getpwuid (in /lib64/tls/libc-2.3.4.so)
==18634== by 0x4004BE: main (memleak_repro.c:6)
==18634== LEAK SUMMARY:
==18634== definitely lost: 52 bytes in 1 blocks.
==18634== indirectly lost: 240 bytes in 10 blocks.
==18634== possibly lost: 0 bytes in 0 blocks.
==18634== still reachable: 0 bytes in 0 blocks.
==18634== suppressed: 0 bytes in 0 blocks.
That doesn't seem to be a real leak.
Normally libnss_* modules are dlopened the first time they are needed and afterwards kept around until exit time, and libnss_compat.so.2 allocates some memory and references it from its global variables.
When valgrind/mtrace or some other allocation checker reaches program exit, it
runs __libc_freeres to free some memory still referenced at exit time (normally that isn't needed, as exit terminates the process and so there is no point to free anything), and among other things this attempts to dlclose libnss* modules that aren't normally ever dlclosed. As libnss_compat.so.2 doesn't contain a destructor that would free the memory at its dlclose time, valgrind/mtrace report this as memory leak, but that is something that will never actually happen when not under valgrind/mtrace.
Thanks for the explanation Jakub
This event sent from IssueTracker by jleddy