]> granicus.if.org Git - php/commitdiff
Fix Bug #69402: Reading empty SSL stream hangs until timeout
authorDaniel Lowrey <rdlowrey@php.net>
Tue, 14 Apr 2015 15:12:28 +0000 (09:12 -0600)
committerDaniel Lowrey <rdlowrey@php.net>
Tue, 14 Apr 2015 15:24:40 +0000 (09:24 -0600)
NEWS
ext/openssl/xp_ssl.c

diff --git a/NEWS b/NEWS
index a71c3fca5b5c1be792215e858097b786c38e7599..b274ce8c321359278a92be7f5ce1a9456ca1489d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,10 @@ PHP                                                                        NEWS
   . Fixed bug #69281 (opcache_is_script_cached no longer works). (danack)
   . Fixed bug #68677 (Use After Free). (CVE-2015-1351) (Laruence)
 
+- OpenSSL:
+  . Fixed bug #69402 (Reading empty SSL stream hangs until timeout).
+    (Daniel Lowrey)
+
 - Sqlite3:
   . Fixed bug #66550 (SQLite prepared statement use-after-free). (Sean Heelan)
 
index e8bc6ae39d358e4bff41360614a46b9e09c23189..6c80c2228733ec8e479500359368ab524717280b 100644 (file)
@@ -195,7 +195,7 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
 {
        php_openssl_netstream_data_t *sslsock = (php_openssl_netstream_data_t*)stream->abstract;
        int nr_bytes = 0;
-       
+
        /* Only do this if SSL is active. */
        if (sslsock->ssl_active) {
                int retry = 1;
@@ -271,13 +271,18 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
 
                                /* Also, on reads, we may get this condition on an EOF. We should check properly. */
                                if (read) {
-                               stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
+                                       stream->eof = (retry == 0 && errno != EAGAIN && !SSL_pending(sslsock->ssl_handle));
                                }
-                               
+
+                               /* Don't loop indefinitely in non-blocking mode if no data is available */
+                               if (began_blocked == 0) {
+                                       break;
+                               }
+
                                /* Now, if we have to wait some time, and we're supposed to be blocking, wait for the socket to become
                                 * available. Now, php_pollfd_for uses select to wait up to our time_left value only...
                                 */
-                               if (retry && began_blocked) {
+                               if (retry) {
                                        if (read) {
                                                php_pollfd_for(sslsock->s.socket, (err == SSL_ERROR_WANT_WRITE) ?
                                                        (POLLOUT|POLLPRI) : (POLLIN|POLLPRI), has_timeout ? &left_time : NULL);