Skip to content

fpm: fix event queue use-after-free in select and poll backends - #25154

Open
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/aph-fpm-event-queue-uaf-84
Open

iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/aph-fpm-event-queue-uaf-84

Conversation

@iliaal

@iliaal iliaal commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

When a worker pipe reaches EOF, fpm_stdio_child_said() deletes its own event, freeing the queue node that fpm_event_select_wait() and fpm_event_poll_wait() then read next from. With catch_workers_output = yes this happens when a worker exits under select, and under poll when it leaves unread output (on Linux an empty pipe at EOF raises only POLLHUP); with glibc the master segfaults. The loops now save the successor before firing, as the timer loop already does, and no fd callback can free that node.

fpm_event_select_wait() and fpm_event_poll_wait() read q->next after
firing the event, but fpm_stdio_child_said() deletes its own event when a
worker pipe reaches EOF, which frees q. The iterator must not touch a node
a callback may have freed, so save the successor before firing, as the
timer loop in fpm_event_loop() already does. With catch_workers_output
enabled, the loop reads freed memory when a worker exits under select, and
under poll on Linux when the worker leaves unread output in its pipe. With
glibc this crashes the master.
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