mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix GH-13860: Incorrect PHP_STREAM_OPTION_CHECK_LIVENESS case in ext/openssl/xp_ssl.c - causing use of dead socket
php_socket_errno() may return a stale value when recv returns a value >= 0. As such, the liveness check is wrong. This is the same bug as #70198 (fixed in GH-1456). So we fix it in the same way. Closes GH-13895.
This commit is contained in:
2
NEWS
2
NEWS
@@ -32,6 +32,8 @@ PHP NEWS
|
||||
- Streams:
|
||||
. Fixed bug GH-13264 (Part 1 - Memory leak on stream filter failure).
|
||||
(Jakub Zelenka)
|
||||
. Fixed bug GH-13860 (Incorrect PHP_STREAM_OPTION_CHECK_LIVENESS case in
|
||||
ext/openssl/xp_ssl.c - causing use of dead socket). (nielsdos)
|
||||
|
||||
- Treewide:
|
||||
. Fix gcc-14 Wcalloc-transposed-args warnings. (Cristian Rodríguez)
|
||||
|
||||
49
ext/openssl/tests/gh13860.phpt
Normal file
49
ext/openssl/tests/gh13860.phpt
Normal file
@@ -0,0 +1,49 @@
|
||||
--TEST--
|
||||
GH-13860 (Incorrect PHP_STREAM_OPTION_CHECK_LIVENESS case in ext/openssl/xp_ssl.c - causing use of dead socket)
|
||||
--EXTENSIONS--
|
||||
openssl
|
||||
--SKIPIF--
|
||||
<?php
|
||||
if (!function_exists("proc_open")) die("skip no proc_open");
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
$serverCode = <<<'CODE'
|
||||
$serverUri = "tcp://127.0.0.1:64325";
|
||||
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
|
||||
$serverCtx = stream_context_create();
|
||||
|
||||
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
|
||||
phpt_notify();
|
||||
|
||||
$client = @stream_socket_accept($server);
|
||||
if ($client) {
|
||||
fwrite($client, "xx");
|
||||
phpt_wait();
|
||||
fclose($client);
|
||||
}
|
||||
CODE;
|
||||
|
||||
$clientCode = <<<'CODE'
|
||||
$serverUri = "tcp://127.0.0.1:64325";
|
||||
$clientFlags = STREAM_CLIENT_CONNECT;
|
||||
|
||||
phpt_wait();
|
||||
$fp = stream_socket_client($serverUri);
|
||||
stream_set_blocking($fp, false);
|
||||
|
||||
fread($fp, 2);
|
||||
|
||||
phpt_notify();
|
||||
while (!($in = fread($fp, 2))) {
|
||||
usleep(1000);
|
||||
}
|
||||
var_dump(feof($fp));
|
||||
fclose($fp);
|
||||
CODE;
|
||||
|
||||
include 'ServerClientTestCase.inc';
|
||||
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
|
||||
?>
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
@@ -2575,8 +2575,20 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
|
||||
php_set_sock_blocking(sslsock->s.socket, 1);
|
||||
sslsock->s.is_blocked = 1;
|
||||
}
|
||||
} else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK|MSG_DONTWAIT) && php_socket_errno() != EAGAIN) {
|
||||
alive = 0;
|
||||
} else {
|
||||
#ifdef PHP_WIN32
|
||||
int ret;
|
||||
#else
|
||||
ssize_t ret;
|
||||
#endif
|
||||
int err;
|
||||
|
||||
ret = recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK|MSG_DONTWAIT);
|
||||
err = php_socket_errno();
|
||||
if (0 == ret || /* the counterpart did properly shutdown */
|
||||
(0 > ret && err != EWOULDBLOCK && err != EAGAIN && err != EMSGSIZE)) { /* there was an unrecoverable error */
|
||||
alive = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;
|
||||
|
||||
Reference in New Issue
Block a user