Skip to content

Commit 1e4bb03

Browse files
committed
Merge branch 'PHP-8.3'
* PHP-8.3: Fix GH-13860: Incorrect PHP_STREAM_OPTION_CHECK_LIVENESS case in ext/openssl/xp_ssl.c - causing use of dead socket
2 parents d8f2900 + 9213664 commit 1e4bb03

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

ext/openssl/tests/gh13860.phpt

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
--TEST--
2+
GH-13860 (Incorrect PHP_STREAM_OPTION_CHECK_LIVENESS case in ext/openssl/xp_ssl.c - causing use of dead socket)
3+
--EXTENSIONS--
4+
openssl
5+
--SKIPIF--
6+
<?php
7+
if (!function_exists("proc_open")) die("skip no proc_open");
8+
?>
9+
--FILE--
10+
<?php
11+
$serverCode = <<<'CODE'
12+
$serverUri = "tcp://127.0.0.1:64325";
13+
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
14+
$serverCtx = stream_context_create();
15+
16+
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
17+
phpt_notify();
18+
19+
$client = @stream_socket_accept($server);
20+
if ($client) {
21+
fwrite($client, "xx");
22+
phpt_wait();
23+
fclose($client);
24+
}
25+
CODE;
26+
27+
$clientCode = <<<'CODE'
28+
$serverUri = "tcp://127.0.0.1:64325";
29+
$clientFlags = STREAM_CLIENT_CONNECT;
30+
31+
phpt_wait();
32+
$fp = stream_socket_client($serverUri);
33+
stream_set_blocking($fp, false);
34+
35+
fread($fp, 2);
36+
37+
phpt_notify();
38+
while (!($in = fread($fp, 2))) {
39+
usleep(1000);
40+
}
41+
var_dump(feof($fp));
42+
fclose($fp);
43+
CODE;
44+
45+
include 'ServerClientTestCase.inc';
46+
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
47+
?>
48+
--EXPECT--
49+
bool(true)

ext/openssl/xp_ssl.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -2571,8 +2571,20 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
25712571
php_set_sock_blocking(sslsock->s.socket, 1);
25722572
sslsock->s.is_blocked = 1;
25732573
}
2574-
} else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK|MSG_DONTWAIT) && php_socket_errno() != EAGAIN) {
2575-
alive = 0;
2574+
} else {
2575+
#ifdef PHP_WIN32
2576+
int ret;
2577+
#else
2578+
ssize_t ret;
2579+
#endif
2580+
int err;
2581+
2582+
ret = recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK|MSG_DONTWAIT);
2583+
err = php_socket_errno();
2584+
if (0 == ret || /* the counterpart did properly shutdown */
2585+
(0 > ret && err != EWOULDBLOCK && err != EAGAIN && err != EMSGSIZE)) { /* there was an unrecoverable error */
2586+
alive = 0;
2587+
}
25762588
}
25772589
}
25782590
return alive ? PHP_STREAM_OPTION_RETURN_OK : PHP_STREAM_OPTION_RETURN_ERR;

0 commit comments

Comments
 (0)