<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<font face="Courier New, Courier, monospace">Hi,<br>
<br>
I've been hunting down a heap corruption bug in OpenSSL for the
past few days and I found the guilty instruction. At this point, I
know what causes the problem but I am unsure how to solve it
nicely.<br>
<br>
Here is the minimal sample I used to reproduce the issue on the
latest 1.0.2a (happens on every run, on all platforms in 64 bits):<br>
<br>
int main()<br>
{<br>
ERR_load_crypto_strings(); OpenSSL_add_all_algorithms();
ENGINE_load_builtin_engines();<br>
<br>
EC_GROUP* group = EC_GROUP_new_by_curve_name(NID_sect571k1);<br>
EC_GROUP_set_point_conversion_form(group,
POINT_CONVERSION_UNCOMPRESSED);<br>
<br>
EC_KEY* eckey = EC_KEY_new();<br>
EC_KEY_set_group(eckey, group);<br>
EC_KEY_generate_key(eckey);<br>
<br>
BIO* out = BIO_new(BIO_s_file());<br>
BIO_set_fp(out, stdout, BIO_NOCLOSE);<br>
<br>
PEM_write_bio_ECPrivateKey(out, eckey, NULL, NULL, 0, NULL,
NULL);<br>
}<br>
<br>
Basically what happens is that, somewhere inside the call to
PEM_write_bio_ECPrivateKey(), an ASN1 sequence of 3 elements is
allocated. The corresponding code is as follow (in
crypto/asn1/tasn_new.c:181):<br>
<br>
if (!combine) {<br>
*pval = OPENSSL_malloc(it->size);<br>
if (!*pval)<br>
goto memerr;<br>
memset(*pval, 0, it->size);<br>
asn1_do_lock(pval, 0, it);<br>
asn1_enc_init(pval, it);<br>
}<br>
for (i = 0, tt = it->templates; i < it->tcount; tt++,
i++) {<br>
pseqval = asn1_get_field_ptr(pval, tt);<br>
if (!ASN1_template_new(pseqval, tt))<br>
goto memerr;<br>
}<br>
<br>
In the sample I gave, at some point OPENSSL_malloc allocates 12
bytes for a 3-elements ASN1 SEQUENCE. The for-loop then
initializes every element: </font><font face="Courier New,
Courier, monospace"><font face="Courier New, Courier, monospace">ASN1_template_new()
calls in turn asn1_item_ex_combine_new() which, at line 103,
does:<br>
<br>
if (!combine)<br>
*pval = NULL;<br>
<br>
The problem is that pval at this point points to an element of
the SEQUENCE that is only 4 bytes long. On 64 bits systems this
causes the next 4 bytes to be set to 0x00000000. For the first
two elements of the sequence, this gets recovered by the next
element being initialized. However for the last element, this
affectation happens to write 4 bytes past the allocated memory,
corrupting the heap.<br>
<br>
I'm not sure what is the best place to fix this. Do you have any
hints ?<br>
<br>
Julien Kauffmann.<br>
</font></font>
</body>
</html>