refactor(fspy-shared): make the payload a borrowed view - #671
Draft
wan9chi wants to merge 1 commit into
Draft
Conversation
fspy benchmarklinuxmacoswindows |
wan9chi
force-pushed
the
agent/fspy-channel-conf-view
branch
from
August 14, 2026 04:21
ddd04dd to
cd1446d
Compare
wan9chi
force-pushed
the
agent/fspy-channel-conf-view
branch
7 times, most recently
from
August 14, 2026 07:46
eb1efd6 to
fde03cd
Compare
wan9chi
force-pushed
the
agent/fspy-channel-conf-view
branch
4 times, most recently
from
August 18, 2026 03:43
4fa2c1a to
d44239e
Compare
wan9chi
force-pushed
the
agent/fspy-channel-conf-view
branch
from
August 18, 2026 09:13
d44239e to
e8a57be
Compare
wan9chi
force-pushed
the
agent/fspy-channel-conf-view
branch
3 times, most recently
from
August 18, 2026 10:06
9f03d6f to
e7d0ba3
Compare
The payload and its channel configuration are now views over storage their producer owns, the model the Windows preload already had with its static Detours page: - ChannelConf borrows its path in C-string form (the new IpcCStr, an IpcStr that keeps its NUL terminator): channel() returns only the Receiver, Receiver::conf() borrows the keeper's C string, and a unix sender attaches by borrowing the path straight from the conf — no allocation at all. Windows still re-aligns the wide path through a caller-provided allocator. IpcStr sheds the APIs whose last users this replaces (from_os_c_str, to_os_c_string_in, to_boxed). - The unix Payload and EncodedPayload borrow every path and the encoded string. The supervisor lends its session paths per spawn instead of cloning boxes. seccomp_payload stays owned until fspy_seccomp_unotify grows borrowed types. - decode_payload_from_env leaks its allocations into the allocator the caller lends, whose borrow bounds the payload. - The preload ctor owns the attach storage — one page-backed bump from fspy_nostd_alloc::page_bump(), held in ManuallyDrop and never dropped — and lends it to from_env, which is safe code end to end: decode leaks the payload into the bump and the sender borrows its path from the decoded bytes. The ctor's Client::assume_process_lifetime is the attach's single unsafe step, reasoning against the bump the ctor itself owns. One mapping serves the whole attach unless the payload outgrows the chunk, nothing comes from the global allocator, and nothing borrows the mutable process environment. - The Windows preload deserializes its payload zero-copy from the static page and forwards those original bytes to children instead of re-serializing per spawn. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wan9chi
force-pushed
the
agent/fspy-channel-conf-view
branch
from
August 18, 2026 10:21
e7d0ba3 to
94b517a
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.
Motivation
The end goal is a fully std-free preload, and the payload types were shaped against it: the channel configuration and every payload path crossed process boundaries as
Box<IpcStr>, copied out of the deserialization buffer through the global allocator — on the attach path, under the loader lock on Windows.Nothing needs to own payload fields. This makes
PayloadandEncodedPayloadstrictly borrowed views over storage their producer owns — the model the Windows preload already had with its'staticDetours page:ChannelConf<'a>borrows its path in C-string form — the newIpcCStr, anIpcStrthat keeps its NUL terminator.channel()returns only theReceiver,Receiver::conf()borrows the keeper's C string, and a unix sender attaches by borrowing the path straight from the conf, allocating nothing; Windows still re-aligns the wide path through a caller-provided allocator.IpcStrsheds the APIs whose last users this replaces.decode_payload_from_envleaks its allocations into whichever allocator the caller passes — the allocator's lifetime bounds the payload's. The supervisor lends its session paths per spawn instead of cloning boxes.fspy_nostd_alloc::page_bump()), held inManuallyDropand never dropped — and lends it tofrom_env, which is now safe code end to end: decode leaks the payload into the bump, and the sender borrows its path from the decoded bytes, so no temporary allocation, no scope, and no lifetime laundering exist in the attach at all. The ctor'sClient::assume_process_lifetimeis the singleunsafestep, reasoning against the bump the ctor itself owns. One mapping serves the whole attach (a second only if the payload outgrows the chunk), no global allocator, and no borrows into the mutable process environment — env memory is not stable storage, so the value is copied out deliberately.seccomp_payloadstays owned until fspy_seccomp_unotify grows borrowed types.🤖 Generated with Claude Code