Fix potential memory leak in ASN1_TIME_to_generalizedtime()
authorTodd Short <tshort@akamai.com>
Fri, 17 Feb 2017 16:36:13 +0000 (11:36 -0500)
committerRich Salz <rsalz@openssl.org>
Thu, 23 Feb 2017 22:17:11 +0000 (17:17 -0500)
If ret is allocated, it may be leaked on error.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2666)
(cherry picked from commit 4483e23444fa18034344874ffbe67919207e9e47)

crypto/asn1/a_time.c

index fcb2d565cdd0acdff81f7904d4a4951e200cbabd..607432581686473fd971c4372b8c66b599a2cafc 100644 (file)
@@ -137,7 +137,7 @@ int ASN1_TIME_check(ASN1_TIME *t)
 ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
                                                    ASN1_GENERALIZEDTIME **out)
 {
-    ASN1_GENERALIZEDTIME *ret;
+    ASN1_GENERALIZEDTIME *ret = NULL;
     char *str;
     int newlen;
 
@@ -146,7 +146,7 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
 
     if (!out || !*out) {
         if (!(ret = ASN1_GENERALIZEDTIME_new()))
-            return NULL;
+            goto err;
         if (out)
             *out = ret;
     } else
@@ -155,13 +155,13 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
     /* If already GeneralizedTime just copy across */
     if (t->type == V_ASN1_GENERALIZEDTIME) {
         if (!ASN1_STRING_set(ret, t->data, t->length))
-            return NULL;
-        return ret;
+            goto err;
+        goto done;
     }
 
     /* grow the string */
     if (!ASN1_STRING_set(ret, NULL, t->length + 2))
-        return NULL;
+        goto err;
     /* ASN1_STRING_set() allocated 'len + 1' bytes. */
     newlen = t->length + 2 + 1;
     str = (char *)ret->data;
@@ -173,9 +173,18 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
 
     BUF_strlcat(str, (char *)t->data, newlen);
 
-    return ret;
+ done:
+   if (out != NULL && *out == NULL)
+       *out = ret;
+   return ret;
+
+ err:
+    if (out == NULL || *out != ret)
+        ASN1_GENERALIZEDTIME_free(ret);
+    return NULL;
 }
 
+
 int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
 {
     ASN1_TIME t;