Skip to content

linux-user, fix: Handle AT_FDCWD when hiding helper threads - #463

Open
y347812075 wants to merge 4 commits into
lat-opensource:masterfrom
y347812075:fix-at-fdcwd-procfs
Open

y347812075 wants to merge 4 commits into
lat-opensource:masterfrom
y347812075:fix-at-fdcwd-procfs

Conversation

@y347812075

@y347812075 y347812075 commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Handle relative and AT_EMPTY_PATH stat-family lookups through AT_FDCWD
after a sandbox chroot. Preserve guest pathname snapshots and serialize
identity checks with same-process cwd, root and descriptor changes.

The follow-up fixes address three problems:

  • Release the filesystem mutex before statx guest copyout, including the
    fstatat fallback, to avoid an mmap/fs lock-order deadlock with fork.
  • Restore the saved proc-root self/task identity probe when appending the
    identity suffix to a valid long pathname causes ENAMETOOLONG. Retain
    procfs device/inode checks and other-PID negative coverage.
  • Map guest test failures to exit 1 so Meson does not interpret failure
    code 77 as a skipped test.

Validation

LoongArch Linux, 16 KiB host pages, x86_64 and i386 guest builds, O1;
focused guest tests used LATX_AOT=0 LATX_KZT=0 and namespace tests used
SBX_USER_NS=1.

ninja -C build-tests latx-x86_64 latx-i386
meson test -C build-tests --suite lat-pr-fast --print-errorlogs
LATX_STATX_FORK_GUEST="$GUEST_DIR/statx-fork-race" \
  meson test -C build-tests test-statx-fork-race --print-errorlogs
  • Both guest-target product builds passed.
  • The statx/fork regression passed with 1000 forks and EFAULT checks. Before
    the fix, GDB confirmed statx waiting for mmap while fork waited for fs.
  • The expanded cef-procfs-chroot fixture passed three consecutive runs,
    retaining the original checks and adding long self and other-PID paths.
  • proc-thread-count, cef-userns-exec, fd-transform-race-i386 and
    cef-userns-nested runtime checks passed. The fd-transform injection
    marker was required and observed by its runner.
  • Guest assembly fixtures were compiled separately with GCC/binutils into
    static x86 ELFs. Native helpers were built on LoongArch; original runner
    runtime setup, assertions and exit-status interpretation were retained.
  • Result-handler checks mapped guest statuses 0, 77 and 125 to 0, 1 and 1.
  • Checkpatch found no errors; the new test files produced its generic
    MAINTAINERS reminder.

The final candidate is based on f43de18247c6a139787296a77b945a282a0ee29d.
The complete lat-pr-fast run passed 46/46, with no skips or timeouts.
The AOT cache-reader baseline failure is resolved by the merged #503.

Remaining boundaries

Cross-process CLONE_FS serialization remains outside these follow-up
repairs. The long-path fallback restores the saved proc-root behavior and
does not claim arbitrary long-path support from every procfs dirfd.
No performance neutrality or real-application acceptance is claimed.

y347812075 and others added 4 commits October 10, 2026 15:07
stat-family calls may resolve /proc/self/task through absolute, relative, or empty paths after a shared sandbox chroot. Those accesses could expose LATX-only helper threads in st_nlink.

Snapshot guest pathnames before host at-calls and serialize identity-sensitive stat operations with guest cwd, root, mount, and fd-binding changes. Resolve relative self-task identity through the original dirfd and snapshot without creating translator-owned descriptors in the guest fd table. Carry the serialization lock safely across fork.

Extend the chroot regression with alternate relative spellings and concurrent cwd, dirfd, pathname, and root changes, while retaining negative coverage for other processes and ordinary directories.

Validated with x86_64 and i386 builds, repeated focused procfs races, proc thread-count and userns exec coverage, and the i386 fd-transform fork race.

Signed-off-by: yuerengan <y347812075@163.com>
A multithreaded guest can deadlock when fork runs concurrently with statx
whose output address is inside the guest VA range but unmapped. The statx
path holds latx_syscall_fs_mutex while host_to_target_statx checks the guest
buffer and acquires mmap_lock. fork_start takes the same locks in the
opposite order: mmap first, then the filesystem mutex.

Keep the host lookup and procfs identity correction serialized, then release
the filesystem mutex before accessing the guest output buffer. Apply the
same ordering to the native statx and fstatat fallback paths. The corrected
host result is already a snapshot and needs no filesystem lock during
copyout.

Add a statx/fork integration regression with a guarded unmapped output page
and 1000 forks concurrent with statx calls. The pre-fix translator hangs with the two opposing
wait chains; the corrected translator completes and returns EFAULT for the
invalid statx buffers.

Validated x86_64 and i386 builds and the registered statx/fork regression
on LoongArch.

Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
The saved-procfd chroot regression can expose helper threads when a valid
relative pathname leaves no room for the /../../self/task identity suffix.
For example, a 4091-byte spelling of self/task passes the original lookup,
but the appended 4107-byte identity lookup fails with ENAMETOOLONG. The
syscall still succeeds while returning an unadjusted task link count.

On ENAMETOOLONG only, restore the fixed self/task probe supported by the
saved proc-root path before the AT_FDCWD follow-up. Both stat and statx
callers still require the original result to match the candidate device and
inode on the verified procfs filesystem. Successful short-path lookups do
not perform another host syscall or expose a temporary descriptor.

Extend the chroot regression with long self and other-PID paths for both
fstatat and statx. This restores the saved proc-root behavior; it does not
claim arbitrary long-path support from every possible procfs dirfd.

Validated the expanded chroot regression and three consecutive runs of the
original chroot checks on LoongArch.

Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
The cef-procfs-chroot guest uses exit 77 for an ordinary-directory fstatat
failure. Its runner prints FAIL but forwards that status to Meson, whose
exitcode protocol interprets 77 as SKIP. A real guest regression can
therefore be reported as a skipped test.

Map all nonzero guest results to runner exit 1. Keep the early exit 77 paths
for unavailable build or namespace prerequisites, and retain the individual
failure diagnostics. Guest status 0 remains success.

Validated the result handler with guest statuses 0, 77 and 125: the runner
returns 0, 1 and 1 respectively.

Signed-off-by: Hanlu Li <heuleehanlu@gmail.com>
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.

2 participants