Repository navigation
fix(fspy): forward calls with -1 as the directory descriptor - #862
Open
magurotuna wants to merge 6 commits into
Open
magurotuna wants to merge 6 commits into
magurotuna wants to merge 6 commits into
Conversation
A tracked program can pass -1 as a directory descriptor, such as a failed `open` result it does not check. procps-ng's `ps -p <pid>` does this for an exited process, and the interposers abort it while borrowing -1 (voidzero-dev/vite-plus#2954). Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The interposers borrowed every descriptor argument with `BorrowedFd::borrow_raw`, which panics on -1, so a tracked program that passed a failed `open` result to `openat`, `fstatat`, `faccessat`, `statx`, `fdopendir`, or `execveat` aborted. procps-ng's `ps -p <pid>` does this when the process has exited. Borrow descriptor arguments as `Option`, with `None` for -1. An absolute pathname is still tracked, since the kernel ignores the descriptor; a relative pathname or a lone descriptor is not, since the call fails with `EBADF`. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…rget The tests called the libc `statx` wrapper, which glibc 2.17 lacks and the libc crate does not declare for musl, so the Linux CI builds failed. Call `statx` through `syscall` instead, and resolve the glibc `statx` and `execveat` wrappers with `dlsym` so that their interposers are still covered on glibc. Also cover `statx` with a null path and `AT_EMPTY_PATH`, and check that a relative path at -1 is not recorded under the current directory. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…#862 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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
In a cached task, the
ps -p <pid>command aborts with theSIGABRTsignal if the process<pid>has already exited. Outside ofvp run, the same command exits with status 1.Some file system calls, such as
openat, take a directory descriptor: an open file descriptor of a directory, which the call uses to resolve a relative path. Starting with version 4.0.6 (5e4886ae),psfrom procps-ng opens/proc/<pid>as a directory descriptor and then reads thestatusfile relative to it. If the process has exited, the open fails and returns-1.psdoes not check the result, and callsopenat(-1, "status", O_RDONLY). This call is harmless by itself: the kernel fails it with theEBADFerror.On Linux and macOS, fspy injects interceptors into tracked programs. An interceptor is a function that replaces a libc function, such as
openat, records the path, and then calls the original function. The interceptor converted the directory descriptor with theBorrowedFd::borrow_rawfunction, which panics on-1. The injected library aborts on panic, so the panic abortedps.Any tracked program that passes
-1as a directory descriptor aborted in the same way. Thepscommand is the reported case.Fixes voidzero-dev/vite-plus#2954.
Changes
BorrowedFd::try_borrow_rawfunction, which returnsNonefor-1. The interceptors use this function, so that they forward a call with-1to the original function instead of panicking.openat,fstatat,faccessat,statx,syscall(SYS_statx),fdopendir,getdirentries, andexecveat, and on macOS alsoopenat$NOCANCELand__getdirentries64.crates/fspy/tests/invalid_dirfd.rstests. The tests callstatxwith thesyscallfunction, and call the glibcstatxandexecveatfunctions through thedlsymfunction, so that the tests build for glibc 2.17 and musl.