Route sys_statfs through the /proc intercept#193
Merged
Conversation
c5f0ff3 to
aa5f7fd
Compare
/proc entries are synthesized on open with
no backing file under the sysroot (see proc_intercept_open), so a raw
statfs() on any /proc path -- including the literal "/proc" -- fails
with ENOENT even though stat() and open() on the same path succeed.
Confirmed by cross-compiling a guest probe and running it under
elfuse: stat("/proc") succeeded while statfs("/proc") returned ENOENT.
Fix sys_statfs to route /proc paths through proc_intercept_open,
fstatfs the resulting host fd, and close it, mirroring how
sys_newfstatat already resolves /proc via proc_intercept_stat. The
prefix check is boundary-safe (rejects "/procfoo") to avoid
reintroducing the naive-match class of bug the issue warns about.
While reproducing this, found that proc_intercept_open's bare "/proc"
case lacked the trailing-slash variant present on all its children
(e.g. "/proc/self/"), so statfs("/proc/") missed even after the fix
above; stat() already handled it via proc_intercept_stat's separate
check. Added the missing variant for consistency.
Review flagged that routing /proc/self/fd and /proc/self/fdinfo
through proc_intercept_open makes statfs() pay for those nodes'
per-open scratch directory -- one placeholder file per live guest fd,
needed only so getdents has something to list -- even though statfs()
never enumerates it. Past PROC_SCRATCH_DIRS_MAX untracked opens, the
leaked dirs also stop getting cleaned up at exit. Add
proc_intercept_statfs, a lightweight resolver that recognizes just
those two nodes and statfs()es /tmp directly (every scratch dir lives
under /tmp, so the filesystem info is identical); sys_statfs tries it
first and only falls back to proc_intercept_open for every other
/proc path.
Add regression coverage to test-proc.c: statfs on "/proc", "/proc/",
and a synthetic file, plus an f_type cross-check against fstatfs on
an already-open fd of the same path; repeated statfs on
/proc/self/fd and /proc/self/fdinfo past the scratch-dir tracking cap.
aa5f7fd to
0795592
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.
/proc entries are synthesized on open with no backing file under
the sysroot (see proc_intercept_open), so a raw statfs() on any
/proc path -- including the literal "/proc" -- fails with ENOENT even
though stat() and open() on the same path succeed. Confirmed by
cross-compiling a guest probe and running it under elfuse:
stat("/proc") succeeded while statfs("/proc") returned ENOENT.
Fix sys_statfs to route /proc paths through proc_intercept_open,
fstatfs the resulting host fd, and close it, mirroring how sys_newfstatat
already resolves /proc via proc_intercept_stat. The prefix check is
boundary-safe (rejects "/procfoo") to avoid reintroducing the naive-match
class of bug the issue warns about.
While reproducing this, found that proc_intercept_open's bare "/proc"
case lacked the trailing-slash variant present on all its children (e.g. "/proc/self/"),
so statfs("/proc/") missed even after the fix above; stat() already handled it
via proc_intercept_stat's separate check. Added the missing variant for consistency.
Add regression coverage to test-proc.c: statfs on "/proc", "/proc/", and a synthetic
file, plus an f_type cross-check against fstatfs on an already-open fd of the same path.
Summary by cubic
Fix ENOENT from statfs on /proc paths by routing them through the /proc intercept so statfs matches stat/open, and avoid scratch-dir allocation for
/proc/self/{fd,fdinfo}. Also handle the/proc/trailing-slash case and extend tests./procpaths; tryproc_intercept_statfsfor/proc/self/{fd,fdinfo}(statfs/tmpto avoid per-open scratch), else useproc_intercept_open→fstatfs; fall back to hoststatfsif not intercepted.proc_intercept_open: accept"/proc/"to match"/proc".statfs("/proc"),statfs("/proc/"),statfs("/proc/self/cmdline"); confirmf_typematchesfstatfs; repeatstatfson/proc/self/fdand/proc/self/fdinfopast the tracking cap.Written for commit 0795592. Summary will update on new commits.