From 270ffa7d1ea5475f1dcaf5e65079f050fc2f7ecf Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Wed, 24 Jun 2026 18:40:58 +0800 Subject: [PATCH] Fix GH-9945: Reject shmop/sysvshm keys outside key_t range --- NEWS | 8 ++++++++ ext/shmop/shmop.c | 11 +++++++++-- ext/shmop/tests/gh9945.phpt | 19 +++++++++++++++++++ ext/sysvshm/sysvshm.c | 17 ++++++++++++----- ext/sysvshm/tests/gh9945.phpt | 19 +++++++++++++++++++ 5 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 ext/shmop/tests/gh9945.phpt create mode 100644 ext/sysvshm/tests/gh9945.phpt diff --git a/NEWS b/NEWS index 3e24c2fa0bc6..4ac23c032ae7 100644 --- a/NEWS +++ b/NEWS @@ -206,6 +206,10 @@ PHP NEWS . Changed defaults of session.use_strict_mode (now 1), session.cookie_httponly (now 1) and session.cookie_samesite (now "Lax"). (jorgsowa) +- Shmop: + . Fixed bug GH-9945 (shmop_open() silently truncates keys outside the key_t + range). (Weilin Du) + - Soap: . Soap::__setCookie() when cookie name is a digit is now not stored and represented as a string anymore but a int. (David Carlier) @@ -236,6 +240,10 @@ PHP NEWS . Fix bug GH-22062 (SplDoublyLinkedList iterator UAF via destructor releasing next node). (David Carlier) +- Sysvshm: + . Fixed shm_attach() to throw ValueError for keys outside the key_t range. + (Weilin Du) + - Sqlite3: . Fix NUL byte truncation in sqlite3 TEXT column handling. (ndossche) diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c index c3ed217443f4..645ce172fdcd 100644 --- a/ext/shmop/shmop.c +++ b/ext/shmop/shmop.c @@ -129,13 +129,20 @@ PHP_MINFO_FUNCTION(shmop) /* {{{ gets and attaches a shared memory segment */ PHP_FUNCTION(shmop_open) { - zend_long key, mode, size; + zend_long key_arg, mode, size; + key_t key; php_shmop *shmop; struct shmid_ds shm; char *flags; size_t flags_len; - if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsll", &key, &flags, &flags_len, &mode, &size) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "lsll", &key_arg, &flags, &flags_len, &mode, &size) == FAILURE) { + RETURN_THROWS(); + } + + key = (key_t) key_arg; + if ((zend_long) key != key_arg) { + zend_argument_value_error(1, "is out of range"); RETURN_THROWS(); } diff --git a/ext/shmop/tests/gh9945.phpt b/ext/shmop/tests/gh9945.phpt new file mode 100644 index 000000000000..f22f79149bfb --- /dev/null +++ b/ext/shmop/tests/gh9945.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-9945: shmop_open() must reject keys outside the key_t range +--EXTENSIONS-- +shmop +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +shmop_open(): Argument #1 ($key) is out of range diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 59ca49a974e6..6ca06be935d9 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -126,10 +126,17 @@ PHP_FUNCTION(shm_attach) sysvshm_shm *shm_list_ptr; char *shm_ptr; sysvshm_chunk_head *chunk_ptr; - zend_long shm_key, shm_id, shm_size, shm_flag = 0666; + zend_long shm_key_arg, shm_id, shm_size, shm_flag = 0666; + key_t shm_key; bool shm_size_is_null = true; - if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|l!l", &shm_key, &shm_size, &shm_size_is_null, &shm_flag)) { + if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|l!l", &shm_key_arg, &shm_size, &shm_size_is_null, &shm_flag)) { + RETURN_THROWS(); + } + + shm_key = (key_t) shm_key_arg; + if ((zend_long) shm_key != shm_key_arg) { + zend_argument_value_error(1, "is out of range"); RETURN_THROWS(); } @@ -145,17 +152,17 @@ PHP_FUNCTION(shm_attach) /* get the id from a specified key or create new shared memory */ if ((shm_id = shmget(shm_key, 0, 0)) < 0) { if (shm_size < (zend_long)sizeof(sysvshm_chunk_head)) { - php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key); + php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": memorysize too small", shm_key_arg); RETURN_FALSE; } if ((shm_id = shmget(shm_key, shm_size, shm_flag | IPC_CREAT | IPC_EXCL)) < 0) { - php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); + php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key_arg, strerror(errno)); RETURN_FALSE; } } if ((shm_ptr = shmat(shm_id, NULL, 0)) == (void *) -1) { - php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno)); + php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key_arg, strerror(errno)); RETURN_FALSE; } diff --git a/ext/sysvshm/tests/gh9945.phpt b/ext/sysvshm/tests/gh9945.phpt new file mode 100644 index 000000000000..8185d39b0981 --- /dev/null +++ b/ext/sysvshm/tests/gh9945.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-9945: shm_attach() must reject keys outside the key_t range +--EXTENSIONS-- +sysvshm +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} +?> +--EXPECT-- +shm_attach(): Argument #1 ($key) is out of range