Skip to content

Fix GH-22063: stream filter chain UAF on self-removal during callback#67

Closed
iliaal wants to merge 1 commit into
masterfrom
fix/gh-22063-stream-filter-uaf
Closed

Fix GH-22063: stream filter chain UAF on self-removal during callback#67
iliaal wants to merge 1 commit into
masterfrom
fix/gh-22063-stream-filter-uaf

Conversation

@iliaal
Copy link
Copy Markdown
Owner

@iliaal iliaal commented May 18, 2026

A php_user_filter that calls stream_filter_remove on its own resource from inside filter() frees the php_stream_filter struct while userfilter_filter still dereferences &thisfilter->abstract and while the chain walks in _php_stream_filter_flush, _php_stream_write_filtered, and _php_stream_fill_read_buffer still need current->next. Two new fields on php_stream_filter, in_callback and deferred_dtor, carry the deferral: php_stream_filter_remove(filter, true) unlinks and runs zend_list_delete immediately but defers the pefree.

A stream filter struct must stay live while a fops->filter() callback
or chain iteration holds it. A php_user_filter that removes its own
resource inside filter() frees the struct under userfilter_filter
(&thisfilter->abstract deref) and under the three chain-walk sites
(current->next read). Defer pefree via an in_callback counter until
every C-level frame holding the filter releases it.

Closes phpGH-22063
@iliaal
Copy link
Copy Markdown
Owner Author

iliaal commented May 18, 2026

Submitted upstream as php#22083

@iliaal iliaal closed this May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant