| From 7f5a6256231e278aa7d00b6851c22fb457537262 Mon Sep 17 00:00:00 2001 |
| From: mancha <mancha1@zoho.com> |
| Date: Sun, 1 Jun 2014 |
| Subject: CVE-2014-3469 |
| |
| This is a backport adaptation for use with GnuTLS 2.12.23. |
| |
| 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 |
| @@ -231,7 +231,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) |
| @@ -239,7 +238,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; |
| @@ -362,7 +364,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 |
| @@ -112,8 +112,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); |
| @@ -611,7 +614,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) \ |
| @@ -620,16 +624,19 @@ asn1_write_value (asn1_node node_root, c |
| return ASN1_MEM_ERROR; \ |
| } else { \ |
| /* this strcpy is checked */ \ |
| - _asn1_strcpy(ptr, data); \ |
| + if (ptr) { \ |
| + _asn1_strcpy(ptr, data); \ |
| + } \ |
| } |
| |
| #define ADD_STR_VALUE( ptr, ptr_size, data) \ |
| - *len = (int) _asn1_strlen(data) + 1; \ |
| - if (ptr_size < (int) _asn1_strlen(ptr)+(*len)) { \ |
| + *len += _asn1_strlen(data); \ |
| + if (ptr_size < (int) *len) { \ |
| + (*len)++; \ |
| return ASN1_MEM_ERROR; \ |
| } else { \ |
| /* this strcat is checked */ \ |
| - _asn1_strcat(ptr, data); \ |
| + if (ptr) _asn1_strcat (ptr, data); \ |
| } |
| |
| /** |
| @@ -786,7 +793,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) |
| { |
| @@ -800,7 +809,7 @@ asn1_read_value (asn1_node root, const c |
| } |
| p = p->right; |
| } |
| - *len = _asn1_strlen (value) + 1; |
| + (*len)++; |
| } |
| else if ((node->type & CONST_DEFAULT) && (node->value == NULL)) |
| { |