Repository navigation
refactor(fspy): collect execl arguments in the call's bump allocator - #891
Merged
Merged
Conversation
`execl`, `execlp` and `execle` built their argv array in a 32-slot stack array, fell back to libc malloc for longer lists, and failed with E2BIG past a hardcoded 4096 arguments. malloc is not async-signal-safe: exec may run in the child of fork(), where malloc's lock may be held by a thread that no longer exists. Push the arguments into a Vec in the call's pooled bump instead, and pass that bump on to handle_exec, as execveat already does. This drops the stack/heap split, the hardcoded limit, and the closure-based with_argv helper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fspy benchmarklinuxmacoswindows |
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
execl,execlpandexeclepass their arguments as a variadic list, so the interposer has to build an argv array before it can handle the exec. It used a 32-slot stack array, fell back to libcmallocfor longer lists, and failed withE2BIGpast a hardcoded 4096 arguments. That split is where #865's out-of-bounds write lived, and themallocfallback isn't async-signal-safe: exec may run in the child offork(), where malloc's lock may be held by a thread that no longer exists.Change
collect_argvpushesargand the variadic arguments, up to and including the NULL, into anallocator_api2::vec::Vecin the call'spooled_bump(), and leaves theVaListwhereexeclereadsenvp.collect_argvandhandle_exec, asexecveatalready does.with_argv.rsis removed along with the stack/heap split and the 4096-argument limit; the realexecvereportsE2BIGinstead.The rest of the exec path still allocates through libc
malloc(RawExec::to_exec/from_exec,fexecve); the PR stacked on this one removes that.🤖 Generated with Claude Code