Edit report at http://bugs.php.net/bug.php?id=45808&edit=1
ID: 45808 Updated by: [email protected] Reported by: six at aegis-corp dot org -Summary: stream_socket_enable_crypto() blocks and eats CPU +Summary: [PATCH] stream_socket_enable_crypto() blocks and eats CPU Status: Assigned Type: Bug Package: Streams related Operating System: Linux 2.6 PHP Version: 5.*, 6 Assigned To: pajoye New Comment: Pierre, what about this patch? Previous Comments: ------------------------------------------------------------------------ [2009-10-13 10:45:21] vincent at optilian dot com Actually I fixed some things in the patch, see below ... It makes more sense to test whether the socket is in blocking mode, even if a client ssl socket doesn't need multiple calls to stream_socket_enable_crypto() --- xp_ssl.c.orig 2009-10-12 19:34:31.000000000 +0200 +++ xp_ssl.c 2009-10-13 12:30:24.000000000 +0200 @@ -299,8 +299,12 @@ SSL_METHOD *method; if (sslsock->ssl_handle) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS already set-up for this stream"); - return -1; + if (sslsock->s.is_blocked) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS already set-up for this stream"); + return -1; + } else { + return 0; + } } /* need to do slightly different things, based on client/server method, @@ -415,7 +419,7 @@ } if (n <= 0) { - retry = handle_ssl_error(stream, n, 1 TSRMLS_CC); + retry = handle_ssl_error(stream, n, sslsock->is_client || sslsock->s.is_blocked TSRMLS_CC); } else { break; } ------------------------------------------------------------------------ [2009-10-12 20:50:36] vincent at optilian dot com Here is a patch to fix this issue (diff against 5.3.0) As far as I have tested, everything works as expected with this patch applied. --- xp_ssl.c.orig 2009-10-12 19:34:31.000000000 +0200 +++ xp_ssl.c 2009-10-12 20:39:19.000000000 +0200 @@ -299,8 +299,12 @@ SSL_METHOD *method; if (sslsock->ssl_handle) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS already set-up for this stream"); - return -1; + if (sslsock->is_client) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSL/TLS already set-up for this stream"); + return -1; + } else { + return 0; + } } /* need to do slightly different things, based on client/server method, @@ -415,7 +419,7 @@ } if (n <= 0) { - retry = handle_ssl_error(stream, n, 1 TSRMLS_CC); + retry = handle_ssl_error(stream, n, sslsock->is_client TSRMLS_CC); } else { break; } ------------------------------------------------------------------------ [2009-08-18 16:15:00] [email protected] FYI: I can't repro this on Windows with the build off the snaps' box (VC9 x86 Non Thread Safe (2009-Aug-18 16:00:00)). It: blocks until connection using telnet[expected] doens't consume any CPU[expected] and returns 'bool(false)' [expected -- I assume the same as 'int(0)'] and exits[expected] G ------------------------------------------------------------------------ [2008-10-30 11:03:57] xl269 at cam dot ac dot uk just to confirm that this bug still exists in php5.3-200810292330 ------------------------------------------------------------------------ [2008-09-25 17:59:37] singularity_control at rcpt dot at This makes a serious security issue. It is a very effective DoS on all single process PHP servers with SSL and a slightly less bad DoS on multi-process PHP servers. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/bug.php?id=45808 -- Edit this bug report at http://bugs.php.net/bug.php?id=45808&edit=1
