diff --git a/NEWS b/NEWS index 44d7b87e6ca..c54c42628e2 100644 --- a/NEWS +++ b/NEWS @@ -45,6 +45,9 @@ PHP NEWS properties in traits). (nielsdos) . Fix leak of accel_globals->key. (nielsdos) +- OpenSSL: + . Fix missing checks against php_set_blocking() in xp_ssl.c. (nielsdos) + - SPL: . Fixed bug GH-18421 (Integer overflow with large numbers in LimitIterator). (nielsdos) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index eb7ab93815a..d4f162b7b4f 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -1897,6 +1897,15 @@ static int php_openssl_capture_peer_certs(php_stream *stream, } /* }}} */ +static zend_result php_openssl_set_blocking(php_openssl_netstream_data_t *sslsock, int block) +{ + zend_result result = php_set_sock_blocking(sslsock->s.socket, block); + if (EXPECTED(SUCCESS == result)) { + sslsock->s.is_blocked = block; + } + return result; +} + static int php_openssl_enable_crypto(php_stream *stream, php_openssl_netstream_data_t *sslsock, php_stream_xport_crypto_param *cparam) /* {{{ */ @@ -1925,8 +1934,7 @@ static int php_openssl_enable_crypto(php_stream *stream, sslsock->state_set = 1; } - if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0)) { - sslsock->s.is_blocked = 0; + if (SUCCESS == php_openssl_set_blocking(sslsock, 0)) { /* The following mode are added only if we are able to change socket * to non blocking mode which is also used for read and write */ SSL_set_mode(sslsock->ssl_handle, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); @@ -1979,8 +1987,8 @@ static int php_openssl_enable_crypto(php_stream *stream, } } while (retry); - if (sslsock->s.is_blocked != blocked && SUCCESS == php_set_sock_blocking(sslsock->s.socket, blocked)) { - sslsock->s.is_blocked = blocked; + if (sslsock->s.is_blocked != blocked) { + php_openssl_set_blocking(sslsock, blocked); } if (n == 1) { @@ -2063,8 +2071,8 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si timeout = &sslsock->s.timeout; } - if (timeout && php_set_sock_blocking(sslsock->s.socket, 0) == SUCCESS) { - sslsock->s.is_blocked = 0; + if (timeout) { + php_openssl_set_blocking(sslsock, 0); } if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { @@ -2088,8 +2096,7 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si if (php_openssl_compare_timeval(elapsed_time, *timeout) > 0 ) { /* If the socket was originally blocking, set it back. */ if (began_blocked) { - php_set_sock_blocking(sslsock->s.socket, 1); - sslsock->s.is_blocked = 1; + php_openssl_set_blocking(sslsock, 1); } sslsock->s.timeout_event = 1; return -1; @@ -2184,8 +2191,8 @@ static ssize_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, si } /* And if we were originally supposed to be blocking, let's reset the socket to that. */ - if (began_blocked && php_set_sock_blocking(sslsock->s.socket, 1) == SUCCESS) { - sslsock->s.is_blocked = 1; + if (began_blocked) { + php_openssl_set_blocking(sslsock, 1); } return 0 > nr_bytes ? 0 : nr_bytes; @@ -2491,8 +2498,8 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val timeout = &tv; } - if (timeout && php_set_sock_blocking(sslsock->s.socket, 0) == SUCCESS) { - sslsock->s.is_blocked = 0; + if (timeout) { + php_openssl_set_blocking(sslsock, 0); } if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { @@ -2516,8 +2523,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val if (php_openssl_compare_timeval(elapsed_time, *timeout) > 0 ) { /* If the socket was originally blocking, set it back. */ if (began_blocked) { - php_set_sock_blocking(sslsock->s.socket, 1); - sslsock->s.is_blocked = 1; + php_openssl_set_blocking(sslsock, 1); } sslsock->s.timeout_event = 1; return PHP_STREAM_OPTION_RETURN_ERR; @@ -2568,8 +2574,7 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val if (began_blocked && !sslsock->s.is_blocked) { // Set it back to blocking - php_set_sock_blocking(sslsock->s.socket, 1); - sslsock->s.is_blocked = 1; + php_openssl_set_blocking(sslsock, 1); } } else { #ifdef PHP_WIN32