Skip to content

Intercept fstatfs and synthesize procfs magic for all /proc files#207

Open
doanbaotrung wants to merge 1 commit into
sysprog21:mainfrom
open-sources-port:proc_path
Open

Intercept fstatfs and synthesize procfs magic for all /proc files#207
doanbaotrung wants to merge 1 commit into
sysprog21:mainfrom
open-sources-port:proc_path

Conversation

@doanbaotrung

@doanbaotrung doanbaotrung commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator

When fstatfs is called on open file descriptors pointing to /proc files (e.g., /proc/self/maps, /proc/uptime, /proc/loadavg), it returned the host filesystem magic (e.g. APFS) instead of LINUX_PROC_SUPER_MAGIC (0x9fa0).

Fix this by:

  • Modifying resolve_virtual_path in fs.c to resolve and normalize all paths under /proc (not just virtual directories/stateful files) and record them in the fd table's proc_path field.
  • Introducing a fill_proc_statfs helper in fs-stat.c that populates a static linux_statfs_t layout with PROC_SUPER_MAGIC (0x9fa0) and zero blocks/free space.
  • Intercepting both sys_statfs and sys_fstatfs when the target path or fd's proc_path points to /proc, and directly writing the synthesized procfs metadata back to the guest.

Fix #142


Summary by cubic

Return the correct procfs magic for /proc files by intercepting statfs/fstatfs and normalizing /proc paths, while skipping procfs symlinks so only real proc entries report procfs. Fixes #142.

  • Bug Fixes
    • Normalize and record /proc paths in resolve_virtual_path, mapping /proc/<pid> (for the current pid) to /proc/self, and exclude procfs symlinks (/proc/self/{exe,cwd,root}, /proc/self/fd/<n>, and task equivalents) so they report the target filesystem.
    • Add fill_proc_statfs to synthesize a linux_statfs_t with PROC_SUPER_MAGIC (0x9fa0), 4K block size, and zeroed counts.
    • Intercept sys_statfs and sys_fstatfs for /proc targets and return the synthesized procfs stats.

Written for commit 92599f3. Summary will update on new commits.

Review in cubic

cubic-dev-ai[bot]

This comment was marked as resolved.

To fix fstatfs returning the incorrect magic on open descriptors of
procfs magic links and symlinks, exclude paths like /proc/self/exe,
/proc/self/cwd, /proc/self/root, /proc/self/fd/N, and task-specific
equivalents from resolving to a virtual proc_path stamp.

This prevents the guest fd table from recording these entries as part
of the emulated procfs, letting fstatfs correctly query the filesystem
information of their resolved host file targets.

Fix sysprog21#142
@jserv jserv requested a review from Max042004 July 15, 2026 08:09
@jserv jserv changed the title fs: intercept fstatfs and synthesize procfs magic for all /proc files Intercept fstatfs and synthesize procfs magic for all /proc files Jul 15, 2026
Comment thread src/syscall/fs-stat.c
* then fall back to the same intercept open/fstatfs/close that
* sys_newfstatat uses via proc_intercept_stat.
*/
if (statfs_path_is_proc(tx.intercept_path)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

statfs on a nonexistent /proc path now returns success instead of ENOENT. statfs_path_is_proc() matches any /proc-prefixed path, so this block fills PROC_SUPER_MAGIC and returns 0 without confirming the entry exists. The previous code fell through proc_intercept_statfs -> proc_intercept_open -> statfs(host_path), so a miss propagated ENOENT.

Trigger: statfs("/proc/bogus", &buf) or statfs("/proc/self/not_a_file", &buf) -- real Linux and pre-PR return -ENOENT; this returns 0 with f_type=0x9fa0. Programs that use statfs as an existence/feature probe are misled.

Fix: gate synthesis on a positive existence check (only synthesize when proc_intercept_stat(tx.intercept_path, ...) recognizes the path, otherwise fall through to the host statfs that yields ENOENT). Only f_type needed to change; existence semantics should be preserved.

Comment thread src/syscall/fs.c
return true;
}

/* If it has a valid /proc prefix, normalize it and record it. */

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stamping proc_path for every non-symlink /proc/* entry -- including regular files like /proc/cpuinfo and /proc/self/maps -- leaks dirfd semantics into consumers that key off proc_path. dirfd_guest_base_path (path.c:883) accepts any fd with a non-empty proc_path as a resolution base and returns before the snap.type != FD_DIR -> ENOTDIR guard at path.c:909 -- unlike resolve_proc_dirfd_path (path.c:522), which requires FD_DIR.

Trigger: open /proc/cpuinfo as fd 5, then openat(5, "x", ...). Real Linux returns ENOTDIR; this builds /proc/cpuinfo/x and resolves it (wrong errno / wrong target). It also reroutes plain fstat on such fds through proc_intercept_stat.

Fix: only stamp proc_path for /proc entries that are directories (the cases where the fd is a legitimate dirfd), or record a separate proc-mount flag used solely by the statfs path rather than overloading proc_path, which carries dirfd-resolution meaning.

Comment thread src/syscall/fs-stat.c
return !strncmp(path, "/proc", 5) && (path[5] == '\0' || path[5] == '/');
}

static void fill_proc_statfs(linux_statfs_t *lin)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The linux_statfs_t layout here is complete and correct (all fields covered by memset(0); f_type/f_bsize/f_namelen/f_frsize consistent with a real procfs). No regression test asserts the magic, though -- the existing tests only compare statfs vs fstatfs, not the value 0x9fa0. Worth adding one assertion for f_type == 0x9fa0 on both statfs("/proc/...") and fstatfs(open("/proc/...")).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing proc_path for Dynamic/Non-Stateful procfs Files in sys_fstatfs

2 participants