Merge branch 'PHP-8.3' into PHP-8.4

* PHP-8.3:
  Split off php_set_sock_blocking() and s.is_blocked to a separate function
  Fix missing checks against php_set_blocking() in xp_ssl.c
This commit is contained in:
Niels Dossche 2025-05-20 08:08:39 +02:00
commit 1e94f3423b
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
2 changed files with 24 additions and 16 deletions

3
NEWS
View file

@ -45,6 +45,9 @@ PHP NEWS
properties in traits). (nielsdos) properties in traits). (nielsdos)
. Fix leak of accel_globals->key. (nielsdos) . Fix leak of accel_globals->key. (nielsdos)
- OpenSSL:
. Fix missing checks against php_set_blocking() in xp_ssl.c. (nielsdos)
- SPL: - SPL:
. Fixed bug GH-18421 (Integer overflow with large numbers in LimitIterator). . Fixed bug GH-18421 (Integer overflow with large numbers in LimitIterator).
(nielsdos) (nielsdos)

View file

@ -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, static int php_openssl_enable_crypto(php_stream *stream,
php_openssl_netstream_data_t *sslsock, php_openssl_netstream_data_t *sslsock,
php_stream_xport_crypto_param *cparam) /* {{{ */ php_stream_xport_crypto_param *cparam) /* {{{ */
@ -1925,8 +1934,7 @@ static int php_openssl_enable_crypto(php_stream *stream,
sslsock->state_set = 1; sslsock->state_set = 1;
} }
if (SUCCESS == php_set_sock_blocking(sslsock->s.socket, 0)) { if (SUCCESS == php_openssl_set_blocking(sslsock, 0)) {
sslsock->s.is_blocked = 0;
/* The following mode are added only if we are able to change socket /* 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 */ * 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); 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); } while (retry);
if (sslsock->s.is_blocked != blocked && SUCCESS == php_set_sock_blocking(sslsock->s.socket, blocked)) { if (sslsock->s.is_blocked != blocked) {
sslsock->s.is_blocked = blocked; php_openssl_set_blocking(sslsock, blocked);
} }
if (n == 1) { 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; timeout = &sslsock->s.timeout;
} }
if (timeout && php_set_sock_blocking(sslsock->s.socket, 0) == SUCCESS) { if (timeout) {
sslsock->s.is_blocked = 0; php_openssl_set_blocking(sslsock, 0);
} }
if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { 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 (php_openssl_compare_timeval(elapsed_time, *timeout) > 0 ) {
/* If the socket was originally blocking, set it back. */ /* If the socket was originally blocking, set it back. */
if (began_blocked) { if (began_blocked) {
php_set_sock_blocking(sslsock->s.socket, 1); php_openssl_set_blocking(sslsock, 1);
sslsock->s.is_blocked = 1;
} }
sslsock->s.timeout_event = 1; sslsock->s.timeout_event = 1;
return -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. */ /* 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) { if (began_blocked) {
sslsock->s.is_blocked = 1; php_openssl_set_blocking(sslsock, 1);
} }
return 0 > nr_bytes ? 0 : nr_bytes; 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; timeout = &tv;
} }
if (timeout && php_set_sock_blocking(sslsock->s.socket, 0) == SUCCESS) { if (timeout) {
sslsock->s.is_blocked = 0; php_openssl_set_blocking(sslsock, 0);
} }
if (!sslsock->s.is_blocked && timeout && (timeout->tv_sec > 0 || (timeout->tv_sec == 0 && timeout->tv_usec))) { 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 (php_openssl_compare_timeval(elapsed_time, *timeout) > 0 ) {
/* If the socket was originally blocking, set it back. */ /* If the socket was originally blocking, set it back. */
if (began_blocked) { if (began_blocked) {
php_set_sock_blocking(sslsock->s.socket, 1); php_openssl_set_blocking(sslsock, 1);
sslsock->s.is_blocked = 1;
} }
sslsock->s.timeout_event = 1; sslsock->s.timeout_event = 1;
return PHP_STREAM_OPTION_RETURN_ERR; 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) { if (began_blocked && !sslsock->s.is_blocked) {
// Set it back to blocking // Set it back to blocking
php_set_sock_blocking(sslsock->s.socket, 1); php_openssl_set_blocking(sslsock, 1);
sslsock->s.is_blocked = 1;
} }
} else { } else {
#ifdef PHP_WIN32 #ifdef PHP_WIN32