#45808 [Com]: stream_socket_enable_crypto() blocks and eats CPU

From: Date: Tue, 13 Oct 2009 10:45:22 +0000
Subject: #45808 [Com]: stream_socket_enable_crypto() blocks and eats CPU
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-143521@lists.php.net to get a copy of this message
 ID:               45808
 Comment by:       vincent at optilian dot com
 Reported By:      six at aegis-corp dot org
 Status:           Assigned
 Bug Type:         Streams related
 Operating System: Linux 2.6
 PHP Version:      5.3.0alpha1
 Assigned To:      pajoye
 New Comment:

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;
 			}


Previous Comments:
------------------------------------------------------------------------

[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] garretts@php.net

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.

------------------------------------------------------------------------

[2008-09-25 16:07:31] nasam at mailvault dot com

Bug is in ext/openssl/xp_ssl.c
Function handle_ssl_error: (line 107)
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
       /* re-negotiation, or perhaps the SSL layer needs more
       * packets: retry in next iteration */
       errno = EAGAIN;
       retry = is_init ? 1 : sslsock->s.is_blocked; //BUG
       break;

it sets retry to 1 in php_openssl_enable_crypto no matter if socket is
blocking or not.

------------------------------------------------------------------------

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/45808

-- 
Edit this bug report at http://bugs.php.net/?id=45808&edit=1



Thread (13 messages)

« previous php.bugs (#143521) next »