summaryrefslogtreecommitdiffstats
path: root/crypto/asn1
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-04-20 08:43:30 +0200
committerRichard Levitte <levitte@openssl.org>2021-04-27 12:41:28 +0200
commit65b88a75921533ada8b465bc8d5c0817ad927947 (patch)
tree494c31f80bb4fb8aa0c34b04f94c7b223b33dd6a /crypto/asn1
parent513ead860853e0d07f7fc43bf35d1b90fdad5a11 (diff)
ASN1: Ensure that d2i_ASN1_OBJECT() frees the strings on ASN1_OBJECT reuse
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)
Diffstat (limited to 'crypto/asn1')
-rw-r--r--crypto/asn1/a_object.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
index d67a723c96..8790be340a 100644
--- a/crypto/asn1/a_object.c
+++ b/crypto/asn1/a_object.c
@@ -286,16 +286,13 @@ ASN1_OBJECT *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 */
@@ -313,6 +310,12 @@ ASN1_OBJECT *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;