Fix openat2 ENOTDIR/ENOENT errno mismatches#184
Merged
Conversation
dirfd_guest_base_path() fell back to EBADF whenever a dirfd was open but not host-path-nameable (pipes, sockets, and other non-directory types without an F_GETPATH-able backing file) and was not a directory. The fd is valid, it just cannot anchor a relative lookup, so Linux reports ENOTDIR there and reserves EBADF for closed or out-of-range descriptors. This surfaced through openat2()'s RESOLVE_NO_XDEV precheck. sc_openat2() also let an empty pathname slip through under RESOLVE_IN_ROOT: path_openat2_normalize_in_root() substitutes "." for "", which resolves to dirfd itself instead of failing. Linux's openat2() has no AT_EMPTY_PATH equivalent, so any empty path must fail ENOENT regardless of the requested RESOLVE_* flags. Reject it up front before the resolve-flag-specific handling runs. Fixes sysprog21#133.
Collaborator
Emulated Test Script (
|
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.
Summary
dirfd_guest_base_path()returned EBADF instead of ENOTDIR for a valid but non-directory dirfd with no host-nameable path (pipes, sockets, etc.), surfacing through openat2()'s RESOLVE_NO_XDEV precheck.sc_openat2()let an empty pathname succeed under RESOLVE_IN_ROOT, sincepath_openat2_normalize_in_root()substitutes "." for "" and resolves to dirfd itself. openat2() has no AT_EMPTY_PATH equivalent, so empty paths now fail ENOENT up front.Fixes #133.
Test
Added two regression tests to
tests/test-syscall-fidelity.cmake check— 120/120 passedSummary by cubic
Fix errno handling in openat2 path resolution: valid non-directory dirfds now return ENOTDIR (not EBADF), and empty pathnames return ENOENT even under RESOLVE_IN_ROOT. Added two regression tests to confirm Linux-compatible behavior.
Written for commit 9b99624. Summary will update on new commits.