From c540a26afc437789159eeaf9ee2b8bd1c6ff359b Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 25 Jun 2025 22:33:21 +0100 Subject: [PATCH] ext/posix: posix_kill() process_id range check. pid_t is, for the most part, represented by a signed int, by overflowing it, we end up being in the -1 case which affect all accessible processes. --- ext/posix/posix.c | 16 ++++++++++++++ ext/posix/tests/posix_kill_error.phpt | 2 +- ext/posix/tests/posix_kill_pidoverflow.phpt | 24 +++++++++++++++++++++ ext/posix/tests/posix_setpgid_error.phpt | 22 +++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 ext/posix/tests/posix_kill_pidoverflow.phpt create mode 100644 ext/posix/tests/posix_setpgid_error.phpt diff --git a/ext/posix/posix.c b/ext/posix/posix.c index 512776d3ced20..58d8b11753672 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -45,6 +45,12 @@ # include #endif +#if (defined(__sun) && !defined(_LP64)) || defined(_AIX) +#define POSIX_PID_MAX LONG_MAX +#else +#define POSIX_PID_MAX INT_MAX +#endif + #include "posix_arginfo.h" ZEND_DECLARE_MODULE_GLOBALS(posix) @@ -118,6 +124,12 @@ ZEND_GET_MODULE(posix) } \ RETURN_TRUE; +#define PHP_POSIX_CHECK_PID(pid) \ + if (pid < -1 || pid > POSIX_PID_MAX) { \ + zend_argument_value_error(1, "must be between -1 and " ZEND_LONG_FMT, POSIX_PID_MAX); \ + RETURN_THROWS(); \ + } + /* {{{ Send a signal to a process (POSIX.1, 3.3.2) */ PHP_FUNCTION(posix_kill) @@ -129,6 +141,8 @@ PHP_FUNCTION(posix_kill) Z_PARAM_LONG(sig) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(pid) + if (kill(pid, sig) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; @@ -291,6 +305,8 @@ PHP_FUNCTION(posix_setpgid) Z_PARAM_LONG(pgid) ZEND_PARSE_PARAMETERS_END(); + PHP_POSIX_CHECK_PID(pid) + if (setpgid(pid, pgid) < 0) { POSIX_G(last_error) = errno; RETURN_FALSE; diff --git a/ext/posix/tests/posix_kill_error.phpt b/ext/posix/tests/posix_kill_error.phpt index c4ad7b5e8dc73..a64c0d07d7aa1 100644 --- a/ext/posix/tests/posix_kill_error.phpt +++ b/ext/posix/tests/posix_kill_error.phpt @@ -13,7 +13,7 @@ $sig = 999; var_dump( posix_kill($pid, 999) ); echo "\n-- Testing posix_kill() function with negative pid --\n"; -$pid = -999; +$pid = -1; $sig = 9; var_dump( posix_kill($pid, 999) ); diff --git a/ext/posix/tests/posix_kill_pidoverflow.phpt b/ext/posix/tests/posix_kill_pidoverflow.phpt new file mode 100644 index 0000000000000..45baf5fe6e0af --- /dev/null +++ b/ext/posix/tests/posix_kill_pidoverflow.phpt @@ -0,0 +1,24 @@ +--TEST-- +posix_kill() with large pid +--EXTENSIONS-- +posix +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} + +try { + posix_kill(PHP_INT_MIN, SIGTERM); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +posix_kill(): Argument #1 ($process_id) must be between -1 and %d +posix_kill(): Argument #1 ($process_id) must be between -1 and %d diff --git a/ext/posix/tests/posix_setpgid_error.phpt b/ext/posix/tests/posix_setpgid_error.phpt new file mode 100644 index 0000000000000..34e8f238a6562 --- /dev/null +++ b/ext/posix/tests/posix_setpgid_error.phpt @@ -0,0 +1,22 @@ +--TEST-- +posix_setpgid() with wrong pid values +--EXTENSIONS-- +posix +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +try { + posix_setpgid(-2, 1); +} catch (\ValueError $e) { + echo $e->getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +posix_setpgid(): Argument #1 ($process_id) must be between -1 and %d +posix_setpgid(): Argument #1 ($process_id) must be between -1 and %d