[gnutls-devel] memory leak, gnutls_pubkey_import_privkey() with PKCS 11

Jan Včelák jan.vcelak at nic.cz
Fri Dec 4 18:42:35 CET 2015


Hello everyone.

I'm working on the HSM support in Knot DNS using the PKCS #11 interface of
GnuTLS. And I believe I found a memory leak in the library:

==8406== 2,048 bytes in 1 blocks are definitely lost in loss record 16 of 21
==8406==    at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==8406==    by 0x4E98AEF: pkcs11_read_pubkey (pkcs11.c:1526)
==8406==    by 0x4E9FE83: _pkcs11_privkey_get_pubkey (pkcs11_privkey.c:1025)
==8406==    by 0x4E89D67: _gnutls_privkey_get_mpis (gnutls_privkey.c:213)
==8406==    by 0x4E89EB6: _gnutls_privkey_get_public_mpis (gnutls_privkey.c:240)
==8406==    by 0x400D36: main (main.c:37)
==8406== 
==8406== 2,048 bytes in 1 blocks are definitely lost in loss record 17 of 21
==8406==    at 0x4C28C50: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==8406==    by 0x4E98B03: pkcs11_read_pubkey (pkcs11.c:1530)
==8406==    by 0x4E9FE83: _pkcs11_privkey_get_pubkey (pkcs11_privkey.c:1025)
==8406==    by 0x4E89D67: _gnutls_privkey_get_mpis (gnutls_privkey.c:213)
==8406==    by 0x4E89EB6: _gnutls_privkey_get_public_mpis (gnutls_privkey.c:240)
==8406==    by 0x400D36: main (main.c:37)

This is the reproducer. It's just a private key import into the abstract
public key structure, and then construction of a maching public key:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include <gnutls/abstract.h>
#include <gnutls/pkcs11.h>

int main(int argc, char *argv[])
{
	if (argc != 2) {
		fprintf(stderr, "usage: %s <key-url>\n", argv[0]);
		return 1;
	}

	const char *url = argv[1];

	int r;

	r = gnutls_pkcs11_init(GNUTLS_PKCS11_FLAG_MANUAL, NULL);
	assert(r == 0);
	gnutls_global_init();

	r = gnutls_pkcs11_add_provider("libsofthsm2.so", NULL);
	assert(r == 0);

	gnutls_privkey_t key;
	r = gnutls_privkey_init(&key);
	assert(r == 0);

	gnutls_privkey_import_pkcs11_url(key, url);
	assert(r == 0);

	gnutls_pubkey_t pubkey;
	r = gnutls_pubkey_init(&pubkey);
	assert(r == 0);

	r = gnutls_pubkey_import_privkey(pubkey, key, 0, 0);  // <-- LEAK
	assert(r == 0);

	gnutls_pubkey_deinit(pubkey);
	gnutls_privkey_deinit(key);

	gnutls_pkcs11_deinit();
	gnutls_global_deinit();

	return 0;
}

I'm using SoftHSM 2 for testing. You can use to following commands to
setup the token:

% mkdir -p /tmp/softhsm
% cat > /tmp/softhsm/softhsm.conf << EOF
directories.tokendir = /tmp/softhsm
directories.backend = db
log.debug = INFO
EOF
% export SOFTHSM2_CONF=/tmp/softhsm/softhsm.conf
% softhsm2-util --init --slot 0 --label foo --pin 1234 --so-pin 123456
% p11tool --generate-rsa --label bar --login "pkcs11:token=foo;pin-value=1234"

Then just run the reproducer:

% gcc -std=gnu99 -Wall -g $(pkg-config --cflags --libs gnutls) ./reproducer.c
% valgrind --leak-check=full \
  ./a.out "pkcs11:token=foo;object=bar;pin-value=1234"

And some more details about my enviroment:

% rpm -q gnutls softhsm valgrind
gnutls-3.4.7-1.fc23.x86_64
softhsm-2.0.0rc1-3.fc23.x86_64
valgrind-3.11.0-1.fc23.x86_64

Please, can you take a look at it?

Thank you.

Cheers,

Jan



More information about the Gnutls-devel mailing list