Fix OBJ_dup's handling of malloc failures r->data doesn't get freed in the error path. Since we have a functional ASN1_OBJECT, just use ASN1_OBJECT_free to clean up the temporary. Change-Id: Ie0583048e8c781bd02807895a89ed8627dfc7478 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/95987 Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: Lily Chen <chlily@google.com> Presubmit-BoringSSL-Verified: boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com <boringssl-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Lily Chen <chlily@google.com>
diff --git a/crypto/asn1/a_object.cc b/crypto/asn1/a_object.cc index 125058a..1ed5ee1 100644 --- a/crypto/asn1/a_object.cc +++ b/crypto/asn1/a_object.cc
@@ -158,12 +158,12 @@ return; } if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { - OPENSSL_free((void *)a->sn); - OPENSSL_free((void *)a->ln); + OPENSSL_free(const_cast<char *>(a->sn)); + OPENSSL_free(const_cast<char *>(a->ln)); a->sn = a->ln = nullptr; } if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { - OPENSSL_free((void *)a->data); + OPENSSL_free(const_cast<uint8_t *>(a->data)); a->data = nullptr; a->length = 0; }
diff --git a/crypto/obj/obj.cc b/crypto/obj/obj.cc index a6e6e5a..04cc4f8 100644 --- a/crypto/obj/obj.cc +++ b/crypto/obj/obj.cc
@@ -57,63 +57,48 @@ } ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { - ASN1_OBJECT *r; - unsigned char *data = nullptr; - char *sn = nullptr, *ln = nullptr; - if (o == nullptr) { return nullptr; } if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { // TODO(fork): this is a little dangerous. - return (ASN1_OBJECT *)o; + return const_cast<ASN1_OBJECT *>(o); } - r = ASN1_OBJECT_new(); + UniquePtr<ASN1_OBJECT> r(ASN1_OBJECT_new()); if (r == nullptr) { OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB); return nullptr; } - r->ln = r->sn = nullptr; - // once data is attached to an object, it remains const + // All fields of the object will be allocated. + r->flags = o->flags | ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA; + r->data = reinterpret_cast<uint8_t *>(OPENSSL_memdup(o->data, o->length)); if (o->length != 0 && r->data == nullptr) { - goto err; + return nullptr; } r->length = o->length; r->nid = o->nid; if (o->ln != nullptr) { - ln = OPENSSL_strdup(o->ln); - if (ln == nullptr) { - goto err; + r->ln = OPENSSL_strdup(o->ln); + if (r->ln == nullptr) { + return nullptr; } } if (o->sn != nullptr) { - sn = OPENSSL_strdup(o->sn); - if (sn == nullptr) { - goto err; + r->sn = OPENSSL_strdup(o->sn); + if (r->sn == nullptr) { + return nullptr; } } - r->sn = sn; - r->ln = ln; - - r->flags = - o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | - ASN1_OBJECT_FLAG_DYNAMIC_DATA); - return r; - -err: - OPENSSL_free(ln); - OPENSSL_free(sn); - OPENSSL_free(data); - OPENSSL_free(r); - return nullptr; + return r.release(); } int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) {