Hello, Our UC-KLEE tool discovered a double free bug in i2o_ECPublicKey (all recent versions of OpenSSL).
The bug occurs in i2o_ECPublicKey (crypto/ec/ec_asn1.c). A double free is
triggered if the second call to EC_POINT_point2oct (line 1434 of
crypto/ec/ec_asn1.c) returns 0 from a callsite where i2o_ECPublicKey was passed
a valid *out buffer:
if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form,
*out, buf_len, NULL))
{
ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB);
OPENSSL_free(*out);
*out = NULL;
return 0;
}
Even if the first call to EC_POINT_point2oct succeeds, the second call may fail
since a bunch of code is bypassed by the first call (when buf == NULL). I'm not
well-versed in the OpenSSL codebase, but it seems like an attacker might be
able to supply inputs that cause EC_POINT_get_affine_coordinates_GFp (called by
EC_POINT_point2oct) to fail.
Callers of i2o_ECPublicKey typically don't expect their buffers to have been
freed by i2o_ECPublicKey. The offending callsites where a double free would
occur are in crypto/ec/ec_ameth.c:
- eckey_pub_encode, line 127; jumps to line 134 and causes a double free with
the call to OPENSSL_free on line 139.
- ecdh_cms_encrypt, line 900; jumps to line 1000 and similarly calls
OPENSSL_free on line 1001.
I've attached a proposed patch that I believe captures the intent of the
function, which is to free the buffer only if 'new_buffer' is set.
-David
double-free-i2o_ECPublicKey.patch
Description: Binary data
