Skip to content

Commit dc2ffde

Browse files
committed
Fix bug #77390 (feof might hang on TLS streams in case of fragmented TLS records)
Simplified version of the fix from Abyl Valg so credit to him.
1 parent d9b2902 commit dc2ffde

File tree

3 files changed

+25
-24
lines changed

3 files changed

+25
-24
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ PHP NEWS
3434
. Fixed bug #77361 (configure fails on 64-bit AIX when opcache enabled).
3535
(Kevin Adler)
3636

37+
- OpenSSL:
38+
. Fixed bug #77390 (feof might hang on TLS streams in case of fragmented TLS
39+
records). (Abyl Valg, Jakub Zelenka)
40+
3741
- PDO:
3842
. Fixed bug #77273 (array_walk_recursive corrupts value types leading to PDO
3943
failure). (Nikita)

ext/openssl/tests/bug77390.phpt

+8-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,16 @@ $clientCode = <<<'CODE'
2323
2424
$read = [$fp];
2525
$buf = '';
26+
$printed = false;
2627
while (stream_select($read, $write, $except, 1000)) {
2728
$chunk = stream_get_contents($fp, 4096);
28-
var_dump($chunk);
29-
$buf .= $chunk;
29+
if ($chunk !== "") {
30+
var_dump($chunk);
31+
$buf .= $chunk;
32+
} elseif (!$printed) {
33+
$printed = true;
34+
var_dump($chunk);
35+
}
3036
if ($buf === 'hello, world') {
3137
break;
3238
}
@@ -110,5 +116,4 @@ ServerClientTestCase::getInstance()->run($clientCode, [
110116
?>
111117
--EXPECT--
112118
string(0) ""
113-
string(0) ""
114119
string(12) "hello, world"

ext/openssl/xp_ssl.c

+13-21
Original file line numberDiff line numberDiff line change
@@ -2405,30 +2405,22 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
24052405
alive = 0;
24062406
} else if (php_pollfd_for(sslsock->s.socket, PHP_POLLREADABLE|POLLPRI, &tv) > 0) {
24072407
if (sslsock->ssl_active) {
2408-
int n;
2409-
2410-
do {
2411-
n = SSL_peek(sslsock->ssl_handle, &buf, sizeof(buf));
2412-
if (n <= 0) {
2413-
int err = SSL_get_error(sslsock->ssl_handle, n);
2414-
2415-
if (err == SSL_ERROR_SYSCALL) {
2408+
int n = SSL_peek(sslsock->ssl_handle, &buf, sizeof(buf));
2409+
if (n <= 0) {
2410+
int err = SSL_get_error(sslsock->ssl_handle, n);
2411+
switch (err) {
2412+
case SSL_ERROR_SYSCALL:
24162413
alive = php_socket_errno() == EAGAIN;
24172414
break;
2418-
}
2419-
2420-
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
2421-
/* re-negotiate */
2422-
continue;
2423-
}
2424-
2425-
/* any other problem is a fatal error */
2426-
alive = 0;
2415+
case SSL_ERROR_WANT_READ:
2416+
case SSL_ERROR_WANT_WRITE:
2417+
alive = 1;
2418+
break;
2419+
default:
2420+
/* any other problem is a fatal error */
2421+
alive = 0;
24272422
}
2428-
/* either peek succeeded or there was an error; we
2429-
* have set the alive flag appropriately */
2430-
break;
2431-
} while (1);
2423+
}
24322424
} else if (0 == recv(sslsock->s.socket, &buf, sizeof(buf), MSG_PEEK) && php_socket_errno() != EAGAIN) {
24332425
alive = 0;
24342426
}

0 commit comments

Comments
 (0)