Conversation
Linux O_PATH descriptors carry only path reference: read, write, lseek, ftruncate, fsync/fdatasync, flock, ioctl, fchmod, fchown, getdents64, fsetxattr, and fremovexattr must all return EBADF. Our translate_open_flags maps O_PATH to a plain O_RDONLY host fd, so without explicit gating the host call would silently succeed and diverge from Linux semantics on every one of those paths. Add host_fd_ref_open_io in syscall/internal.h that snapshots the fd entry and rejects FD_PATH with -EBADF. Wire it into sys_lseek and sys_ftruncate (fs.c), sc_fsync_common and sc_flock (syscall.c), and sys_fsetxattr / sys_fremovexattr (fs-xattr.c). sys_getdents64 gains an explicit FD_PATH gate ahead of the dir==NULL check so an O_PATH directory reports EBADF rather than ENOTDIR. io.c's host_fd_ref_open_regular_io now delegates to the shared helper. fchdir, fstat, fstatfs, close, dup, fcntl(CLOEXEC/DUPFD/GETFL), and *at() dirfd usage stay allowed, matching Linux. Audit also surfaced an aarch64 syscall-number bug. SYS_fgetxattr was 16 (real value 10) and SYS_fremovexattr was 18 (real value 16) per include/uapi/asm-generic/unistd.h. Guest fremovexattr was being dispatched to the fgetxattr handler, which then ran with garbage size/value pointers from the unused argument registers; the missing FD_PATH check kept this hidden until tests/test-opath.c exercised it. Numbers in src/syscall/abi.h now match upstream.
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.
Linux O_PATH descriptors carry only path reference: read, write, lseek, ftruncate, fsync/fdatasync, flock, ioctl, fchmod, fchown, getdents64, fsetxattr, and fremovexattr must all return EBADF. Our translate_open_flags maps O_PATH to a plain O_RDONLY host fd, so without explicit gating the host call would silently succeed and diverge from Linux semantics on every one of those paths.
Add host_fd_ref_open_io in syscall/internal.h that snapshots the fd entry and rejects FD_PATH with -EBADF. Wire it into sys_lseek and sys_ftruncate (fs.c), sc_fsync_common and sc_flock (syscall.c), and sys_fsetxattr / sys_fremovexattr (fs-xattr.c). sys_getdents64 gains an explicit FD_PATH gate ahead of the dir==NULL check so an O_PATH directory reports EBADF rather than ENOTDIR. io.c's host_fd_ref_open_regular_io now delegates to the shared helper. fchdir, fstat, fstatfs, close, dup, fcntl(CLOEXEC/DUPFD/GETFL), and *at() dirfd usage stay allowed, matching Linux.
Audit also surfaced an aarch64 syscall-number bug. SYS_fgetxattr was 16 (real value 10) and SYS_fremovexattr was 18 (real value 16) per include/uapi/asm-generic/unistd.h. Guest fremovexattr was being dispatched to the fgetxattr handler, which then ran with garbage size/value pointers from the unused argument registers; the missing FD_PATH check kept this hidden until tests/test-opath.c exercised it. Numbers in src/syscall/abi.h now match upstream.
Summary by cubic
Enforce Linux O_PATH semantics so ops that need a real file now return EBADF on O_PATH fds, and fix aarch64 xattr syscall numbers. This aligns behavior with Linux and prevents silent success.
FD_PATH; used by lseek, ftruncate, fsync/fdatasync, flock, fsetxattr, fremovexattr; getdents64 now returns EBADF for O_PATH dirs;io.cdelegates to the helper.Written for commit b23f003. Summary will update on new commits.