Repository navigation
Conversation
/dev/bus/usb/099/../001/001 answered as the usbfs node where Linux answers ENOENT: the walk fails at 099, which does not exist, before the '..' is applied. The layer folded the '..' without checking whether the name before it exists, so stat and open served the node, and 099/../../../null from a /dev/bus/usb cwd reached /dev/null. On a sysroot that carries a dev/bus/usb/099 directory, /dev/bus/usb/099/../../other/f went to the backing, which walked through that directory although the layer answers ENOENT for /dev/bus/usb/099 itself. Every name under /dev/bus/usb is the layer's, so usb_sysfs_resolve_dev_climb, which already checks each directory it pops, fails such a walk with ENOENT in path_translate_at. path_rebuild_under stops its fold at a missing name as it does at a node, so a name relative to a /dev/bus cwd or descriptor reaches the same check. Its stop test, usb_sysfs_stops_fold, takes usb_lock to look a bus up, and cwd_lock holds only fuse_lock beneath it, so resolve_proc_cwd_path copies the cwd out of its view before rebuilding. A '..' after a name shaped like a node, such as 001/099, is left to the intercepts, which answer ENOENT when no such device exists; calls that skip the intercepts, such as chmod, still reach the backing for such a name. A '..' after a name outside /dev/bus/usb is still applied unchecked, and in an absolute name so is every later '..' except one after a name shaped like a node, as docs/internals.md says. The shadow-dotdot column was recorded on Linux 7.0; recording the table again left every other cell unchanged. With the ENOENT return in usb_sysfs_resolve_dev_climb taken out, the column fails 19 of its 20 cells. test-usb-sysfs checks the absolute, cwd, fchdir, dirfd and openat-retry spellings.
There was a problem hiding this comment.
1 issue found across 8 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/runtime/usb-sysfs.c">
<violation number="1" location="src/runtime/usb-sysfs.c:2378">
P2: `/dev/bus/other/../usb/099/../001/001` hits this `FOREIGN` early return, so `099/..` is later folded unchecked and a valid `001/001` node is served instead of `ENOENT`. Continue validating the walk after the foreign climb so missing names reached under `/dev/bus/usb` still fail.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Re-trigger cubic
| if (!rest) { | ||
| int bus = 0; | ||
| usb_path_kind_t kind = usb_dev_kind(folded, &bus); | ||
| if (kind != USB_PATH_DEV_BUSNUM && kind != USB_PATH_DEV_ABSENT) |
There was a problem hiding this comment.
P2: /dev/bus/other/../usb/099/../001/001 hits this FOREIGN early return, so 099/.. is later folded unchecked and a valid 001/001 node is served instead of ENOENT. Continue validating the walk after the foreign climb so missing names reached under /dev/bus/usb still fail.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/runtime/usb-sysfs.c, line 2378:
<comment>`/dev/bus/other/../usb/099/../001/001` hits this `FOREIGN` early return, so `099/..` is later folded unchecked and a valid `001/001` node is served instead of `ENOENT`. Continue validating the walk after the foreign climb so missing names reached under `/dev/bus/usb` still fail.</comment>
<file context>
@@ -2345,23 +2355,31 @@ bool usb_sysfs_node_path(const char *guest_path, char *out, size_t outsz)
+ if (!rest) {
+ int bus = 0;
+ usb_path_kind_t kind = usb_dev_kind(folded, &bus);
+ if (kind != USB_PATH_DEV_BUSNUM && kind != USB_PATH_DEV_ABSENT)
+ return 0;
+ errno = ENOENT;
</file context>
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.
/dev/bus/usb/099/../001/001answers as the usbfs node and099/../../../nullfrom a/dev/bus/usbcwd reaches/dev/null, where Linux answersENOENTfor both, because the layer applies a..without checking that the name before it exists. On a sysroot with adev/bus/usb/099directory,/dev/bus/usb/099/../../other/freaches the backing's file the same way. Review raised the sysroot case on #439, which left this change for a separate PR.Reproduce with the fixture devices and a static aarch64 busybox:
On
mainthese printcharacter special fileandreached. With this change the first fails withNo such file or directoryand the second printsrefused, as Linux does.Tested on macOS 15.6.1 (24G90) with the 15.5 SDK on an Apple M1 (MacBookAir10,1).
make checkpasses 100 of 101 andmake test-matrix-elfuse-aarch64gives 299 passed, 1 failed and 10 skipped. Onmainand on this branch alike, the one failure in each istest-thread-churntiming out, and it passes when run alone.Summary by cubic
Fails
..after a missing/dev/bus/usbname withENOENT, matching Linux. Previously/dev/bus/usb/099/../001/001was served as the usbfs node and099/../../../nullfrom a/dev/bus/usbcwd reached/dev/null; on a sysroot with adev/bus/usb/099directory,099/../../other/freached the backing.path_translate_atnow returnsENOENTwhen..follows a name under/dev/bus/usbthat is not a served directory...after a name outside/dev/bus/usbis still applied unchecked, so/dev/bus/nosuch/../usb/001/001remains served.shadow-dotdotmatrix column andtest-usb-sysfscoverage for absolute, cwd, fchdir, dirfd, and openat-retry spellings.Written for commit db51cc5. Summary will update on new commits.