[gnutls-devel] GnuTLS | Memory leak in gnutls_pkcs11_obj_list_import_url4(GNUTLS_PKCS11_OBJ_FLAG_WITH_PRIVKEY) (#629)

Development of GNU's TLS library gnutls-devel at lists.gnutls.org
Wed Nov 28 16:56:14 CET 2018


New Issue was created.

Issue 629: https://gitlab.com/gnutls/gnutls/issues/629
Author:    Peter Wu
Assignee:  

## Description of problem:
A memory leak is reported for `gnutls_pkcs11_obj_list_import_url4` requesting certificate + private keys.

The context looks suspicious:
```c
find_privkeys(struct pkcs11_session_info *sinfo,
	      struct ck_token_info *tinfo, struct find_pkey_list_st *list)
{
// ...
	unsigned long count, current;

	current = 0;
	while (pkcs11_find_objects
	       (sinfo->module, sinfo->pks, &ctx, 1, &count) == CKR_OK
	       && count == 1) {
// ...
		_gnutls_buffer_init(&list->key_ids[current]);

		if (pkcs11_get_attribute_value
		    (sinfo->module, sinfo->pks, ctx, a, 1) == CKR_OK) {
// ...
			current++;
		}

		if (current > list->key_ids_size)
			break;
	}
// ...

        // Potential integer underflow if the above loop does not match?
        // Potentially loses track of the last element, causing a memleak?
	list->key_ids_size = current - 1;
```

## Version of gnutls used:
3.5.18-1ubuntu1

## Distributor of gnutls (e.g., Ubuntu, Fedora, RHEL)
Ubuntu 18.04

## How reproducible:

Steps to Reproduce:

 * Setup a PKCS#11 token (e.g. SoftHSM2).
 * `cc -g $(pkgconf --cflags --libs gnutls) repro.c -fsanitize=address && ./a.out`
 * Enter PIN code if requested and press Enter.

## Actual results:
No error.

## Expected results:
Memory leak report (first backtraces have been manually converted with `addr2line`):
```
==17862==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 96 byte(s) in 1 object(s) allocated from:
    #0 0x56431559d219 in malloc (/shared/a.out+0xf2219)
    #1 0x7f8fba224e55  ./lib/pkcs11.c:2708
    #2 0x7f8fba2260e9  ./lib/pkcs11.c:1420
    #3 0x7f8fba22691b in gnutls_pkcs11_obj_list_import_url4 ./lib/pkcs11.c:3177
    #4 0x5643155da92c in main /home/peter/work/hsm/demo/repro.c:27:13
    #5 0x7f8fb920bb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #6 0x5643154ca0bd in _start (/shared/a.out+0x1f0bd)

Indirect leak of 6144 byte(s) in 3 object(s) allocated from:
    #0 0x56431559d6c8 in realloc (/shared/a.out+0xf26c8)
    #1 0x7f8fba2088b5  (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x4c8b5)
    #2 0x7f8fba20bf77 in gnutls_buffer_append_data (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x4ff77)
    #3 0x7f8fba22512a  (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x6912a)
    #4 0x7f8fba2260e9  (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x6a0e9)
    #5 0x7f8fba22691b in gnutls_pkcs11_obj_list_import_url4 (/usr/lib/x86_64-linux-gnu/libgnutls.so.30+0x6a91b)
    #6 0x5643155da92c in main /home/peter/work/hsm/demo/repro.c:27:13
    #7 0x7f8fb920bb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #8 0x5643154ca0bd in _start (/shared/a.out+0x1f0bd)
```

repro.c
```c
/*
cc -g $(pkgconf --cflags --libs gnutls) repro.c -fsanitize=address
*/
#include <gnutls/gnutls.h>
#include <gnutls/pkcs11.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static int pin_callback(void *userdata, int attempt, const char *token_url,
                        const char *token_label, unsigned int flags, char *pin,
                        size_t pin_max) {
  const char *pass = getpass("PIN: ");
  if (!pass || !pass[0]) {
    fprintf(stderr, "PIN retrieval failed.\n");
    return -1;
  }
  strncpy(pin, pass, pin_max);
  return 0;
}

int main(int argc, char *argv[]) {
  const char *url = argc < 2 ? "pkcs11:" : argv[1];
  gnutls_pkcs11_set_pin_function(pin_callback, NULL);
  gnutls_pkcs11_obj_t *list = NULL;
  unsigned int nlist = 0;
  int ret = gnutls_pkcs11_obj_list_import_url4(
      &list, &nlist, url,
      GNUTLS_PKCS11_OBJ_FLAG_CRT | GNUTLS_PKCS11_OBJ_FLAG_WITH_PRIVKEY |
          GNUTLS_PKCS11_OBJ_FLAG_LOGIN);
  if (ret < 0) {
    fprintf(stderr, "import_url failed: %d (%s)\n", ret, gnutls_strerror(ret));
  } else {
    for (unsigned j = 0; j < nlist; j++) {
      gnutls_pkcs11_obj_deinit(list[j]);
    }
    gnutls_free(list);
  }
}
```

-- 
Reply to this email directly or view it on GitLab: https://gitlab.com/gnutls/gnutls/issues/629
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.gnupg.org/pipermail/gnutls-devel/attachments/20181128/e101ceef/attachment.html>


More information about the Gnutls-devel mailing list