Double free and free of invalid pointer on certain errors [GNUTLS-SA-2009-1] [CVE-2009-1415]

Simon Josefsson simon at josefsson.org
Thu Apr 30 12:36:31 CEST 2009


Miroslav Kratochvil reported [1] that he was able to crash libgnutls
when experimenting with (corrupt) DSA keys.  The client crashes when
verifying invalid DSA signatures provided by the remote server when
using a DSA ciphersuite.  The code that crashes is also used for
verifying DSA signatures in X.509 Certificates, and for verifying
RSA/DSA signatures in OpenPGP keys.

Only GnuTLS 2.6.x is affected.  GnuTLS 2.4.x and earlier did not
contain the buggy code.

The problem can be reproduced by:

gnutls-serv --x509dsakeyfile ssl.key --x509dsacertfile ssl.crt &
gnutls-cli localhost -p 5556

Using the files included below under [SSL.KEY] and [SSL.CRT].  The key
is a corrupt DSA key generated using GnuTLS 2.6.x, see CVE-2009-1416.

If your libgnutls has the bug, gnutls-cli will crash.  Once patched,
expected output should be:

jas at mocca:~$ gnutls-cli localhost -p 5556
Resolving 'localhost'...
Connecting to '127.0.0.1:5556'...
*** Fatal error: Public key signature verification has failed.
*** Handshake has failed
GNUTLS ERROR: Public key signature verification has failed.
jas at mocca:~$ 

See [2] for an in-depth analysis of the double-free problem.

When reading the code, Simon Josefsson also noticed that invalid input
can also cause the library to call free on an uninitialized pointer.

Both problems are fixed in an minimal way by [PATCH] below that
applies to GnuTLS 2.6.x.  The code has been re-written in a cleaner
way in the GnuTLS 2.7.x branch.

This problem can be identified with GNUTLS-SA-2009-1 and
CVE-2009-1415.

According to RedHat Security Response team: double / invalid free flaw
is mitigated on modern Linux systems via malloc checks.  Impact may
differ for other platforms / specific applications, but seems rather
unlikely to allow anything but crash.

We have developed a small tool that will test your gnutls library, see
below under [CODE].

/Simon

[1] http://thread.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3488
[2] http://permalink.gmane.org/gmane.comp.encryption.gpg.gnutls.devel/3502

[PATCH]

