CVE-2017-5334 (published 2017-03-24T15:59Z)

Double free vulnerability in the gnutls_x509_ext_import_proxy function in GnuTLS before 3.3.26 and 3.5.x before 3.5.8 allows remote attackers to have unspecified impact via crafted policy language information in an X.509 certificate with a Proxy Certificate Information extension.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-415
cwe_name: Double Free
description: The product calls free() twice on the same memory address, potentially leading to modification of unexpected memory locations.
extended_description: When a program calls free() twice with the same argument, the program's memory management data structures become corrupted. This corruption can cause the program to crash or, in some circumstances, cause two later calls to malloc() to return the same pointer. If malloc() returns the same value twice and the program later gives the attacker control over the data that is written into this doubly-allocated memory, the program becomes vulnerable to a buffer overflow attack.
         

Fix information:
repo_url: https://gitlab.com/gnutls/gnutls
commit_details: repo_url: https://gitlab.com/gnutls/gnutls
author: Nikos Mavrogiannopoulos
author_date: 2016-12-15 15:02:18+01:00
msg: gnutls_x509_ext_import_proxy: fix issue reading the policy language

If the language was set but the policy wasn't, that could lead to
a double free, as the value returned to the user was freed.
repository: repo_url: https://gitlab.com/gnutls/gnutls
repo_name: visit repo url
description: visit repo url
repo_language: visit repo url
owner: gnutls
file_changes: filename: x509_ext.c
change_type: ModificationType.MODIFY
diff: @@ -1449,7 +1449,8 @@ int gnutls_x509_ext_import_proxy(const gnutls_datum_t * ext, int *pathlen,
 {
 	ASN1_TYPE c2 = ASN1_TYPE_EMPTY;
 	int result;
-	gnutls_datum_t value = { NULL, 0 };
+	gnutls_datum_t value1 = { NULL, 0 };
+	gnutls_datum_t value2 = { NULL, 0 };
 
 	if ((result = asn1_create_element
 	     (_gnutls_get_pkix(), "PKIX1.ProxyCertInfo",
@@ -1479,20 +1480,18 @@ int gnutls_x509_ext_import_proxy(const gnutls_datum_t * ext, int *pathlen,
 	}
 
 	result = _gnutls_x509_read_value(c2, "proxyPolicy.policyLanguage",
-					 &value);
+					 &value1);
 	if (result < 0) {
 		gnutls_assert();
 		goto cleanup;
 	}
 
 	if (policyLanguage) {
-		*policyLanguage = (char *)value.data;
-	} else {
-		gnutls_free(value.data);
-		value.data = NULL;
+		*policyLanguage = (char *)value1.data;
+		value1.data = NULL;
 	}
 
-	result = _gnutls_x509_read_value(c2, "proxyPolicy.policy", &value);
+	result = _gnutls_x509_read_value(c2, "proxyPolicy.policy", &value2);
 	if (result == GNUTLS_E_ASN1_ELEMENT_NOT_FOUND) {
 		if (policy)
 			*policy = NULL;
@@ -1503,16 +1502,17 @@ int gnutls_x509_ext_import_proxy(const gnutls_datum_t * ext, int *pathlen,
 		goto cleanup;
 	} else {
 		if (policy) {
-			*policy = (char *)value.data;
-			value.data = NULL;
+			*policy = (char *)value2.data;
+			value2.data = NULL;
 		}
 		if (sizeof_policy)
-			*sizeof_policy = value.size;
+			*sizeof_policy = value2.size;
 	}
 
 	result = 0;
  cleanup:
-	gnutls_free(value.data);
+	gnutls_free(value1.data);
+	gnutls_free(value2.data);
 	asn1_delete_structure(&c2);
 
 	return result;

programming_language: C