Fix various malloc failure paths.
Caught by running malloc failure tests on unit tests.
Bug: 563
Change-Id: Ic0167ef346a282dc8b5a26a1cedafced7fef9ed0
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/56927
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c
index ef74d0d..81916c2 100644
--- a/crypto/asn1/a_mbstr.c
+++ b/crypto/asn1/a_mbstr.c
@@ -85,11 +85,6 @@
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
int inform, unsigned long mask, long minsize,
long maxsize) {
- int str_type;
- char free_out;
- ASN1_STRING *dest;
- size_t nchar = 0;
- char strbuf[32];
if (len == -1) {
len = strlen((const char *)in);
}
@@ -128,7 +123,7 @@
// Check |minsize| and |maxsize| and work out the minimal type, if any.
CBS cbs;
CBS_init(&cbs, in, len);
- size_t utf8_len = 0;
+ size_t utf8_len = 0, nchar = 0;
while (CBS_len(&cbs) != 0) {
uint32_t c;
if (!decode_func(&cbs, &c)) {
@@ -169,6 +164,7 @@
utf8_len += cbb_get_utf8_len(c);
}
+ char strbuf[32];
if (minsize > 0 && nchar < (size_t)minsize) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
@@ -184,6 +180,7 @@
}
// Now work out output format and string type
+ int str_type;
int (*encode_func)(CBB *, uint32_t) = cbb_add_latin1;
size_t size_estimate = nchar;
int outform = MBSTRING_ASC;
@@ -216,31 +213,28 @@
if (!out) {
return str_type;
}
+
+ int free_dest = 0;
+ ASN1_STRING *dest;
if (*out) {
- free_out = 0;
dest = *out;
- if (dest->data) {
- dest->length = 0;
- OPENSSL_free(dest->data);
- dest->data = NULL;
- }
- dest->type = str_type;
} else {
- free_out = 1;
+ free_dest = 1;
dest = ASN1_STRING_type_new(str_type);
if (!dest) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
- *out = dest;
}
// If both the same type just copy across
if (inform == outform) {
if (!ASN1_STRING_set(dest, in, len)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
- return -1;
+ goto err;
}
+ dest->type = str_type;
+ *out = dest;
return str_type;
}
@@ -267,12 +261,13 @@
OPENSSL_free(data);
goto err;
}
- dest->length = (int)(data_len - 1);
- dest->data = data;
+ dest->type = str_type;
+ ASN1_STRING_set0(dest, data, (int)data_len - 1);
+ *out = dest;
return str_type;
err:
- if (free_out) {
+ if (free_dest) {
ASN1_STRING_free(dest);
}
CBB_cleanup(&cbb);
diff --git a/crypto/asn1/asn1_test.cc b/crypto/asn1/asn1_test.cc
index 59e80d2..3bb7b34 100644
--- a/crypto/asn1/asn1_test.cc
+++ b/crypto/asn1/asn1_test.cc
@@ -1339,6 +1339,7 @@
SCOPED_TRACE(t.flags);
bssl::UniquePtr<ASN1_STRING> str(ASN1_STRING_type_new(t.type));
+ ASSERT_TRUE(str);
ASSERT_TRUE(ASN1_STRING_set(str.get(), t.data.data(), t.data.size()));
str->flags = t.str_flags;
@@ -1393,6 +1394,7 @@
SCOPED_TRACE(t.flags);
bssl::UniquePtr<ASN1_STRING> str(ASN1_STRING_type_new(t.type));
+ ASSERT_TRUE(str);
ASSERT_TRUE(ASN1_STRING_set(str.get(), t.data.data(), t.data.size()));
str->flags = t.str_flags;
diff --git a/crypto/ecdh_extra/ecdh_test.cc b/crypto/ecdh_extra/ecdh_test.cc
index 4b88754..3948525 100644
--- a/crypto/ecdh_extra/ecdh_test.cc
+++ b/crypto/ecdh_extra/ecdh_test.cc
@@ -274,6 +274,7 @@
}
bssl::UniquePtr<EC_KEY> key(EC_KEY_new());
+ ASSERT_TRUE(key);
ASSERT_TRUE(EC_KEY_set_group(key.get(), a.get()));
ASSERT_TRUE(EC_KEY_generate_key(key.get()));
diff --git a/crypto/evp/p_hkdf.c b/crypto/evp/p_hkdf.c
index 932372d..05158e2 100644
--- a/crypto/evp/p_hkdf.c
+++ b/crypto/evp/p_hkdf.c
@@ -64,7 +64,7 @@
if (hctx_src->key_len != 0) {
hctx_dst->key = OPENSSL_memdup(hctx_src->key, hctx_src->key_len);
- if (hctx_src->key == NULL) {
+ if (hctx_dst->key == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -73,7 +73,7 @@
if (hctx_src->salt_len != 0) {
hctx_dst->salt = OPENSSL_memdup(hctx_src->salt, hctx_src->salt_len);
- if (hctx_src->salt == NULL) {
+ if (hctx_dst->salt == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/crypto/fipsmodule/bn/exponentiation.c b/crypto/fipsmodule/bn/exponentiation.c
index 4ec9171..41c7233 100644
--- a/crypto/fipsmodule/bn/exponentiation.c
+++ b/crypto/fipsmodule/bn/exponentiation.c
@@ -444,6 +444,7 @@
return BN_one(r);
}
+ BN_RECP_CTX_init(&recp);
BN_CTX_start(ctx);
aa = BN_CTX_get(ctx);
val[0] = BN_CTX_get(ctx);
@@ -451,7 +452,6 @@
goto err;
}
- BN_RECP_CTX_init(&recp);
if (m->neg) {
// ignore sign of 'm'
if (!BN_copy(aa, m)) {
diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc
index 8e144ec..88665b2 100644
--- a/crypto/fipsmodule/ec/ec_test.cc
+++ b/crypto/fipsmodule/ec/ec_test.cc
@@ -656,6 +656,7 @@
bssl::UniquePtr<EC_POINT> inf1(EC_POINT_new(group())),
inf2(EC_POINT_new(group()));
ASSERT_TRUE(inf1);
+ ASSERT_TRUE(inf2);
ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf1.get()));
// |q| is currently -|pub2|.
ASSERT_TRUE(EC_POINT_add(group(), inf2.get(), pub2, q.get(), nullptr));
@@ -843,8 +844,8 @@
bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam()));
ASSERT_TRUE(key);
- bssl::UniquePtr<BIGNUM> bn(BN_new());
- ASSERT_TRUE(BN_one(bn.get()));
+ bssl::UniquePtr<BIGNUM> bn(BN_dup(BN_value_one()));
+ ASSERT_TRUE(bn);
BN_set_negative(bn.get(), 1);
EXPECT_FALSE(EC_KEY_set_private_key(key.get(), bn.get()))
<< "Unexpectedly set a key of -1";
@@ -937,11 +938,13 @@
TEST_P(ECCurveTest, GPlusMinusG) {
const EC_POINT *g = EC_GROUP_get0_generator(group());
+
bssl::UniquePtr<EC_POINT> p(EC_POINT_dup(g, group()));
ASSERT_TRUE(p);
ASSERT_TRUE(EC_POINT_invert(group(), p.get(), nullptr));
- bssl::UniquePtr<EC_POINT> sum(EC_POINT_new(group()));
+ bssl::UniquePtr<EC_POINT> sum(EC_POINT_new(group()));
+ ASSERT_TRUE(sum);
ASSERT_TRUE(EC_POINT_add(group(), sum.get(), g, p.get(), nullptr));
EXPECT_TRUE(EC_POINT_is_at_infinity(group(), sum.get()));
}
diff --git a/crypto/obj/obj.c b/crypto/obj/obj.c
index 958625d..c4e1aee 100644
--- a/crypto/obj/obj.c
+++ b/crypto/obj/obj.c
@@ -506,25 +506,37 @@
// obj_add_object inserts |obj| into the various global hashes for run-time
// added objects. It returns one on success or zero otherwise.
static int obj_add_object(ASN1_OBJECT *obj) {
- int ok;
- ASN1_OBJECT *old_object;
-
obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
ASN1_OBJECT_FLAG_DYNAMIC_DATA);
CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock);
if (global_added_by_nid == NULL) {
global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid);
+ }
+ if (global_added_by_data == NULL) {
global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data);
- global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name);
+ }
+ if (global_added_by_short_name == NULL) {
+ global_added_by_short_name =
+ lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name);
+ }
+ if (global_added_by_long_name == NULL) {
global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name);
}
+ int ok = 0;
+ if (global_added_by_nid == NULL ||
+ global_added_by_data == NULL ||
+ global_added_by_short_name == NULL ||
+ global_added_by_long_name == NULL) {
+ goto err;
+ }
+
// We don't pay attention to |old_object| (which contains any previous object
// that was evicted from the hashes) because we don't have a reference count
// on ASN1_OBJECT values. Also, we should never have duplicates nids and so
// should always have objects in |global_added_by_nid|.
-
+ ASN1_OBJECT *old_object;
ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj);
if (obj->length != 0 && obj->data != NULL) {
ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj);
@@ -535,8 +547,9 @@
if (obj->ln != NULL) {
ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj);
}
- CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock);
+err:
+ CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock);
return ok;
}
diff --git a/crypto/pkcs7/pkcs7_test.cc b/crypto/pkcs7/pkcs7_test.cc
index bf85379..3c042ec 100644
--- a/crypto/pkcs7/pkcs7_test.cc
+++ b/crypto/pkcs7/pkcs7_test.cc
@@ -639,6 +639,7 @@
bssl::UniquePtr<BIO> bio(BIO_new_mem_buf(pem, strlen(pem)));
ASSERT_TRUE(bio);
bssl::UniquePtr<STACK_OF(X509_CRL)> crls(sk_X509_CRL_new_null());
+ ASSERT_TRUE(crls);
ASSERT_TRUE(PKCS7_get_PEM_CRLs(crls.get(), bio.get()));
ASSERT_EQ(1u, sk_X509_CRL_num(crls.get()));
diff --git a/crypto/rsa_extra/rsa_test.cc b/crypto/rsa_extra/rsa_test.cc
index 883eb97..d3ee69b 100644
--- a/crypto/rsa_extra/rsa_test.cc
+++ b/crypto/rsa_extra/rsa_test.cc
@@ -513,6 +513,7 @@
SCOPED_TRACE(bits);
rsa.reset(RSA_new());
+ ASSERT_TRUE(rsa);
ASSERT_TRUE(RSA_generate_key_fips(rsa.get(), bits, nullptr));
EXPECT_EQ(bits, BN_num_bits(rsa->n));
}
diff --git a/crypto/stack/stack_test.cc b/crypto/stack/stack_test.cc
index 98e5448..1ff44b9 100644
--- a/crypto/stack/stack_test.cc
+++ b/crypto/stack/stack_test.cc
@@ -317,6 +317,7 @@
// sk_*_find should return the first matching element in all cases.
TEST(StackTest, FindFirst) {
bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+ ASSERT_TRUE(sk);
auto value = TEST_INT_new(1);
ASSERT_TRUE(value);
ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
@@ -397,6 +398,7 @@
TEST(StackTest, DeleteIf) {
bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
+ ASSERT_TRUE(sk);
for (int v : {1, 9, 2, 8, 3, 7, 4, 6, 5}) {
auto obj = TEST_INT_new(v);
ASSERT_TRUE(obj);
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index 7e3c395..b640413 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -284,10 +284,12 @@
// count but it has the same effect by duping the STACK and upping the ref of
// each X509 structure.
STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain) {
- STACK_OF(X509) *ret;
- size_t i;
- ret = sk_X509_dup(chain);
- for (i = 0; i < sk_X509_num(ret); i++) {
+ STACK_OF(X509) *ret = sk_X509_dup(chain);
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ for (size_t i = 0; i < sk_X509_num(ret); i++) {
X509_up_ref(sk_X509_value(ret, i));
}
return ret;
diff --git a/crypto/x509/x509_test.cc b/crypto/x509/x509_test.cc
index e152f3d..4f931b3 100644
--- a/crypto/x509/x509_test.cc
+++ b/crypto/x509/x509_test.cc
@@ -1391,6 +1391,7 @@
TEST(X509Test, ZeroLengthsWithCheckFunctions) {
bssl::UniquePtr<X509> leaf(CertFromPEM(kSANTypesLeaf));
+ ASSERT_TRUE(leaf);
EXPECT_EQ(
1, X509_check_host(leaf.get(), kHostname, strlen(kHostname), 0, nullptr));
@@ -2467,7 +2468,9 @@
for (auto t : asn1_utctime_tests) {
SCOPED_TRACE(t.val);
bssl::UniquePtr<ASN1_UTCTIME> tm(ASN1_UTCTIME_new());
+ ASSERT_TRUE(tm);
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
+ ASSERT_TRUE(bio);
// Use this instead of ASN1_UTCTIME_set() because some callers get
// type-confused and pass ASN1_GENERALIZEDTIME to ASN1_UTCTIME_print().
@@ -2525,6 +2528,7 @@
TEST(X509Test, X509NameSet) {
bssl::UniquePtr<X509_NAME> name(X509_NAME_new());
+ ASSERT_TRUE(name);
EXPECT_TRUE(X509_NAME_add_entry_by_txt(
name.get(), "C", MBSTRING_ASC, reinterpret_cast<const uint8_t *>("US"),
-1, -1, 0));