Skip to content

procfs: stat through a task's root or cwd link - #269

Merged
congwang-mk merged 3 commits into
mainfrom
stat-through-task-links
Oct 2, 2026
Merged

congwang-mk merged 3 commits into
mainfrom
stat-through-task-links

Conversation

@congwang-mk

@congwang-mk congwang-mk commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

Inside a sandbox, stat through a task's root or cwd link failed with ELOOP: stat /proc/self/root/etc/passwd, stat /proc/self/cwd/hostname, and stat -L /proc/self/root. Opening the same paths worked, so the procfs test only caught it on riscv64, where uutils cat stats its operand before opening it (GNU cat does not).

Since f9d5ec4 the normalizer spells /proc/<task>/root|cwd/... directly, so the metadata handler's bare-link branch never matched, and a path continuing past the link was probed by its literal spelling, which the probe refuses to resolve through a magic link.

The handler now follows the task's own link itself, as the kernel would, and resolves the rest of the path from there while still refusing further magic links. The bare link is the same case with nothing after it, and .. walks the real tree.

The second commit makes the handler parse a task's /proc prefix once, for both fd/N and the links. The parser walks the prefix the way the kernel does (., .., doubled slashes) over the path joined to its base, and leaves everything after the entry as spelled. That keeps /proc/self/./exe working and also covers relative spellings through a dirfd on /proc/<pid>.

The third commit moves the general metadata handler out of procfs/net_metadata.rs into procfs/metadata.rs, without changing it. It answers every path stat, access and readlink in a sandbox without a chroot, not only those under /proc/net; it lived in the net module only because the network view introduced it. net_metadata.rs keeps the network catalog and exposes serve_pinned, which the handler calls once it has pinned the object.

test_root_and_cwd_magic_links_name_the_virtual_file now also checks with [ -d ]/[ -f ], which stat their operand, so x86 catches a regression too.

Tested: lib tests and full integration suite on x86_64 (887 lib, 517 integration) and the integration suite on riscv64 (882 lib, 514 integration).

🤖 Generated with Claude Code

Since the normalizer started spelling /proc/<task>/root and cwd paths
directly, the metadata handler never saw those entries: a path continuing
past the link was probed by its literal spelling, which the probe refuses
to resolve through a magic link, so stat of /proc/self/root/etc/passwd or
/proc/self/cwd/hostname failed with ELOOP, and stat -L of the bare link
fell to the same probe. Opening a path worked, which hid it: GNU cat never
stats its operand, while uutils cat on riscv64 does.

The handler now follows the task's own link itself, as the kernel would,
and resolves the rest from there, still refusing further magic links. The
bare link is the same case with nothing after it, and .. walks the real
tree rather than the spelling.

Signed-off-by: Cong Wang <cwang@multikernel.io>
The metadata handler parsed the same path twice: the normalized spelling
for fd/N, where the root and cwd links had already been rewritten away,
and the literal one for those links, which missed /proc/self/./exe or a
doubled slash and so regressed them to ELOOP, and missed relative spellings
through a dirfd on /proc/<pid>.

One parse now serves both. It walks the /proc/<task>/ prefix the way the
kernel would, collapsing ., .. and empty components, over the path joined
to its base but not normalized, and leaves the entry and everything after
it as spelled, so the tail behind a root or cwd link still resolves
against the real tree.

Signed-off-by: Cong Wang <cwang@multikernel.io>
handle_pinned_metadata answers every path stat, access and readlink in a
sandbox without a chroot, not just those under /proc/net, but it lived in
net_metadata.rs because the network view introduced it. A bug in its
general path, like stat through /proc/self/root, then read as a network
problem.

The request decoding, the probes, the /proc prefix parser and the handler
move to procfs/metadata.rs unchanged. net_metadata.rs keeps the network
catalog and exposes serve_pinned, which the handler asks once it has
pinned the object.

Signed-off-by: Cong Wang <cwang@multikernel.io>
@congwang-mk
congwang-mk force-pushed the stat-through-task-links branch from 7c126e5 to ee02dfd Compare October 2, 2026 20:40
@congwang-mk
congwang-mk merged commit af03385 into main Oct 2, 2026
17 checks passed
@congwang-mk
congwang-mk deleted the stat-through-task-links branch October 2, 2026 22:16
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.

1 participant