irtimmer/tpm2-pk11

Memory corruption when listing certs via p11tool

Opened this issue · 2 comments

This is possibly related to issue #61.

In trying to figure out the root cause of that issue, I found that there's memory corruption occurring even when nothing crashes outright.

animus@Fenrir ~/Development/tpm2-pk11 $ p11tool --list-certs "pkcs11:model=TPM2;manufacturer=NTC;serial=123456789;token="
No matching objects found

But with Valgrind...

animus@Fenrir ~/Development/tpm2-pk11 $ valgrind p11tool --list-certs "pkcs11:model=TPM2;manufacturer=NTC;serial=123456789;token="
==25792== Memcheck, a memory error detector
==25792== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==25792== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==25792== Command: p11tool --list-certs pkcs11:model=TPM2;manufacturer=NTC;serial=123456789;token=
==25792== 
==25792== Invalid write of size 8
==25792==    at 0x4E8A320: _gnutls_buffer_init (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA3561: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792==  Address 0x7511820 is 0 bytes after a block of size 32 alloc'd
==25792==    at 0x4C2AEAF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==25792==    by 0x4EA32A1: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792== 
==25792== Invalid write of size 8
==25792==    at 0x4E8A327: _gnutls_buffer_init (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA3561: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792==  Address 0x7511828 is 8 bytes after a block of size 32 alloc'd
==25792==    at 0x4C2AEAF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==25792==    by 0x4EA32A1: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792== 
==25792== Invalid write of size 8
==25792==    at 0x4E8A32F: _gnutls_buffer_init (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA3561: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792==  Address 0x7511830 is 16 bytes after a block of size 32 alloc'd
==25792==    at 0x4C2AEAF: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==25792==    by 0x4EA32A1: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792== 
==25792== Invalid write of size 8
==25792==    at 0x4E8A337: _gnutls_buffer_init (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA3561: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)
==25792==  Address 0x7511838 is 24 bytes after a block of size 32 in arena "client"
==25792== 

valgrind: m_mallocfree.c:307 (get_bszB_as_is): Assertion 'bszB_lo == bszB_hi' failed.
valgrind: Heap block lo/hi size mismatch: lo = 96, hi = 0.
This is probably caused by your program erroneously writing past the
end of a heap block and corrupting heap metadata.  If you fix any
invalid writes reported by Memcheck, this assertion failure will
probably go away.  Please try that before reporting this as a bug.


host stacktrace:
==25792==    at 0x5804435A: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x58044474: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x58044602: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x580532E0: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x5803D03A: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x5803B723: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x5803FE14: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x5803A9FB: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x58015424: ??? (in /usr/lib64/valgrind/memcheck-amd64-linux)
==25792==    by 0x1002F66D23: ???
==25792==    by 0x1002BB1F2F: ???
==25792==    by 0x1C0F: ???
==25792==    by 0x100200835F: ???
==25792==    by 0x1002BB1F17: ???
==25792==    by 0x1002BB1F2F: ???
==25792==    by 0xDEC8: ???
==25792==    by 0x600: ???
==25792==    by 0x1004968E4F: ???

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 25792)
==25792==    at 0x4E8A405: gnutls_buffer_append_data (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA35A2: find_objs_cb (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA45CC: _pkcs11_traverse_tokens (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x4EA4E1D: gnutls_pkcs11_obj_list_import_url4 (in /usr/lib64/libgnutls.so.30.14.10)
==25792==    by 0x1145A0: pkcs11_list (in /usr/bin/p11tool)
==25792==    by 0x1138AB: main (in /usr/bin/p11tool)

I removed the PKCS#11 module file for tpm2-pk11 and re-ran it, and no error occurred. I figure there's some memory corruption occurring while handling this, and in some situations it can lead to crashes.

It seems to be a bug related to p11tool or libgnutls.so.

Code of gnutls_pkcs11_obj_list_import_url4() is maintained by Nikos Mavrogiannopoulos on gitlab:
https://gitlab.com/gnutls/gnutls/blob/master/lib/pkcs11.c

It only ever happens when running this specific command and when using this specific module. When I went into the code and commented out the call that adds the objects into the object list, this corruption went away (it also went away when only one of the two objects was added).

I'm not opposed to the idea of it being a bug in gnutls, but given that it's happening during a callback after retrieving objects from tpm2-pk11, I think it's possible it's returning malformed objects and causing the failure.