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:14:48 +0000 (17:14 -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)

crypto/asn1/a_time.c

index 3f82c2b..db82d29 100644 (file)
@@ -62,7 +62,7 @@ int ASN1_TIME_check(const 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;
 
@@ -71,22 +71,20 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
 
     if (out == NULL || *out == NULL) {
         if ((ret = ASN1_GENERALIZEDTIME_new()) == NULL)
-            return NULL;
-        if (out)
-            *out = ret;
+            goto err;
     } else
         ret = *out;
 
     /* 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;
@@ -96,11 +94,20 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
     else
         OPENSSL_strlcpy(str, "20", newlen);
 
-    OPENSSL_strlcat(str, (char *)t->data, newlen);
+    OPENSSL_strlcat(str, (const 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;