Skip to content

Commit 4312a44

Browse files
committed
Fix GH-20601: ftp_connect() timeout argument overflow.
close GH-20603
1 parent c8e13af commit 4312a44

File tree

4 files changed

+31
-0
lines changed

4 files changed

+31
-0
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ PHP NEWS
2424
. Fixed bug GH-20483 (ASAN stack overflow with fiber.stack_size INI
2525
small value). (David Carlier)
2626

27+
- FTP:
28+
. Fixed bug GH-20601 (ftp_connect overflow on timeout). (David Carlier)
29+
2730
- GD:
2831
. Fixed bug GH-20511 (imagegammacorrect out of range input/output values).
2932
(David Carlier)

ext/ftp/php_ftp.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,11 +158,18 @@ PHP_FUNCTION(ftp_connect)
158158
RETURN_THROWS();
159159
}
160160

161+
const zend_long timeoutmax = (zend_long)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0);
162+
161163
if (timeout_sec <= 0) {
162164
zend_argument_value_error(3, "must be greater than 0");
163165
RETURN_THROWS();
164166
}
165167

168+
if (timeout_sec >= timeoutmax) {
169+
zend_argument_value_error(3, "must be less than " ZEND_LONG_FMT, timeoutmax);
170+
RETURN_THROWS();
171+
}
172+
166173
/* connect */
167174
if (!(ftp = ftp_open(host, (short)port, timeout_sec))) {
168175
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
@@ -319,6 +319,8 @@ static inline void php_network_set_limit_time(struct timeval *limit_time,
319319
struct timeval *timeout)
320320
{
321321
gettimeofday(limit_time, NULL);
322+
const double timeoutmax = (double) PHP_TIMEOUT_ULL_MAX / 1000000.0;
323+
ZEND_ASSERT(limit_time->tv_sec < (timeoutmax - timeout->tv_sec));
322324
limit_time->tv_sec += timeout->tv_sec;
323325
limit_time->tv_usec += timeout->tv_usec;
324326
if (limit_time->tv_usec >= 1000000) {

0 commit comments

Comments
 (0)