From b2477c9d1d2b550abade87651382880d370d2803 Mon Sep 17 00:00:00 2001 From: mancha Date: Mon, 2 Jun 2014 Subject: CVE-2014-3469 This is a backport adaptation for use with GnuTLS 2.8.6. Relevant upstream commit(s): ------------------------- http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=a8b3e14f84174e http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=3d6a02f19ff15a http://git.savannah.gnu.org/cgit/libtasn1.git/commit/?id=53958290ab731c --- lib/minitasn1/decoding.c | 11 ++++++++--- lib/minitasn1/element.c | 27 ++++++++++++++++++--------- 2 files changed, 26 insertions(+), 12 deletions(-) --- a/lib/minitasn1/decoding.c +++ b/lib/minitasn1/decoding.c @@ -215,7 +215,6 @@ asn1_get_octet_der (const unsigned char if (der_len <= 0) return ASN1_GENERIC_ERROR; - /* if(str==NULL) return ASN1_SUCCESS; */ *str_len = asn1_get_length_der (der, der_len, &len_len); if (*str_len < 0) @@ -223,7 +222,10 @@ asn1_get_octet_der (const unsigned char *ret_len = *str_len + len_len; if (str_size >= *str_len) - memcpy (str, der + len_len, *str_len); + { + if (*str_len > 0 && str != NULL) + memcpy (str, der + len_len, *str_len); + } else { return ASN1_MEM_ERROR; @@ -350,7 +352,10 @@ asn1_get_bit_der (const unsigned char *d return ASN1_DER_ERROR; if (str_size >= len_byte) - memcpy (str, der + len_len + 1, len_byte); + { + if (len_byte > 0 && str) + memcpy (str, der + len_len + 1, len_byte); + } else { return ASN1_MEM_ERROR; --- a/lib/minitasn1/element.c +++ b/lib/minitasn1/element.c @@ -113,8 +113,11 @@ _asn1_convert_integer (const unsigned ch /* VALUE_OUT is too short to contain the value conversion */ return ASN1_MEM_ERROR; - for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) - value_out[k2 - k] = val[k2]; + if (value_out != NULL) + { + for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) + value_out[k2 - k] = val[k2]; + } #if 0 printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len); @@ -623,7 +626,8 @@ asn1_write_value (asn1_node node_root, c if (ptr_size < data_size) { \ return ASN1_MEM_ERROR; \ } else { \ - memcpy( ptr, data, data_size); \ + if (ptr && data_size > 0) \ + memcpy( ptr, data, data_size); \ } #define PUT_STR_VALUE( ptr, ptr_size, data) \ @@ -632,16 +626,19 @@ asn1_write_value (asn1_node node_root, c return ASN1_MEM_ERROR; \ } else { \ /* this strcpy is checked */ \ - strcpy(ptr, data); \ + if (ptr) { \ + strcpy(ptr, data); \ + } \ } #define ADD_STR_VALUE( ptr, ptr_size, data) \ - *len = (int) strlen(data) + 1; \ - if (ptr_size < (int) strlen(ptr)+(*len)) { \ + *len += strlen(data); \ + if (ptr_size < (int) *len) { \ + (*len)++; \ return ASN1_MEM_ERROR; \ } else { \ /* this strcat is checked */ \ - strcat(ptr, data); \ + if (ptr) strcat (ptr, data); \ } /** @@ -803,7 +810,9 @@ asn1_read_value (asn1_node root, const c case TYPE_OBJECT_ID: if (node->type & CONST_ASSIGN) { - value[0] = 0; + *len = 0; + if (value) + value[0] = 0; p = node->down; while (p) { @@ -817,7 +826,7 @@ asn1_read_value (asn1_node root, const c } p = p->right; } - *len = strlen (value) + 1; + (*len)++; } else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) {