<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>