fix(mediation): add ACK handshake to drain buffer before sending stdio fds#55
Merged
Conversation
…o fds The shim sends a length-prefixed JSON request that can be 6-9 KB in an AI agent session (full process environment included). macOS UDS receive buffers default to ~8 KB, so the JSON can fill the buffer before the server has had a chance to drain it. The subsequent sendmsg with SCM_RIGHTS then fails with EMSGSIZE because there is no contiguous space left in the buffer for the ancillary control message — even with all three fds batched into a single sendmsg call. Fix: the server sends a single ACK byte (0x06) after reading the JSON body (which drains the buffer), and the shim reads this ACK before calling sendmsg. This ensures the buffer is always empty at the point the SCM_RIGHTS message is sent. Protocol change (shim and server must be updated together): 1. Request: u32 length || JSON body (unchanged) 2. ACK: 1 byte 0x06 from server (new) 3. SCM_RIGHTS sendmsg — stdin/stdout/stderr (unchanged) 4. Response: u32 length || JSON body (unchanged) Also adds an end-to-end test in nono-shim that exercises the full ACK handshake and SCM_RIGHTS transfer with a mock server thread.
485620e to
de4dfa9
Compare
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.
Problem
Commands with large environments fail with:
This is EMSGSIZE. The root cause is a race between the JSON write and the SCM_RIGHTS sendmsg: the shim sends the full process environment in the JSON request (which can be 6–9 KB), filling the macOS UDS receive buffer (~8 KB default). When the shim immediately calls
sendmsgwith the SCM_RIGHTS control message, there is no contiguous buffer space left for the ancillary data — even with all three fds bundled into a singlesendmsg.Fix
Add a 1-byte ACK handshake between the JSON read and the fd receive:
0x06ACKsendmsgThis guarantees the buffer is empty at the point the SCM_RIGHTS message is sent.
Protocol change — shim and server must ship together.
Updated protocol:
Test
Added
ack_handshake_round_tripstonono-shim— spins up a mock server thread that follows the new protocol, verifies the SCM_RIGHTS transfer succeeds, and checks the exit code.