On 26/02/2012 22:30, Stefan Fritsch wrote:
> Hi,
>
> running ab via https on httpd trunk with mpm event, I got some crashes
> with
>
> *** glibc detected *** /usr/local/apache2/bin/httpd: free(): invalid
> pointer: 0x0883bd68 ***
>
> or
>
> *** glibc detected *** /usr/local/apache2/bin/httpd: double free or
> corruption (fasttop): 0xe1614d58 ***
>
> The free happens inside openssl in EC_GROUP_free(). Does anyone have
> any idea how to debug this? Steve? I still have the coredump and could
> dump interesting values.
>
Hmmm... it looks like there is a race condition in here:
EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen)
{
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
static EC_KEY *ecdh = NULL;
static int init = 0;
/* XXX Uses 256-bit key for now. TODO: support other sizes. */
ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
"handing out temporary 256 bit ECC key");
if (init == 0) {
ecdh = EC_KEY_new();
if (ecdh != NULL) {
/* ecdh->group = EC_GROUP_new_by_nid(NID_secp160r2); */
EC_KEY_set_group(ecdh,
EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
}
init = 1;
}
return ecdh;
}
Consider two threads calling that at once with init == 0. The static variable
ecdh could end up being modified by two threads simultaneously.
You could include a lock in there or just call ssl_callback_tmpECDH before
starting any threads. Alternatively if you're just setting one curve then you
might as well call SSL_CTX_set_tmp_ecdh and avoid the callback altogether.
[BTW the whole ECDH parameter passing technique is a bit broken in OpenSSL and
needs revising]
Steve.
--
Dr Stephen Henson. OpenSSL Software Foundation, Inc.
1829 Mount Ephraim Road
Adamstown, MD 21710
+1 877-673-6775
[email protected]