diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 432270cff190..27e0c499af19 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -191,11 +191,18 @@ PHP_FUNCTION(ftp_ssl_connect) RETURN_THROWS(); } + const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0); + if (timeout_sec <= 0) { zend_argument_value_error(3, "must be greater than 0"); RETURN_THROWS(); } + if (timeout_sec >= timeoutmax) { + zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT, timeoutmax); + RETURN_THROWS(); + } + /* connect */ if (!(ftp = ftp_open(host, (short)port, timeout_sec))) { RETURN_FALSE; @@ -1259,6 +1266,7 @@ PHP_FUNCTION(ftp_set_option) zval *z_ftp, *z_value; zend_long option; ftpbuf_t *ftp; + const uint64_t timeoutmax = (uint64_t)((double) PHP_TIMEOUT_ULL_MAX / 1000000.0); if (zend_parse_parameters(ZEND_NUM_ARGS(), "Olz", &z_ftp, php_ftp_ce, &option, &z_value) == FAILURE) { RETURN_THROWS(); @@ -1275,6 +1283,10 @@ PHP_FUNCTION(ftp_set_option) zend_argument_value_error(3, "must be greater than 0 for the FTP_TIMEOUT_SEC option"); RETURN_THROWS(); } + if ((uint64_t) Z_LVAL_P(z_value) >= timeoutmax) { + zend_argument_value_error(3, "must be less than " ZEND_ULONG_FMT " for the FTP_TIMEOUT_SEC option", timeoutmax); + RETURN_THROWS(); + } ftp->timeout_sec = Z_LVAL_P(z_value); RETURN_TRUE; break; diff --git a/ext/ftp/tests/gh20601_set_option.phpt b/ext/ftp/tests/gh20601_set_option.phpt new file mode 100644 index 000000000000..233e547c5d9b --- /dev/null +++ b/ext/ftp/tests/gh20601_set_option.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-20601 (ftp_set_option FTP_TIMEOUT_SEC timeout overflow) +--EXTENSIONS-- +ftp +pcntl +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +ftp_set_option(): Argument #3 ($value) must be less than %d for the FTP_TIMEOUT_SEC option diff --git a/ext/ftp/tests/gh20601_ssl.phpt b/ext/ftp/tests/gh20601_ssl.phpt new file mode 100644 index 000000000000..005f866e18e0 --- /dev/null +++ b/ext/ftp/tests/gh20601_ssl.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-20601 (ftp_ssl_connect timeout overflow) +--EXTENSIONS-- +ftp +openssl +--SKIPIF-- + +--FILE-- +getMessage(); +} +?> +--EXPECTF-- +ftp_ssl_connect(): Argument #3 ($timeout) must be less than %d