diff options
author | Richard Levitte <levitte@openssl.org> | 2021-04-20 08:43:30 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2021-04-27 12:43:52 +0200 |
commit | 1727465471e800548694da96b8970743b7efa7ff (patch) | |
tree | 6e91c487b2c0f951c985f5c27dfc699abad50c4e /crypto/asn1/a_object.c | |
parent | 94471ccfdab810a3cdc35116831c231ca277d814 (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)
(cherry picked from commit 65b88a75921533ada8b465bc8d5c0817ad927947)
Diffstat (limited to 'crypto/asn1/a_object.c')
-rw-r--r-- | crypto/asn1/a_object.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c index 3740f608c5..c96c36e730 100644 --- a/crypto/asn1/a_object.c +++ b/crypto/asn1/a_object.c @@ -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; |