From 13c45ef7a4b72c48252f3e16bed952fc748de733 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Sun, 8 Mar 2026 23:00:49 +0100 Subject: [PATCH 1/2] Fix memory leak in shm_get_var() when variable is corrupted This path wasn't tested (clearly). To trigger this we use FFI, which seemed like the easiest way that doesn't involve using another process messing with the shared memory. --- ext/sysvshm/sysvshm.c | 8 +++--- ext/sysvshm/tests/shm_get_var_leak.phpt | 35 +++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 ext/sysvshm/tests/shm_get_var_leak.phpt diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 332a8b47af1b6..3fa7c77add345 100644 --- a/ext/sysvshm/sysvshm.c +++ b/ext/sysvshm/sysvshm.c @@ -309,11 +309,13 @@ PHP_FUNCTION(shm_get_var) shm_data = &shm_var->mem; PHP_VAR_UNSERIALIZE_INIT(var_hash); - if (php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash) != 1) { + int res = php_var_unserialize(return_value, (const unsigned char **) &shm_data, (unsigned char *) shm_data + shm_var->length, &var_hash); + PHP_VAR_UNSERIALIZE_DESTROY(var_hash); + if (res != 1) { php_error_docref(NULL, E_WARNING, "Variable data in shared memory is corrupted"); - RETVAL_FALSE; + zval_ptr_dtor(return_value); + RETURN_FALSE; } - PHP_VAR_UNSERIALIZE_DESTROY(var_hash); } /* }}} */ diff --git a/ext/sysvshm/tests/shm_get_var_leak.phpt b/ext/sysvshm/tests/shm_get_var_leak.phpt new file mode 100644 index 0000000000000..9441eeb840d92 --- /dev/null +++ b/ext/sysvshm/tests/shm_get_var_leak.phpt @@ -0,0 +1,35 @@ +--TEST-- +shm_get_var() leaks if variable is corrupted +--EXTENSIONS-- +sysvshm +ffi +--INI-- +ffi.enable=1 +--SKIPIF-- + +--FILE-- +shmat($ffi->shmget($key, 0, 0), $ffi->new('void *'), 0); + +$ptr[0x40 + 13] = 0; // Corrupt first byte of second element of serialized data + +var_dump(shm_get_var($s, 0)); + +shm_remove($s); + +?> +--EXPECTF-- +Warning: shm_get_var(): Variable data in shared memory is corrupted in %s on line %d +bool(false) From 9aec1ac8ca4c604b5105079de6a7c3d23b530d7f Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Mon, 9 Mar 2026 00:03:47 +0100 Subject: [PATCH 2/2] fixup! skipifs --- ext/sysvshm/tests/shm_get_var_leak.phpt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/sysvshm/tests/shm_get_var_leak.phpt b/ext/sysvshm/tests/shm_get_var_leak.phpt index 9441eeb840d92..037bad7c41d72 100644 --- a/ext/sysvshm/tests/shm_get_var_leak.phpt +++ b/ext/sysvshm/tests/shm_get_var_leak.phpt @@ -7,7 +7,9 @@ ffi ffi.enable=1 --SKIPIF-- --FILE--