I am using openssl-1.0.1 in my 32bit app on 64bit Windows, I got a crash in
ssleay32!freelist_extract(See "Call Stack" in the "OTHER INFO" section as
follow), it is not easy to recreate it and we cannot find a stable way to
recreate it, but it happened several times. After looking into the dump
file and analyzing the heap, now I suspect it is a potential bug in
OpenSSL, here is my analysis:
1. I check the local variables in frame "ssleay32!freelist_extract+0x3c"
and found the structure of free list rbuf_freelist was corrupted, The
length of the list is 10 (the value of len is 0xa), but there is only one
valid node in the list -- the head, the next pointer of head is pointing to
some invalid memory. The free list for write, wbuf_freelist, got the same
problem (length is 10, but only one valid node, next pointer of head points
to invalid memory). so we can reach the conclusion that the heap memory
which the head pointer points to was corrupted.(See "Call Stack" and "Local
variables for frame: ssleay32!freelist_extract+0x3c" below)
2. From the corrupt pattern -- the "next" pointer (the first 4 bytes of
the user accessible part of the heap block) was corrupted, but the 8 bytes
metadata of the heap block was not. It looks like the pointer points to the
user accessible part of the heap block was still in use after the buffer
had been released (e.g. by calling ssl3_release_read_buffer(...)), or
caused by some other similar mistakes.
3. From the corrupt pattern, I think the possibility that it is caused
by memory overrun/underrun is very low. AND given that there are 2 lists
(rbuf_freelist & wbuf_freelist) experiencing the same issue, the
possibility become much lower.
4. I think it is unlikely that the root cause of this issue is in my own
code, since the rbuf_freelist and wbuf_freelist are internal structures in
OpenSSL, my own code does not access these internal structures directly.
OTHER INFO:
--------------------------------------------------------------------------------------------------------------
OpenSSL version, extracted from the README file
--------------------------------------------------------------------------------------------------------------
OpenSSL 1.0.1 14 Mar 2012
--------------------------------------------------------------------------------------------------------------
OS version and platform:
--------------------------------------------------------------------------------------------------------------
Windows Server 2008 R2 Enterprise Edition 6.1 SP 1.
VMware Virtual Platform.
--------------------------------------------------------------------------------------------------------------
Compiler:
--------------------------------------------------------------------------------------------------------------
VC8.0 (VS2005)
--------------------------------------------------------------------------------------------------------------
Local variables for frame: ssleay32!freelist_extract+0x3c
--------------------------------------------------------------------------------------------------------------
ctx
|- method
....
|- wbuf_freelist
|- chucklen (0x44b0)
|- len (0xa)
|- head (0x00dd1098)
|- next (0x17dd1098)
|- next (Memory access error)
|- next (Memory access error)
|- next (Memory access error)
...
|- rbuf_freelist
|- chucklen (0x4548)
|- len (0xa)
|- head (0x00d84a20)
|- next (0x17000316)
|- next (Memory access error)
|- next (Memory access error)
|- next (Memory access error)
...
for_read (0n1)
sz (0n17736)
--------------------------------------------------------------------------------------------------------------
Call Stack:
--------------------------------------------------------------------------------------------------------------
ntdll!NtWaitForMultipleObjects+0x15
KERNELBASE!WaitForMultipleObjectsEx+0x100
kernel32!WaitForMultipleObjectsExImplementation+0xe0
kernel32!WaitForMultipleObjects+0x18
kernel32!WerpReportFaultInternal+0x186
kernel32!WerpReportFault+0x70
kernel32!BasepReportFault+0x20
kernel32!UnhandledExceptionFilter+0x1af
ntdll!__RtlUserThreadStart+0x62
ntdll!_EH4_CallFilterFunc+0x12
ntdll!_except_handler4+0x8e
ntdll!ExecuteHandler2+0x26
ntdll!ExecuteHandler+0x24
ntdll!RtlDispatchException+0x127
ntdll!KiUserExceptionDispatcher+0xf
ssleay32!freelist_extract+0x3c [...\openssl\ssl\s3_both.c @ 691]
ssleay32!ssl3_setup_read_buffer+0x7b [...\openssl\ssl\s3_both.c @ 760]
ssleay32!ssl3_setup_buffers+0xb [...\openssl\ssl\s3_both.c @ 817]
ssleay32!ssl23_get_client_hello+0x34 [...\openssl\ssl\s23_srvr.c @ 266]
ssleay32!ssl23_accept+0x16e [...\openssl\ssl\s23_srvr.c @ 210]
ssleay32!SSL_accept+0x1d [...\openssl\ssl\ssl_lib.c @ 938]
(stacks in my code have been removed)
--------------------------------------------------------------------------------------------------------------
Source code for freelist_extract in s3_both.c
--------------------------------------------------------------------------------------------------------------
static void *
freelist_extract(SSL_CTX *ctx, int for_read, int sz)
{
SSL3_BUF_FREELIST *list;
SSL3_BUF_FREELIST_ENTRY *ent = NULL;
void *result = NULL;
CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX);
list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist;
if (list != NULL && sz == (int)list->chunklen)
ent = list->head;
if (ent != NULL)
{
list->head = ent->next; //Crash here, line 691
result = ent;
if (--list->len == 0)
list->chunklen = 0;
}
CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX);
if (!result)
result = OPENSSL_malloc(sz);
return result;
}
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]