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


Attachment: double-free-i2o_ECPublicKey.patch
Description: Binary data

Reply via email to