Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

open: make OpenInRoot errors match a simple openat2 #17

Merged
merged 5 commits into from
Jul 23, 2024

Conversation

cyphar
Copy link
Owner

@cyphar cyphar commented Jul 23, 2024

Because we use partialOpenInRoot as the backend implementation of
OpenInRoot (which didn't return error information when a partial lookup
succeeded), we would map all non-complete errors as ENOENT. This meant
that for non-directories you didn't get ENOTDIR, which is what you'd
get from a basic openat2(RESOLVE_IN_ROOT) using the path.

While we could map the error in OpenInRoot to -ENOTDIR in simple cases,
in dangling symlink cases OpenInRoot doesn't know what source error
stopped the iteration. So we have to change the partialOpenInRoot API to
return an error when a partial open is done, and all of the callers need
to be updated to handle that. Since partialOpenInRoot is an internal
API, this slightly unconventional interface (where a non-nil error is
paired with actual value information) is not that bad.

This also lets us remove a bit of duplication from partialOpenInRoot
when handling a non-directory component, which I think makes things much
nicer.

Signed-off-by: Aleksa Sarai [email protected]

@cyphar cyphar force-pushed the fix-openinroot-enotdir branch 3 times, most recently from 0b5d3f0 to 98ebf77 Compare July 23, 2024 05:16
It makes more sense to make the open("/proc") unsafe fallback more like
a hasNewMountApi() failure.

Signed-off-by: Aleksa Sarai <[email protected]>
renameat2(fd, ".", ...) is not allowed, and so our rename-swap tests
where we swap the root itself would silently do nothing (this explains
why the racing tests would always succeed).

The tests still pass, so our logic was correct, we just didn't exercise
that particular check properly.

Fixes: ac32743 ("tests: add racing tests for partialLokupInRoot and MkdirAllHandle")
Signed-off-by: Aleksa Sarai <[email protected]>
When switching away from O_PATH, we forgot to close the O_PATH handle
when replacing it with the non-O_DIRECTORY handle.

Fixes: ebb9f1f ("mkdirall: switch away from O_PATH for mkdir loop")
Signed-off-by: Aleksa Sarai <[email protected]>
Because we use partialOpenInRoot as the backend implementation of
OpenInRoot (which didn't return error information when a partial lookup
succeeded), we would map all non-complete errors as ENOENT. This meant
that for non-directories you didn't get ENOTDIR, which is what you'd
get from a basic openat2(RESOLVE_IN_ROOT) using the path.

While we could map the error in OpenInRoot to -ENOTDIR in simple cases,
in dangling symlink cases OpenInRoot doesn't know what source error
stopped the iteration. So we have to change the partialOpenInRoot API to
return an error when a partial open is done, and all of the callers need
to be updated to handle that. Since partialOpenInRoot is an internal
API, this slightly unconventional interface (where a non-nil error is
paired with actual value information) is not that bad.

This also lets us remove a bit of duplication from partialOpenInRoot
when handling a non-directory component, which I think makes things much
nicer.

Signed-off-by: Aleksa Sarai <[email protected]>
For openat2 this means we can just one-shot the lookup (making our
lookups faster) and for partialLookupInRoot we can not bother with the
symlink stack (and simplify the error handling case when doing a
complete lookup).

Signed-off-by: Aleksa Sarai <[email protected]>
@cyphar cyphar merged commit edab538 into main Jul 23, 2024
11 checks passed
@cyphar cyphar deleted the fix-openinroot-enotdir branch July 23, 2024 10:19
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.

None yet

1 participant