Skip to content

[sysvshm] Clamp shm_get_var chunk length to segment bounds - #23495

Open
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/sysvshm-getvar-len-trust-84
Open

[sysvshm] Clamp shm_get_var chunk length to segment bounds#23495
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/sysvshm-getvar-len-trust-84

Conversation

@iliaal

@iliaal iliaal commented Aug 29, 2026

Copy link
Copy Markdown
Member

shm_get_var() passed the segment-controlled sysvshm_chunk->length to php_var_unserialize() as the end bound, so a hostile segment claiming a multi-gigabyte length walks the parser past ptr->end and off the mapping. Out-of-range lengths now draw the existing corruption warning, and php_check_shm_data() skips chunk headers that do not fully fit before ptr->end. Siblings are unaffected: php_remove_shm_data() memmoves only when memcpy_len > 0, and sysvmsg unserializes msgrcv()'s kernel-bounded byte count. The regression test builds the hostile segment in-process via FFI and skips on non-Linux and on 32-bit.

shm_get_var() trusted the sysvshm_chunk->length field read straight from
the shared memory segment and handed it to php_var_unserialize() as the
end bound: a hostile segment claiming a multi-gigabyte length made the
parser read past ptr->end and past the end of the SysV mapping. Reject a
negative or out-of-bounds length with the existing corruption warning and
harden php_check_shm_data() so a chain walk never dereferences a chunk
header that does not fully fit before ptr->end. Sibling audit:
php_remove_shm_data() only memmoves when memcpy_len > 0, which bounds it
to [shm_varpos, old end), and sysvmsg unserializes exactly msgrcv()'s
kernel-bounded byte count, so both are unaffected.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant