Hello,
Our UC-KLEE tool found a NULL pointer dereference bug in do_ssl3_write (ssl/s3_pkt.c) when an alert is pending and the SSL_MODE_RELEASE_BUFFERS flag is used. This bug affects the latest 1.0.1 branch.
The code for do_ssl3_write() first checks whether the write buffer is NULL:
644 if (wb->buf == NULL)
645 if (!ssl3_setup_write_buffer(s))
646 return -1;
It then dispatches any pending alerts:
653 /* If we have an alert to send, lets send it */
654 if (s->s3->alert_dispatch)
655 {
656 i=s->method->ssl_dispatch_alert(s);
This call to ssl3_dispatch_alert() calls do_ssl3_write() again:
1501 i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);
Which calls ssl3_write_pending():
852 /* we now just need to write the buffer */
853 return ssl3_write_pending(s,type,buf,len);
Which releases the write buffer if SSL_MODE_RELEASE_BUFFERS is used:
894 if (s->mode & SSL_MODE_RELEASE_BUFFERS &&
895 SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER)
896 ssl3_release_write_buffer(s);
When control returns back to the original do_ssl3_write() call, wb->buf has been set to NULL (*after* the NULL check). The NULL pointer dereference then occurs at:
743 *(p++)=type&0xff;
A second check is necessary after the call to ssl->dispatch_alert(), or a counter could be added to ssl_st to avoid releasing the buffers if any callers are performing writes.
-David