ports/122526: lighttpd active SSL connection loss (SSL3_WRITE_PENDING:bad write retry)
Harald Schmalzbauer
harry at omnisec.de
Mon Apr 7 11:20:01 UTC 2008
>Number: 122526
>Category: ports
>Synopsis: lighttpd active SSL connection loss (SSL3_WRITE_PENDING:bad write retry)
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Apr 07 11:20:00 UTC 2008
>Closed-Date:
>Last-Modified:
>Originator: Harald Schmalzbauer
>Release: FreeBSD 7.0-STABLE i386
>Organization:
OmniSEC
>Environment:
System: FreeBSD titan.flintsbach.schmalzbauer.de 7.0-STABLE FreeBSD 7.0-STABLE #1: Thu Mar 27 09:36:49 CET 2008 root at titan.flintsbach.schmalzbauer.de:/usr/obj/usr/src/sys/TITAN i386
>Description:
lighttpd 1.4.19 shows these lines in the error-log:
(network_openssl.c.130) SSL: 1 -1 error:1409F07F:SSL routines:SSL3_WRITE_PENDING:bad write retry
(connections.c.614) connection closed: write failed on fd 8
If one of two concurrent SSL connections get cancelled by the client then also the other connection gets closed by lighhtpd.
According to http://trac.lighttpd.net/trac/ticket/285 this is a closed DoS vulnerability
(http://nvd.nist.gov/nvd.cfm?cvename=CVE-2008-1531)
>How-To-Repeat:
Install lighttpd 1.4.19 and download something using SSL
>Fix:
add patch-SSL_shutdown to files directory:
--- src/connections.c (revision 2103)
+++ src/connections.c (revision 2136)
@@ -200,4 +200,5 @@
/* don't resize the buffer if we were in SSL_ERROR_WANT_* */
+ ERR_clear_error();
do {
if (!con->ssl_error_want_reuse_buffer) {
@@ -1670,4 +1671,5 @@
if (srv_sock->is_ssl) {
int ret;
+ ERR_clear_error();
switch ((ret = SSL_shutdown(con->ssl))) {
case 1:
@@ -1675,6 +1677,8 @@
break;
case 0:
- SSL_shutdown(con->ssl);
- break;
+ ERR_clear_error();
+ if ((ret = SSL_shutdown(con->ssl)) == 1) break;
+
+ // fall through
default:
log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
--- src/network_openssl.c (revision 2084)
+++ src/network_openssl.c (revision 2136)
@@ -86,4 +86,5 @@
*/
+ ERR_clear_error();
if ((r = SSL_write(ssl, offset, toSend)) <= 0) {
unsigned long err;
@@ -188,4 +189,5 @@
close(ifd);
+ ERR_clear_error();
if ((r = SSL_write(ssl, s, toSend)) <= 0) {
unsigned long err;
--- NEWS (revision 2130)
+++ NEWS (revision 2136)
@@ -9,4 +9,5 @@
* Fix mod_extforward to compile with old gcc version (#1591)
* Update documentation for #1587
+ * Fix #285 again: read error after SSL_shutdown (thx marton.illes at balabit.com) and clear the error queue before some other calls
- 1.4.19 - 2008-03-10
--- src/connections.c (revision 2136)
+++ src/connections.c (revision 2139)
@@ -1670,5 +1670,6 @@
#ifdef USE_OPENSSL
if (srv_sock->is_ssl) {
- int ret;
+ int ret, ssl_r;
+ unsigned long err;
ERR_clear_error();
switch ((ret = SSL_shutdown(con->ssl))) {
@@ -1678,14 +1679,40 @@
case 0:
ERR_clear_error();
- if ((ret = SSL_shutdown(con->ssl)) == 1) break;
+ if (-1 != (ret = SSL_shutdown(con->ssl))) break;
// fall through
default:
- log_error_write(srv, __FILE__, __LINE__, "sds", "SSL:",
- SSL_get_error(con->ssl, ret),
- ERR_error_string(ERR_get_error(), NULL));
- return -1;
+
+ switch ((ssl_r = SSL_get_error(con->ssl, ret))) {
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ break;
+ case SSL_ERROR_SYSCALL:
+ /* perhaps we have error waiting in our error-queue */
+ if (0 != (err = ERR_get_error())) {
+ do {
+ log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
+ ssl_r, ret,
+ ERR_error_string(err, NULL));
+ } while((err = ERR_get_error()));
+ } else {
+ log_error_write(srv, __FILE__, __LINE__, "sddds", "SSL (error):",
+ ssl_r, r, errno,
+ strerror(errno));
+ }
+
+ break;
+ default:
+ while((err = ERR_get_error())) {
+ log_error_write(srv, __FILE__, __LINE__, "sdds", "SSL:",
+ ssl_r, ret,
+ ERR_error_string(err, NULL));
+ }
+
+ break;
+ }
}
}
+ ERR_clear_error();
#endif
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list