diff options
author | Todd Short <tshort@akamai.com> | 2020-08-31 19:59:43 -0400 |
---|---|---|
committer | Benjamin Kaduk <bkaduk@akamai.com> | 2020-09-02 15:21:11 -0700 |
commit | 2b748d722b6ac560d122ea2dcf8d09fe6f03124b (patch) | |
tree | 13c4f50f7e76a59d03eb755d790ab72dd1c86d23 /crypto/provider_core.c | |
parent | 2c0e356ef7fdbb117c9294b57deb67be66db3470 (diff) |
Fix use of OPENSSL_realloc in provider
Fix OPENSSL_realloc failure case; `provider->operation_bits` memory
is lost when `OPENSSL_realloc()` returns NULL.
`operation_bits_sz` is never set to the length of the allocated array.
This means that operation_bits is always reallocated in
`ossl_provider_set_operation_bit()`, possibly shrinking the array.
In addition, it means that the `memset()` always zeros out the
whole reallocated array, not just the new part. Also, because
`operation_bits_sz` is always zero, the value of `*result` in
`ossl_provider_test_operation_bit()` will always be zero.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Ben Kaduk <kaduk@mit.edu>
(Merged from https://github.com/openssl/openssl/pull/12760)
Diffstat (limited to 'crypto/provider_core.c')
-rw-r--r-- | crypto/provider_core.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/crypto/provider_core.c b/crypto/provider_core.c index a714a71681..f282071e2d 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -875,14 +875,17 @@ int ossl_provider_set_operation_bit(OSSL_PROVIDER *provider, size_t bitnum) unsigned char bit = (1 << (bitnum % 8)) & 0xFF; if (provider->operation_bits_sz <= byte) { - provider->operation_bits = OPENSSL_realloc(provider->operation_bits, - byte + 1); - if (provider->operation_bits == NULL) { + unsigned char *tmp = OPENSSL_realloc(provider->operation_bits, + byte + 1); + + if (tmp == NULL) { ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } + provider->operation_bits = tmp; memset(provider->operation_bits + provider->operation_bits_sz, '\0', byte + 1 - provider->operation_bits_sz); + provider->operation_bits_sz = byte + 1; } provider->operation_bits[byte] |= bit; return 1; |