--- pk-libgcrypt.c-	2009-04-23 10:59:06.000000000 +0200
+++ pk-libgcrypt.c	2009-04-23 18:32:17.000000000 +0200
@@ -418,7 +418,7 @@
 		      const gnutls_datum_t * signature,
 		      const gnutls_pk_params_st * pk_params)
 {
-  gcry_sexp_t s_sig, s_hash, s_pkey;
+  gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
   int rc = -1, ret;
   bigint_t hash;
   bigint_t tmp[2] = { NULL, NULL };
@@ -511,6 +511,7 @@
   gcry_sexp_release (s_sig);
   gcry_sexp_release (s_hash);
   gcry_sexp_release (s_pkey);
+  s_hash = s_pkey = s_sig = NULL;
 
   if (rc != 0)
     {

[SSL.KEY]

-----BEGIN DSA PRIVATE KEY-----
MIIDGQIBAAKCAQEAygAmvvWeV4auzm9ZFG1+omVlyVqHelM0qqJ717DdaKoJlIiC
Agwsg7r+zpz4ekncShy0UxRm2yElW6p90Otx9QrCWTpvjP6wHiTptk/vUEDSQ6/Z
lqax7mI946XfoIxx3JCavVzBvNgUQAOai6BpjJ4a9ZVLBdP2gSldt9XJ4CTuSdos
BBjrCwTWn1oaZWFsXt6bgZdyZiZvAVizpDDkrV0RH6Fo6PqfLAn3hyoesM5SeAll
Hba6cGibyXxsuocwwjwynq3Y1W4SIZomh63OYNWBh6uY+9pYrdJsYtkQxhJwDSGg
9yhyL3agmx2OmOD8S7we6r3j8/D8XJgW6rszTwIDAQABAoIBAANXfbMBCzqPDtgT
Ck06A0znRbs1of7v3qb7NlzhUl7Hf8F5gXUZNtwco6SCMklYbKpWAtTkOVAv7zDi
B2AFoezLRCw67EEcrlTOIlOsZNzvnzFH30Vy9bsBqXZy3KbVfyvswUwxFNkHIuag
NW+3Gqfp4a/lMi8jGSiv3E4M3ZPorcW1qiv5i/UZX3wBrphD9dLKwgdTwmtyz+hp
/zFKwtThIuhb2qZKbYZzMqI6d4FhLufcvvXFrZ3LoTEdsprZ3fZI1M7IdvsGTZLn
HQ4Bws32hPNSaA7/b3yxK3wfBZRs8+92LYE3kiGojylNREsD8PXH5epas5+bS8A3
RL284AkCgYEA3a5KHeltiQKAE2nO4zFZirFmG5Oee4Z84oRWjz3NujAy7B8OaZmS
BQbXe8XdS67/bIHO+ULzStGEjQqs8xaev90rzJ/HY5q4G5SbwCo9AB+a99waDV+H
06CdcH2aWzuphx88VgkoNTTjT/rsgUUw6i9GOTd0CaM8UhirdOSRRCUCgYEA6UXj
26jtOpcysQhn5FaDxpUbjvlPHO8k6FUUXnbVCl4BKEkSW5kzeL1ezog65RUyPKdm
SXKgQcvWRXF76GRgAiqgUI1/tSYyKXTjljiyZZPjYhZB1hTcxVcZROHFvskLXmsn
UcdCdUM7POtFT/Cy3Nx1ZvyTYqwCH0Jomvx6pWM=
-----END DSA PRIVATE KEY-----

[SSL.CRT]

-----BEGIN CERTIFICATE-----
MIIFLDCCBBagAwIBAgIESexK4DALBgkqhkiG9w0BAQUwVzELMAkGA1UEBhMCQ1ox
DjAMBgNVBAoTBXByYWhhMQswCQYDVQQLEwJuZTENMAsGA1UEBxMEdm9sZTEOMAwG
A1UECBMFbmV2aW0xDDAKBgNVBAMTA2V4YTAeFw0wOTA0MjAxMDEzNTNaFw0xOTA0
MTgxMDEzNTdaMFcxCzAJBgNVBAYTAkNaMQwwCgYDVQQKEwNCbGUxDTALBgNVBAsT
BFNtcnQxDjAMBgNVBAcTBUt0ZXJhMQ4wDAYDVQQIEwVCbGlqZTELMAkGA1UEAxMC
TmUwggKlMIICGgYHKoZIzjgEATCCAg0CggEAygAmvvWeV4auzm9ZFG1+omVlyVqH
elM0qqJ717DdaKoJlIiCAgwsg7r+zpz4ekncShy0UxRm2yElW6p90Otx9QrCWTpv
jP6wHiTptk/vUEDSQ6/Zlqax7mI946XfoIxx3JCavVzBvNgUQAOai6BpjJ4a9ZVL
BdP2gSldt9XJ4CTuSdosBBjrCwTWn1oaZWFsXt6bgZdyZiZvAVizpDDkrV0RH6Fo
6PqfLAn3hyoesM5SeAllHba6cGibyXxsuocwwjwynq3Y1W4SIZomh63OYNWBh6uY
+9pYrdJsYtkQxhJwDSGg9yhyL3agmx2OmOD8S7we6r3j8/D8XJgW6rszTwIDAQAB
AoIBAANXfbMBCzqPDtgTCk06A0znRbs1of7v3qb7NlzhUl7Hf8F5gXUZNtwco6SC
MklYbKpWAtTkOVAv7zDiB2AFoezLRCw67EEcrlTOIlOsZNzvnzFH30Vy9bsBqXZy
3KbVfyvswUwxFNkHIuagNW+3Gqfp4a/lMi8jGSiv3E4M3ZPorcW1qiv5i/UZX3wB
rphD9dLKwgdTwmtyz+hp/zFKwtThIuhb2qZKbYZzMqI6d4FhLufcvvXFrZ3LoTEd
sprZ3fZI1M7IdvsGTZLnHQ4Bws32hPNSaA7/b3yxK3wfBZRs8+92LYE3kiGojylN
REsD8PXH5epas5+bS8A3RL284AkDgYQAAoGA3a5KHeltiQKAE2nO4zFZirFmG5Oe
e4Z84oRWjz3NujAy7B8OaZmSBQbXe8XdS67/bIHO+ULzStGEjQqs8xaev90rzJ/H
Y5q4G5SbwCo9AB+a99waDV+H06CdcH2aWzuphx88VgkoNTTjT/rsgUUw6i9GOTd0
CaM8UhirdOSRRCWjgYAwfjAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUF
BwMCBggrBgEFBQcDATAPBgNVHQ8BAf8EBQMDB4AAMB0GA1UdDgQWBBRdOw6fAlG3
powcRYMbekXDEG0QGjAfBgNVHSMEGDAWgBTZbe4eoATyPzAYVtkaOaB4Dcl57zAL
BgkqhkiG9w0BAQUDggEBAC1ErfpfBUAKsdBCDUaQmqzoiMQ5Bm6jX7vzht7HG0Bq
MA89SOrr09tTMkEIkab3LN+pCs2cSRRtHRNBk+tzn+cyq4VptFnV+EhpB32YCLro
SnfYD0eclv3yO2GnzP6tADDuHWyOq0bSYOxcnUZuEe7X/rl7Zj8meiE48i9jNQYD
lX0YayTBR1eYbtNEaZASUvrFO4JkBZlTjXR/qNRjj1SidVLfAayZtct40usEH+9V
EgpmZmtIqCPsmF8f3KVEcxwz7xwAtjI820qCRzFUmgboZ65jm3IWr4CibIgjlhs7
tzclPT9WeIZdeP7QWlFmhjbiY5yFfjCiyvlf3mechow=
-----END CERTIFICATE-----

[CODE]

/*
 * Small code to reproduce the CVE-2009-1415 double-free problem.
 *
 * Build it using:
 *
 *  gcc -o cve-2009-1415 cve-2009-1415.c -lgnutls
 *
 * If your gnutls library is OK then running it will just print 'success!'.
 *
 * If your gnutls library is buggy, then running it will crash like this:
 *
 * ** glibc detected *** ./cve-2009-1415: munmap_chunk(): invalid pointer: 0xb7f80a9c ***
 * ======= Backtrace: =========
 * ...
 */

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

#include <gnutls/gnutls.h>

static char dsa_cert[] =
  "-----BEGIN CERTIFICATE-----\n"
  "MIIDbzCCAtqgAwIBAgIERiYdRTALBgkqhkiG9w0BAQUwGTEXMBUGA1UEAxMOR251\n"
  "VExTIHRlc3QgQ0EwHhcNMDcwNDE4MTMyOTQxWhcNMDgwNDE3MTMyOTQxWjA3MRsw\n"
  "GQYDVQQKExJHbnVUTFMgdGVzdCBzZXJ2ZXIxGDAWBgNVBAMTD3Rlc3QuZ251dGxz\n"
  "Lm9yZzCCAbQwggEpBgcqhkjOOAQBMIIBHAKBgLmE9VqBvhoNxYpzjwybL5u2DkvD\n"
  "dBp/ZK2d8yjFoEe8m1dW8ZfVfjcD6fJM9OOLfzCjXS+7oaI3wuo1jx+xX6aiXwHx\n"
  "IzYr5E8vLd2d1TqmOa96UXzSJY6XdM8exXtLdkOBBx8GFLhuWBLhkOI3b9Ib7GjF\n"
  "WOLmMOBqXixjeOwHAhSfVoxIZC/+jap6bZbbBF0W7wilcQKBgGIGfuRcdgi3Rhpd\n"
  "15fUKiH7HzHJ0vT6Odgn0Zv8J12nCqca/FPBL0PCN8iFfz1Mq12BMvsdXh5UERYg\n"
  "xoBa2YybQ/Dda6D0w/KKnDnSHHsP7/ook4/SoSLr3OCKi60oDs/vCYXpNr2LelDV\n"
  "e/clDWxgEcTvcJDP1hvru47GPjqXA4GEAAKBgA+Kh1fy0cLcrN9Liw+Luin34QPk\n"
  "VfqymAfW/RKxgLz1urRQ1H+gDkPnn8l4EV/l5Awsa2qkNdy9VOVgNpox0YpZbmsc\n"
  "ur0uuut8h+/ayN2h66SD5out+vqOW9c3yDI+lsI+9EPafZECD7e8+O+P90EAXpbf\n"
  "DwiW3Oqy6QaCr9Ivo4GTMIGQMAwGA1UdEwEB/wQCMAAwGgYDVR0RBBMwEYIPdGVz\n"
  "dC5nbnV0bHMub3JnMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdDwEB/wQFAwMH\n"
  "gAAwHQYDVR0OBBYEFL/su87Y6HtwVuzz0SuS1tSZClvzMB8GA1UdIwQYMBaAFOk8\n"
  "HPutkm7mBqRWLKLhwFMnyPKVMAsGCSqGSIb3DQEBBQOBgQBCsrnfD1xzh8/Eih1f\n"
  "x+M0lPoX1Re5L2ElHI6DJpHYOBPwf9glwxnet2+avzgUQDUFwUSxOhodpyeaACXD\n"
  "o0gGVpcH8sOBTQ+aTdM37hGkPxoXjtIkR/LgG5nP2H2JRd5TkW8l13JdM4MJFB4W\n"
  "QcDzQ8REwidsfh9uKAluk1c/KQ==\n"
  "-----END CERTIFICATE-----\n";

const gnutls_datum_t dsa_cert_dat = {
  dsa_cert, sizeof (dsa_cert)
};

int
main (void)
{
  gnutls_x509_crt_t crt;
  gnutls_datum_t data = { "foo", 3 };
  gnutls_datum_t sig = { "bar", 3 };
  int ret;

  gnutls_global_init ();

  ret = gnutls_x509_crt_init (&crt);
  if (ret < 0)
    return 1;

  ret = gnutls_x509_crt_import (crt, &dsa_cert_dat, GNUTLS_X509_FMT_PEM);
  if (ret < 0)
    return 1;

  ret = gnutls_x509_crt_verify_data (crt, 0, &data, &sig);
  if (ret < 0)
    return 1;

  printf ("success!\n");

  gnutls_x509_crt_deinit (crt);
  gnutls_global_deinit ();

  return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 419 bytes
Desc: not available
URL: </pipermail/attachments/20090430/e5e3be52/attachment.pgp>


More information about the Gnutls-devel mailing list