[codex] Avoid retaining caller input after non-blocking gzwrite stall - #1302
Open
maxvanamersfort wants to merge 1 commit into
Open
[codex] Avoid retaining caller input after non-blocking gzwrite stall#1302maxvanamersfort wants to merge 1 commit into
maxvanamersfort wants to merge 1 commit into
Conversation
maxvanamersfort
marked this pull request as ready for review
August 25, 2026 08:44
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
gzwrite()stallFixes #1292.
Root cause
The large-write path points
strm.next_indirectly at the caller's buffer.If writing compressed output stalls with
EAGAIN,gz_comp()returns whilenext_inandavail_instill describe the unconsumed caller input. A latersmall
gzwrite()orgzputc()assumes that pending input belongs tostate->in, performs pointer arithmetic across unrelated allocations, andcan write out of bounds.
Leaving the caller pointer pending for a later retry is also not sufficient:
the caller may release that buffer after the partial return, and retrying the
reported remainder would duplicate data once zlib consumed the retained input.
On a non-blocking stall, this change accepts at most one internal buffer of the
remaining input, copies that prefix into zlib-owned storage, and reports those
bytes as accepted. The caller retains responsibility for the rest.
Impact
This restores the internal-buffer invariant before the public write call
returns, preventing the out-of-bounds write and the related stale-pointer
read while preserving partial-write semantics for compressed and transparent
output.
Validation
memcpy()fromgz_write()atgzwrite.c:217exactly once, without loss or duplication
-Wall -Wextra -Werror./configure && make -j2 test(static, shared, and 64-bit tests)