ASN1: Ensure that d2i_ASN1_OBJECT() frees the strings on ASN1_OBJECT reuse
authorRichard Levitte <levitte@openssl.org>
Tue, 20 Apr 2021 06:43:30 +0000 (08:43 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 27 Apr 2021 10:43:52 +0000 (12:43 +0200)
The 'sn' and 'ln' strings may be dynamically allocated, and the
ASN1_OBJECT flags have a bit set to say this.  If an ASN1_OBJECT with
such strings is passed to d2i_ASN1_OBJECT() for reuse, the strings
must be freed, or there is a memory leak.

Fixes #14667

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/14938)

(cherry picked from commit 65b88a75921533ada8b465bc8d5c0817ad927947)

crypto/asn1/a_object.c

index 3740f608c51db80377afd89aadd85e9d52ddcdfd..c96c36e73029d0db7e7a2dd94c188c5b3beba412 100644 (file)
@@ -291,16 +291,13 @@ ASN1_OBJECT *ossl_c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
         }
     }
 
-    /*
-     * only the ASN1_OBJECTs from the 'table' will have values for ->sn or
-     * ->ln
-     */
     if ((a == NULL) || ((*a) == NULL) ||
         !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
         if ((ret = ASN1_OBJECT_new()) == NULL)
             return NULL;
-    } else
+    } else {
         ret = (*a);
+    }
 
     p = *pp;
     /* detach data from object */
@@ -318,6 +315,12 @@ ASN1_OBJECT *ossl_c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
         ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
     }
     memcpy(data, p, length);
+    /* If there are dynamic strings, free them here, and clear the flag */
+    if ((ret->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) != 0) {
+        OPENSSL_free((char *)ret->sn);
+        OPENSSL_free((char *)ret->ln);
+        ret->flags &= ~ASN1_OBJECT_FLAG_DYNAMIC_STRINGS;
+    }
     /* reattach data to object, after which it remains const */
     ret->data = data;
     ret->length = length;