Skip to content

Fix stream filter flush corrupting a partially-read buffer - #22424

Closed
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:streams-filter-flush-writepos
Closed

iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:streams-filter-flush-writepos

Conversation

@iliaal

@iliaal iliaal commented Jun 24, 2026

Copy link
Copy Markdown
Member

When a read filter is flushed (for example via stream_filter_remove()) while the stream has already been partially read, _php_stream_filter_flush() backs the unconsumed tail of the read buffer up to offset 0. Two defects in that block diverged from the equivalent code in streams.c. The copy used memcpy() on source/destination ranges that overlap whenever writepos - readpos exceeds readpos, which is undefined behavior (ASAN reports memcpy-param-overlap). And writepos was shrunk with writepos -= readpos after readpos had already been zeroed, making the subtraction a no-op, so writepos stayed inflated by readpos bytes: the stale tail was kept live and later flushed buckets were appended past the real end, duplicating bytes and risking an out-of-bounds write. Use memmove() and subtract before zeroing, matching streams.c. The block dates to the original stream_filter_remove() commit (3455038) in 2004.

When a read filter is flushed (for example via stream_filter_remove())
while the stream has already been partially read, _php_stream_filter_flush()
backs the unconsumed tail of the read buffer up to offset 0. Two defects
in that block diverged from the equivalent code in streams.c. The copy
used memcpy() on source and destination ranges that overlap whenever
writepos - readpos exceeds readpos, which is undefined behavior (ASAN
reports memcpy-param-overlap). And writepos was shrunk with
writepos -= readpos after readpos had already been zeroed, making the
subtraction a no-op, so writepos stayed inflated by readpos bytes: the
stale tail was kept as live data and later flushed buckets were appended
past the real end, duplicating bytes and risking an out-of-bounds write.
Use memmove() and subtract before zeroing, matching streams.c.
@bukka

bukka commented Oct 5, 2026

Copy link
Copy Markdown
Member

Already merged in #23439

@bukka bukka closed this Oct 5, 2026
@bukka

bukka commented Oct 5, 2026

Copy link
Copy Markdown
Member

Just for the record, there was another issue with not saving the readbuflen which is now fixed in #24136

@iliaal
iliaal deleted the streams-filter-flush-writepos branch October 5, 2026 15:08
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.

3 participants