memory leak from within libp11-kit-1 (maybe a module not getting properly unloaded?)

Daniel Kahn Gillmor dkg at fifthhorseman.net
Mon Feb 18 13:05:40 PST 2013


On Mon 2013-02-18 14:17:25 -0500, Stef Walter wrote:

> You can use the P11_KIT_DEBUG=all environment variable to get debug
> output and see more details about what's going on.

> If there's not
> enough detail, could you add a debug statement near the dlclose() and
> see if it's getting called?



sure, here's the patch i applied, and here's the output:

0 dkg at alice:~/src/p11-kit/test$ cat ../p11-kit-0.15.2/debian/patches/add-debug-output.diff 
--- a/p11-kit/modules.c	2013-02-12 10:02:28.000000000 -0500
+++ b/p11-kit/modules.c	2013-02-18 14:52:55.409530338 -0500
@@ -189,8 +189,10 @@
 	/* Module must have no outstanding references */
 	assert (mod->ref_count == 0);
 
-	if (mod->dl_module)
+	if (mod->dl_module) {
+          printf("XXXX closing XXXX\n");
 		p11_module_close (mod->dl_module);
+        }
 
 	p11_mutex_uninit (&mod->initialize_mutex);
 	p11_dict_free (mod->config);
0 dkg at alice:~/src/p11-kit/test$ P11_KIT_DEBUG=all ./p11kittest
(p11-kit:5357) p11_library_init_impl: initializing library
(p11-kit:5357) p11_kit_initialize_registered: in
(p11-kit:5357) _p11_conf_parse_file: reading config file: /etc/pkcs11/pkcs11.conf
(p11-kit:5357) read_config_file: config file does not exist
(p11-kit:5357) _p11_conf_parse_file: reading config file: /home/dkg/.pkcs11/pkcs11.conf
(p11-kit:5357) read_config_file: config file does not exist
(p11-kit:5357) load_configs_from_directory: loading module configs in: /home/dkg/.pkcs11/modules
(p11-kit:5357) load_configs_from_directory: module configs do not exist
(p11-kit:5357) load_configs_from_directory: loading module configs in: /etc/pkcs11/modules
(p11-kit:5357) _p11_conf_parse_file: reading config file: /etc/pkcs11/modules/gnome-keyring.module
(p11-kit:5357) _p11_conf_parse_file: config value: module: gnome-keyring-pkcs11.so
(p11-kit:5357) _p11_conf_parse_file: config value: x-trust-store: pkcs11:library-manufacturer=GNOME%20Keyring;serial=1:XDG:DEFAULT
(p11-kit:5357) _p11_conf_parse_file: config value: x-trust-lookup: pkcs11:library-manufacturer=GNOME%20Keyring
(p11-kit:5357) load_configs_from_directory: loading module configs in: /usr/share/p11-kit/modules
(p11-kit:5357) _p11_conf_parse_file: reading config file: /usr/share/p11-kit/modules/p11-kit-trust.module
(p11-kit:5357) _p11_conf_parse_file: config value: module: p11-kit-trust.so
(p11-kit:5357) _p11_conf_parse_file: config value: trust-policy: 1
(p11-kit:5357) _p11_conf_parse_file: config value: x-trust-lookup: pkcs11:library-description=PKCS%2311%20Kit%20Trust%20Module
(p11-kit:5357) expand_module_path: module path is relative, loading from: /usr/lib/x86_64-linux-gnu/pkcs11
(p11-kit:5357) p11_library_init_impl: initializing library
(p11-kit:5357) dlopen_and_get_function_list: opened module: /usr/lib/x86_64-linux-gnu/pkcs11/p11-kit-trust.so
(p11-kit:5357) expand_module_path: module path is relative, loading from: /usr/lib/x86_64-linux-gnu/pkcs11
(p11-kit:5357) dlopen_and_get_function_list: opened module: /usr/lib/x86_64-linux-gnu/pkcs11/gnome-keyring-pkcs11.so
(p11-kit:5357) initialize_module_unlocked_reentrant: C_Initialize: calling
(p11-kit:5357) sys_C_Initialize: in
(p11-kit:5357) sys_C_Initialize: out: 0x0
(p11-kit:5357) initialize_module_unlocked_reentrant: C_Initialize: result: 0
(p11-kit:5357) initialize_module_unlocked_reentrant: C_Initialize: calling
(p11-kit:5357) initialize_module_unlocked_reentrant: C_Initialize: result: 0
(p11-kit:5357) p11_kit_initialize_registered: out: 0
(p11-kit:5357) p11_kit_finalize_registered: in
(p11-kit:5357) _p11_kit_finalize_registered_unlocked_reentrant: finalizing 2 modules
(p11-kit:5357) sys_C_Finalize: in
(p11-kit:5357) sys_C_Finalize: out: 0x0
XXXX closing XXXX
(p11-kit:5357) uninit_common: uninitializing library
XXXX closing XXXX
(p11-kit:5357) p11_kit_finalize_registered: out: 0
(p11-kit:5357) uninit_common: uninitializing library
0 dkg at alice:~/src/p11-kit/test$ 

sometimes the "XXXX closing XXXX" lines are both before the
"uninit_common: uninitializing library" line, sometimes split like
above.


interestingly, i can trigger what appears to be the same leak with a
simple dlopen() test against libm (arbitrarily chosen):

dllopentest.c
-----------------------
#include <dlfcn.h>
#include <stdio.h>

int main() {
  void* x;
  int j;
  x = dlopen("/usr/lib/x86_64-linux-gnu/libm.so", RTLD_LOCAL | RTLD_NOW);
  j = dlclose(x);
  printf("result: %d\n", j);
  printf("bar: %s\n", dlerror());
  return 0;
}
-----------------------

But it only happens if i've linked the executable explicitly against libpthread:

0 dkg at alice:~/src/p11-kit/test$ rm  -f dlopentest && make dlopentest
gcc -g -Wall -Werror --pedantic --std=c99 -o dlopentest -ldl -lpthread dlopentest.c
0 dkg at alice:~/src/p11-kit/test$ valgrind --leak-check=full --show-reachable=yes ./dlopentest
==5990== Memcheck, a memory error detector
==5990== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==5990== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==5990== Command: ./dlopentest
==5990== 
result: 0
bar: (null)
==5990== 
==5990== HEAP SUMMARY:
==5990==     in use at exit: 32 bytes in 1 blocks
==5990==   total heap usage: 6 allocs, 5 frees, 1,563 bytes allocated
==5990== 
==5990== 32 bytes in 1 blocks are still reachable in loss record 1 of 1
==5990==    at 0x4C272B8: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5990==    by 0x4E3035F: _dlerror_run (dlerror.c:142)
==5990==    by 0x4E2FEE0: dlopen@@GLIBC_2.2.5 (dlopen.c:88)
==5990==    by 0x400672: main (dlopentest.c:7)
==5990== 
==5990== LEAK SUMMARY:
==5990==    definitely lost: 0 bytes in 0 blocks
==5990==    indirectly lost: 0 bytes in 0 blocks
==5990==      possibly lost: 0 bytes in 0 blocks
==5990==    still reachable: 32 bytes in 1 blocks
==5990==         suppressed: 0 bytes in 0 blocks
==5990== 
==5990== For counts of detected and suppressed errors, rerun with: -v
==5990== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 7 from 7)
0 dkg at alice:~/src/p11-kit/test$ rm  -f dlopentest && make dlopentest
gcc -g -Wall -Werror --pedantic --std=c99 -o dlopentest -ldl dlopentest.c
0 dkg at alice:~/src/p11-kit/test$ valgrind --leak-check=full --show-reachable=yes ./dlopentest
==6002== Memcheck, a memory error detector
==6002== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==6002== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==6002== Command: ./dlopentest
==6002== 
result: 0
bar: (null)
==6002== 
==6002== HEAP SUMMARY:
==6002==     in use at exit: 0 bytes in 0 blocks
==6002==   total heap usage: 5 allocs, 5 frees, 1,531 bytes allocated
==6002== 
==6002== All heap blocks were freed -- no leaks are possible
==6002== 
==6002== For counts of detected and suppressed errors, rerun with: -v
==6002== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 7 from 7)
0 dkg at alice:~/src/p11-kit/test$ 

So maybe this needs to go to the libc6 folks?  Any suggestions?

    --dkg
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 965 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/p11-glue/attachments/20130218/819ce927/attachment.pgp>


More information about the p11-glue mailing list