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
2 times, most recently
from
August 14, 2026 08:07
4ea95ea to
d2b0d8e
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 two paths; channel() returns only the Receiver, and Receiver::conf() derives the configuration from receiver-owned C strings, with the lock path now stored beside the keeper path. - 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 whichever allocator the caller passes, whose lifetime bounds the payload. - The unix preload attaches with one page-backed bump from fspy_nostd_alloc::page_bump(), held in ManuallyDrop from the start: the payload storage lands at its base, the sender's temporary path decode runs inside Bump::scoped so the same chunk is reused and reclaimed, and the never-dropped bump gives one mapping for the whole attach unless the payload outgrows the chunk, nothing from the global allocator, and no borrows into the mutable process environment. assume_process_lifetime documents the single unsafe step that names the leak. - 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 14, 2026 08:10
d2b0d8e to
4fa2c1a
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 paths;channel()returns only theReceiver, andReceiver::conf()derives the serializable configuration from receiver-owned C strings.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 inManuallyDropfrom the start: the payload's process-lifetime storage lands at the bump's base, the sender's temporary path decode runs insideBump::scopedso the same chunk is reused and reclaimed, and the bump is never dropped. One mapping for the whole attach (a second only if the payload outgrows the chunk), no global allocator, and the singleunsafe—assume_process_lifetime— reasons directly against theManuallyDropdeclaration;scopedtaking&mut selfforces the promotion to happen before any temporary can exist. The copy out of the environment is deliberate — env memory is not stable storage.seccomp_payloadstays owned until fspy_seccomp_unotify grows borrowed types.🤖 Generated with Claude Code