From ea8aab92208186799112d1aa53dde56685332f37 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] 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. Closes GH-21388. --- NEWS | 3 ++ ext/sysvshm/sysvshm.c | 10 ++++--- ext/sysvshm/tests/shm_get_var_leak.phpt | 37 +++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 ext/sysvshm/tests/shm_get_var_leak.phpt diff --git a/NEWS b/NEWS index 5380688ce3d..542447107fa 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,9 @@ PHP NEWS . Fixed bug GH-20627 (Cannot identify some avif images with getimagesize). (y-guyon) +- Sysvshm: + . Fix memory leak in shm_get_var() when variable is corrupted. (ndossche) + 12 Mar 2026, PHP 8.4.19 - Core: diff --git a/ext/sysvshm/sysvshm.c b/ext/sysvshm/sysvshm.c index 332a8b47af1..3fa7c77add3 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) { - php_error_docref(NULL, E_WARNING, "Variable data in shared memory is corrupted"); - RETVAL_FALSE; - } + 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"); + zval_ptr_dtor(return_value); + RETURN_FALSE; + } } /* }}} */ 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 00000000000..037bad7c41d --- /dev/null +++ b/ext/sysvshm/tests/shm_get_var_leak.phpt @@ -0,0 +1,37 @@ +--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)