[php-src] PHP-8.5: Merge branch 'PHP-8.4' into PHP-8.5
David Carlier <[email protected]> Sun, 2 Aug 2026 20:56:22 +0000
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: David Carlier (devnexen)
Date: 2026-08-02T21:54:51+01:00
Commit: https://github.com/php/php-src/commit/947f4d2b662f1279ec502b8d9e4ee4b700858285
Raw diff: https://github.com/php/php-src/commit/947f4d2b662f1279ec502b8d9e4ee4b700858285.diff
Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
ext/sysvshm: do not trust $size when opening an existing segment
Changed paths:
A ext/sysvshm/tests/shm_attach_existing_segment_size.phpt
A ext/sysvshm/tests/shm_attach_existing_segment_too_small.phpt
M ext/sysvshm/sysvshm.c
Diff:
diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c
index 179fe0ed139c..f7b5b0dcdae2 100644
--- a/ext/sysvshm/sysvshm.c
+++ b/ext/sysvshm/sysvshm.c
@@ -130,6 +130,7 @@ PHP_FUNCTION(shm_attach)
sysvshm_shm *shm_list_ptr;
char *shm_ptr;
sysvshm_chunk_head *chunk_ptr;
+ struct shmid_ds shm_desc;
zend_long shm_key, shm_id, shm_size, shm_flag = 0666;
bool shm_size_is_null = 1;
bool created = false;
@@ -168,6 +169,25 @@ PHP_FUNCTION(shm_attach)
RETURN_FALSE;
}
+ if (shmctl(shm_id, IPC_STAT, &shm_desc) < 0) {
+ php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": %s", shm_key, strerror(errno));
+ shmdt(shm_ptr);
+ if (created) {
+ shmctl(shm_id, IPC_RMID, NULL);
+ }
+ RETURN_FALSE;
+ }
+ shm_size = (zend_long)shm_desc.shm_segsz;
+
+ if (shm_size < (zend_long) sizeof(sysvshm_chunk_head)) {
+ php_error_docref(NULL, E_WARNING, "Failed for key 0x" ZEND_XLONG_FMT ": segment too small", shm_key);
+ shmdt(shm_ptr);
+ if (created) {
+ shmctl(shm_id, IPC_RMID, NULL);
+ }
+ RETURN_FALSE;
+ }
+
/* check if shm is already initialized */
chunk_ptr = (sysvshm_chunk_head *) shm_ptr;
if (strcmp((char*) &(chunk_ptr->magic), "PHP_SM") != 0) {
diff --git a/ext/sysvshm/tests/shm_attach_existing_segment_size.phpt b/ext/sysvshm/tests/shm_attach_existing_segment_size.phpt
new file mode 100644
index 000000000000..8f7f233e0d5f
--- /dev/null
+++ b/ext/sysvshm/tests/shm_attach_existing_segment_size.phpt
@@ -0,0 +1,36 @@
+--TEST--
+shm_attach() takes the size of an existing segment from the kernel, not from $size
+--EXTENSIONS--
+sysvshm
+shmop
+--FILE--
+<?php
+$key = 0x53484D31;
+
+$raw = shmop_open($key, 'n', 0600, 4096);
+
+$shm = shm_attach($key, 10 * 1024 * 1024);
+var_dump($shm instanceof SysvSharedMemory);
+
+var_dump(shm_put_var($shm, 1, str_repeat('A', 1024 * 1024)));
+
+var_dump(shm_put_var($shm, 2, 'ok'));
+var_dump(shm_get_var($shm, 2));
+
+var_dump(shm_remove($shm));
+?>
+--EXPECTF--
+bool(true)
+
+Warning: shm_put_var(): Not enough shared memory left in %s on line %d
+bool(false)
+bool(true)
+string(2) "ok"
+bool(true)
+--CLEAN--
+<?php
+$raw = @shmop_open(0x53484D31, 'w', 0, 0);
+if ($raw) {
+ shmop_delete($raw);
+}
+?>
diff --git a/ext/sysvshm/tests/shm_attach_existing_segment_too_small.phpt b/ext/sysvshm/tests/shm_attach_existing_segment_too_small.phpt
new file mode 100644
index 000000000000..eec56c8f0919
--- /dev/null
+++ b/ext/sysvshm/tests/shm_attach_existing_segment_too_small.phpt
@@ -0,0 +1,25 @@
+--TEST--
+shm_attach() rejects an existing segment too small to hold its header
+--EXTENSIONS--
+sysvshm
+shmop
+--FILE--
+<?php
+$key = 0x53484D32;
+
+$raw = shmop_open($key, 'n', 0600, 8);
+
+var_dump(shm_attach($key, 1024));
+
+shmop_delete($raw);
+?>
+--EXPECTF--
+Warning: shm_attach(): Failed for key 0x%x: segment too small in %s on line %d
+bool(false)
+--CLEAN--
+<?php
+$raw = @shmop_open(0x53484D32, 'w', 0, 0);
+if ($raw) {
+ shmop_delete($raw);
+}
+?>