Fix up do_ext_i2d's error-handling Thanks to wangjiale3 for noticing a leak of ext_oct on malloc error in https://boringssl-review.googlesource.com/c/boringssl/+/58488. This is a fixed version of that CL, and also fixes a leak of ext_der on malloc failure. Change-Id: I2c7ece6b2950a9cb807d78e72b2fddc21897a019 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/58686 Reviewed-by: Bob Beck <bbe@google.com> Auto-Submit: David Benjamin <davidben@google.com> Commit-Queue: Bob Beck <bbe@google.com>
diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509v3/v3_conf.c index 8f71502..598fba3 100644 --- a/crypto/x509v3/v3_conf.c +++ b/crypto/x509v3/v3_conf.c
@@ -202,42 +202,38 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid, int crit, void *ext_struc) { + // Convert the extension's internal representation to DER. unsigned char *ext_der; int ext_len; - ASN1_OCTET_STRING *ext_oct; - X509_EXTENSION *ext; - // Convert internal representation to DER if (method->it) { ext_der = NULL; ext_len = ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); if (ext_len < 0) { - goto merr; + return NULL; } } else { - unsigned char *p; + // TODO(davidben): Remove support for the "old-style" ASN.1 callbacks. Every + // |X509V3_EXT_METHOD|, both inside and outside the library, has an + // |ASN1_ITEM|, and this codepath is missing handling. ext_len = method->i2d(ext_struc, NULL); if (!(ext_der = OPENSSL_malloc(ext_len))) { - goto merr; + return NULL; } - p = ext_der; + unsigned char *p = ext_der; method->i2d(ext_struc, &p); } - if (!(ext_oct = ASN1_OCTET_STRING_new())) { - goto merr; - } - ext_oct->data = ext_der; - ext_oct->length = ext_len; - ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); - if (!ext) { - goto merr; + ASN1_OCTET_STRING *ext_oct = ASN1_OCTET_STRING_new(); + if (ext_oct == NULL) { + OPENSSL_free(ext_der); + return NULL; } + ASN1_STRING_set0(ext_oct, ext_der, ext_len); + + X509_EXTENSION *ext = + X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); ASN1_OCTET_STRING_free(ext_oct); - return ext; - -merr: - return NULL; } // Given an internal structure, nid and critical flag create an extension