Repository navigation
fix(syswrap): return the client's auxv from prctl(PR_GET_AUXV) - #49
Open
lvaroqui wants to merge 2 commits into
Conversation
lvaroqui
added this pull request to stack #50
October 9, 2026 11:59
Merging this PR will not alter performance
Comparing Footnotes
|
lvaroqui
marked this pull request as ready for review
October 9, 2026 12:24
|
The kernel answers PR_GET_AUXV (Linux 6.4+) with the auxv it saved when it exec'd the Valgrind tool, so a program reading its auxv this way got the tool's entries, including AT_EXECFN (e.g. .../callgrind-amd64-linux), while getauxval() and /proc/self/auxv already report the client's. Multicall binaries that pick their behavior from AT_EXECFN, such as rust-coreutils 0.8.0 shipped with Ubuntu 26.04, failed with "unknown program 'callgrind-amd64-linux'". Handle PR_GET_AUXV in the prctl wrapper: copy the client auxv, zero-padded to the size the kernel reports, into the caller's buffer and return that size. Keep the kernel's EINVAL for nonzero arg4/arg5 and on kernels without the option, and EFAULT for an unaddressable buffer. Closes COD-3810 Co-Authored-By: Claude <noreply@anthropic.com>
lvaroqui
force-pushed
the
cod-3810-valgrind-codspeed-leaks-the-host-auxv-through
branch
from
October 9, 2026 12:45
305a73e to
8df58f1
Compare
The PR_GET_AUXV handler read the auxv from the client's initial stack on every call. A program that writes to those pages got the modified vector, and one that unmaps or protects them after switching stacks made Valgrind fault while reading them, where the kernel answers from the copy it saved at exec. Copy the client auxv at startup, where the fake /proc/self/auxv is created, and answer PR_GET_AUXV from that copy. The regression test now also writes to the stack auxv and checks that PR_GET_AUXV still returns the saved vector. Refs COD-3810 Co-Authored-By: Claude <noreply@anthropic.com>
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.
Under valgrind,
prctl(PR_GET_AUXV)(Linux 6.4+) reached the kernel unchanged and returned the auxv the kernel saved when it exec'd the valgrind tool, not the program's.getauxval()and/proc/self/auxvalready report the program's auxv, so the two disagreed.AT_EXECFNcame back as.../callgrind-amd64-linux, which breaks multicall binaries that pick their behavior from it. rust-coreutils 0.8.0, shipped with Ubuntu 26.04, failed every command under valgrind withcoreutils: unknown program 'callgrind-amd64-linux'. Its 0.10.0 update no longer reads its name this way, but any program callingPR_GET_AUXVis affected, on any distro.The prctl wrapper now answers
PR_GET_AUXVitself and keeps the kernel's contract:/proc/self/auxvis created, like the kernel's copy saved at exec. Writing to, protecting or unmapping the original stack afterwards does not affect it.arg4/arg5fail withEINVAL, and a buffer the caller cannot write (unmapped or read-only) withEFAULT. Kernels withoutPR_GET_AUXVreturn their ownEINVAL.The wrapper completes the call itself, so it clears
SfMayBlock: syswrap-main asserts that a call completed successfully in the pre-handler does not carry it.callgrind/tests/prctl_get_auxvchecksAT_EXECFN, that the whole vector equals the one on the stack and later writes to the stack copy do not show, that the size equals the kernel's (taken from a native run) with zero padding up to it, short buffers,EINVALforarg4/arg5, andEFAULTfor unmapped and read-only buffers. It passes natively, fails without this fix, and is skipped outside Linux and on kernels withoutPR_GET_AUXV. Under memcheck the only report is the test's deliberate unmapped buffer, so the copied bytes are marked defined. Only amd64 was verified locally.Stacked on #48.
Closes COD-3810