Skip to content

Commit 6f51b1e

Browse files
committed
Fix GH-14780: p(f)sockopen overflow on timeout argument.
1 parent cd67080 commit 6f51b1e

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

ext/standard/fsock.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
3030
char *host;
3131
size_t host_len;
3232
zend_long port = -1;
33+
zend_ulong ltimeout;
3334
zval *zerrno = NULL, *zerrstr = NULL;
3435
double timeout;
3536
bool timeout_is_null = 1;
@@ -73,13 +74,23 @@ static void php_fsockopen_stream(INTERNAL_FUNCTION_PARAMETERS, int persistent)
7374
}
7475

7576
/* prepare the timeout value for use */
77+
ltimeout = (zend_ulong)(timeout * 1000000.0);
78+
if (ltimeout > LONG_MAX) {
79+
if (port > 0) {
80+
efree(hostname);
81+
}
82+
if (hashkey) {
83+
efree(hashkey);
84+
}
85+
zend_argument_value_error(6, "must be between 0 and " ZEND_LONG_FMT, (LONG_MAX / 1000000));
86+
RETURN_THROWS();
87+
}
7688
#ifndef PHP_WIN32
77-
conv = (time_t) (timeout * 1000000.0);
78-
tv.tv_sec = conv / 1000000;
89+
conv = (time_t) (ltimeout);
7990
#else
80-
conv = (long) (timeout * 1000000.0);
81-
tv.tv_sec = conv / 1000000;
91+
conv = (long) (ltimeout);
8292
#endif
93+
tv.tv_sec = conv / 1000000;
8394
tv.tv_usec = conv % 1000000;
8495

8596
stream = php_stream_xport_create(hostname, hostname_len, REPORT_ERRORS,
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
GH-14780: p(f)sockopen overflow on timeout.
3+
--FILE--
4+
<?php
5+
$code = null;
6+
$err = null;
7+
try {
8+
pfsockopen('udp://127.0.0.1', '63844', $code, $err, (PHP_INT_MAX/1000000)+1);
9+
} catch (\ValueError $e) {
10+
echo $e->getMessage();
11+
}
12+
--EXPECTF--
13+
pfsockopen(): Argument #6 must be between 0 and %s

0 commit comments

Comments
 (0)