Skip to content

Commit 227541c

Browse files
committed
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4: Fix GH-20601: ftp_connect() timeout argument overflow.
2 parents 848269d + 1701589 commit 227541c

File tree

3 files changed

+28
-0
lines changed

3 files changed

+28
-0
lines changed

ext/ftp/php_ftp.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,18 @@ PHP_FUNCTION(ftp_connect)
147147
RETURN_THROWS();
148148
}
149149

150+
const zend_long timeoutmax = (zend_long)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0);
151+
150152
if (timeout_sec <= 0) {
151153
zend_argument_value_error(3, "must be greater than 0");
152154
RETURN_THROWS();
153155
}
154156

157+
if (timeout_sec >= timeoutmax) {
158+
zend_argument_value_error(3, "must be less than " ZEND_LONG_FMT, timeoutmax);
159+
RETURN_THROWS();
160+
}
161+
155162
/* connect */
156163
if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
157164
RETURN_FALSE;

ext/ftp/tests/gh20601.phpt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
GH-20601 (ftp_connect timeout overflow)
3+
--EXTENSIONS--
4+
ftp
5+
--SKIPIF--
6+
<?php
7+
if (PHP_INT_SIZE != 8) die("skip: 64-bit only");
8+
if (PHP_OS_FAMILY === 'Windows') die("skip not for windows");
9+
?>
10+
--FILE--
11+
<?php
12+
try {
13+
ftp_connect('127.0.0.1', 1024, PHP_INT_MAX);
14+
} catch (\ValueError $e) {
15+
echo $e->getMessage();
16+
}
17+
?>
18+
--EXPECTF--
19+
ftp_connect(): Argument #3 ($timeout) must be less than %d

main/network.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,8 @@ static inline void php_network_set_limit_time(struct timeval *limit_time,
317317
struct timeval *timeout)
318318
{
319319
gettimeofday(limit_time, NULL);
320+
const double timeoutmax = (double) PHP_TIMEOUT_ULL_MAX / 1000000.0;
321+
ZEND_ASSERT(limit_time->tv_sec < (timeoutmax - timeout->tv_sec));
320322
limit_time->tv_sec += timeout->tv_sec;
321323
limit_time->tv_usec += timeout->tv_usec;
322324
if (limit_time->tv_usec >= 1000000) {

0 commit comments

Comments
 (0)