1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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.
This commit is contained in:
ndossche
2026-03-08 23:00:49 +01:00
parent 3073948885
commit ea8aab9220
3 changed files with 46 additions and 4 deletions

3
NEWS
View File

@@ -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:

View File

@@ -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;
}
}
/* }}} */

View File

@@ -0,0 +1,37 @@
--TEST--
shm_get_var() leaks if variable is corrupted
--EXTENSIONS--
sysvshm
ffi
--INI--
ffi.enable=1
--SKIPIF--
<?php
if (!function_exists('ftok')) die('skip needs ftok');
if (PHP_INT_SIZE !== 8) die('skip only for 64-bit');
if (PHP_OS_FAMILY !== 'Linux') die('skip only for decent operating systems');
?>
--FILE--
<?php
$key = ftok(__FILE__, 't');
$s = shm_attach($key, 128);
shm_put_var($s, 0, [1, 2]);
$ffi = FFI::cdef(<<<CODE
int shmget(int, size_t, int);
char *shmat(int, const void *, int);
CODE);
$ptr = $ffi->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)