Core dump (corrupted double-linked list) in p11tool occurs only when no tpm2-pk11 log file specified
Opened this issue ยท 4 comments
Thanks for your work on this project ๐
Noticed a small (and strange) bug. When no log file is specified in the tpm2-pk11 config file, there is a core dump upon attempting to list the available certificates from p11tool. I have isolated the issue to the log
key within the config file being absent.
Initial config file:
# Type can be device/socket/tabrmd
type device
# Hostname to connect when using socket
hostname localhost
# Port number of TPM socket to connect to
port 2321
# Device to use as TPM
device /dev/tpmrm0
# Sign using encrypt in case TPM doesn't support hash format
# For example SSH use SHA512 which isn't supported by all TPM's
# Enabling this option requires key's to be encryption keys instead of signing only keys
sign-using-encrypt false
certificates ~/.tpm2/certs
Attempting to list certificates (one is created, present, and working in Firefox per wiki instructions) results in:
p11tool --list-certs pkcs11:model=TPM2
Object 0:
URL: pkcs11:model=TPM2;manufacturer=NTC;serial=123456789;token=;id=%0[....];object=000B[....];type=cert
Type: X.509 Certificate
Label: [....]
Flags: CKA_WRAP/UNWRAP; CKA_PRIVATE; CKA_ALWAYS_AUTH; CKA_TRUSTED; CKA_EXTRACTABLE; CKA_NEVER_EXTRACTABLE; CKA_SENSITIVE;
ID: 00:0b:[....]
corrupted double-linked list
[1] 4766 abort (core dumped) p11tool --list-certs pkcs11:model=TPM2
If a log file is defined (by adding the below to the config file):
log ~/.tpm2/logfile.txt
then there is no corrupted double-linked list, and no resulting core dump. I can reproduce this by removing and adding the above line from the config as required.
Additionally, in testing, I found the log
parameter requires an absolute path (i.e. cannot accept ~/.tpm2/log.txt
), otherwise no output is created.
The log file path that started with ~
, for example:
log ~/.tpm2/logfile.txt
is not yet supported.
I'm hitting this issue even with a logfile provided. For what it's worth, firefox also crashes when loading the module.
I'm having a similar issue, but I'm not sure if I'm experiencing the same bug. The output from p11tool is:
*** Error in '/usr/bin/p11tool': free(): invalid pointer: 0x76c1c884 ***
I have compiled the library with debug symbols and run it through gdb:
The crash occurs when the library tries to free the session->objects->object->userdata
list when closing a session with C_CloseSession
Breakpoint 2, object_free (list=0x76c1c894 <main_arena+256>) at /home/pi/tpm2-pk11/src/objects.c:81
81 while (list != NULL) {
(gdb) bt
#0 object_free (list=0x76c1c894 <main_arena+256>) at /home/pi/tpm2-pk11/src/objects.c:81
#1 0x7698cdc0 in session_close (session=0x8cfa8) at /home/pi/tpm2-pk11/src/sessions.c:152
#2 0x7698a97c in C_CloseSession (session_handle=577448) at /home/pi/tpm2-pk11/src/pk11.c:87
#3 0x76dbc83c in ?? () from /usr/lib/arm-linux-gnueabihf/libp11-kit.so.0
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) f 1
#1 0x7698cdc0 in session_close (session=0x8cfa8) at /home/pi/tpm2-pk11/src/sessions.c:152
152 object_free(session->objects);
(gdb) p session->objects->object->userdata
$30 = (void *) 0x76c1c884 <main_arena+240>
It seems like the session that p11tool is trying to close was created erroneously. Below is the flow of session_init for the session that is later closed.
session_init (session=0x8cfa8, config=0x769a136c <pk11_config>) at /home/pi/tpm2-pk11/src/sessions.c:40
40 session->context = NULL;
(gdb) n
42 size_t size = 0;
(gdb) n
43 TSS2_TCTI_CONTEXT *tcti_ctx = NULL;
(gdb) n
50 switch(config->type) {
(gdb) n
63 rc = Tss2_Tcti_Device_Init(NULL, &size, device_conf);
(gdb) n
64 break;
(gdb) n
76 if (rc != TSS2_RC_SUCCESS)
(gdb) print rc
$25 = 0
(gdb) n
79 tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc(1, size);
(gdb) n
80 if (tcti_ctx == NULL)
(gdb) n
90 switch(config->type) {
(gdb) n
105 TSS_COMPAT_DEVICE_CONF(device_conf, config->device != NULL ? config->device : DEFAULT_DEVICE);
(gdb) n
106 rc = Tss2_Tcti_Device_Init(tcti_ctx, &size, device_conf);
(gdb) n
107 break;
(gdb) n
120 if (rc != TSS2_RC_SUCCESS)
(gdb) n
121 goto cleanup;
(gdb) p rc
$26 = 655370
As you can see here, the session_init
function does not reach the point where session->objects
list is populated. Therefore, the value in that position of the struct is garbage after session_init
. Which means that when we try to free that session, we will crash trying to free session->objects
. I have created a pull request that zeroes the memory allocated for a session before calling session_init
(6df6fa1).
I also noticed that when we fail to initialize the session, we don't free the allocated memory, but I'm not sure if that is correct or not.
The funny thing here is that the library reports the error to the upper layer (i.e. returns CKR_GENERAL_ERROR
) but it seems like p11tool doesn't care and tells us to free the session anyway. Again, not sure if that is expected behavior or not.
Anyway, I hope this helps, and I can provide more information regarding this if needed.
EDIT: Forgot to add the last line of the long comment.
rc: 655370 == 0xA000A
TSS2_TCTI_RC_IO_ERROR 0xA000A was defined in https://github.com/tpm2-software/tpm2-tss/blob/master/include/tss2/tss2_common.h
tpm2_rc_decode 0xA000A
error layer
hex: 0xa0000
identifier: TSS2_TCTI_ERROR_LEVEL
description: Error from the TCTI
base error code
identifier: TSS2_BASE_RC_IO_ERROR
description: IO failure