mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
ext/pcntl: Reject negative values in pcntl_alarm()
internal refactorings: - pcntl_signal_get_handler() max signals handling simplification, reusing the num_signals global. - pcntl_alarm() accepts a zend_long (signed) but passes it to alarm(), which takes an unsigned int. Negative values silently wrap to large unsigned values, scheduling an alarm far in the future instead of raising an error. Also reject large values above unsigned long max value. close GH-21282
This commit is contained in:
@@ -105,6 +105,10 @@ PHP 8.6 UPGRADE NOTES
|
||||
. Output of openssl_x509_parse() contains criticalExtensions listing all
|
||||
critical certificate extensions.
|
||||
|
||||
- PCNTL:
|
||||
. pcntl_alarm() now throws a ValueError if the seconds argument is
|
||||
lower than zero or greater than platform's UINT_MAX.
|
||||
|
||||
- Phar:
|
||||
. Phar::mungServer() now supports reference values.
|
||||
|
||||
|
||||
@@ -212,7 +212,7 @@ PHP_RINIT_FUNCTION(pcntl)
|
||||
PCNTL_G(last_error) = 0;
|
||||
PCNTL_G(num_signals) = NSIG;
|
||||
#ifdef SIGRTMAX
|
||||
/* At least FreeBSD reports an incorrecrt NSIG that does not include realtime signals.
|
||||
/* At least FreeBSD reports an incorrect NSIG that does not include realtime signals.
|
||||
* As SIGRTMAX may be a dynamic value, adjust the value in INIT. */
|
||||
if (NSIG < SIGRTMAX + 1) {
|
||||
PCNTL_G(num_signals) = SIGRTMAX + 1;
|
||||
@@ -314,6 +314,11 @@ PHP_FUNCTION(pcntl_alarm)
|
||||
Z_PARAM_LONG(seconds);
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
if (seconds < 0 || seconds > UINT_MAX) {
|
||||
zend_argument_value_error(1, "must be between 0 and %u", UINT_MAX);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
RETURN_LONG((zend_long) alarm(seconds));
|
||||
}
|
||||
/* }}} */
|
||||
@@ -870,17 +875,8 @@ PHP_FUNCTION(pcntl_signal_get_handler)
|
||||
Z_PARAM_LONG(signo)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
|
||||
// note: max signal on mac is SIGUSR2 (31), no real time signals.
|
||||
int sigmax = NSIG - 1;
|
||||
#if defined(SIGRTMAX)
|
||||
// oddily enough, NSIG on freebsd reports only 32 whereas SIGRTMIN starts at 65.
|
||||
if (sigmax < SIGRTMAX) {
|
||||
sigmax = SIGRTMAX;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (signo < 1 || signo > sigmax) {
|
||||
zend_argument_value_error(1, "must be between 1 and %d", sigmax);
|
||||
if (signo < 1 || signo >= PCNTL_G(num_signals)) {
|
||||
zend_argument_value_error(1, "must be between 1 and %d", PCNTL_G(num_signals) - 1);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
@@ -1153,7 +1149,7 @@ static void pcntl_siginfo_to_zval(int signo, siginfo_t *siginfo, zval *user_sigi
|
||||
case SIGFPE:
|
||||
case SIGSEGV:
|
||||
case SIGBUS:
|
||||
add_assoc_double_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo->si_addr);
|
||||
add_assoc_long_ex(user_siginfo, "addr", sizeof("addr")-1, (zend_long)siginfo->si_addr);
|
||||
break;
|
||||
#if defined(SIGPOLL) && !defined(__CYGWIN__)
|
||||
case SIGPOLL:
|
||||
|
||||
35
ext/pcntl/tests/pcntl_alarm_invalid_value.phpt
Normal file
35
ext/pcntl/tests/pcntl_alarm_invalid_value.phpt
Normal file
@@ -0,0 +1,35 @@
|
||||
--TEST--
|
||||
pcntl_alarm() rejects invalid values
|
||||
--EXTENSIONS--
|
||||
pcntl
|
||||
--SKIPIF--
|
||||
<?php if (PHP_INT_SIZE < 8) die("skip 64-bit only"); ?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
try {
|
||||
pcntl_alarm(-1);
|
||||
} catch (\ValueError $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
pcntl_alarm(PHP_INT_MIN);
|
||||
} catch (\ValueError $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
|
||||
try {
|
||||
pcntl_alarm(PHP_INT_MAX);
|
||||
} catch (\ValueError $e) {
|
||||
echo $e->getMessage() . \PHP_EOL;
|
||||
}
|
||||
|
||||
var_dump(pcntl_alarm(0));
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
pcntl_alarm(): Argument #1 ($seconds) must be between 0 and %d
|
||||
pcntl_alarm(): Argument #1 ($seconds) must be between 0 and %d
|
||||
pcntl_alarm(): Argument #1 ($seconds) must be between 0 and %d
|
||||
int(0)
|
||||
Reference in New Issue
Block a user