-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Prohibit /proc and /sys to be symlinks #3773
Conversation
With the above comment in mind, I prefer this patch to #3756. |
libcontainer/rootfs_linux.go
Outdated
// has been a "fun" attack scenario in the past. | ||
// TODO: This won't be necessary once we switch to libpathrs and we can | ||
// stop all of these symlink-exchange attacks. | ||
dest := m.Destination |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to filepath.Clean()
before checking the prefix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dest := filepath.Clean("/"+m.Destination)
probably makes the most sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And once we'll finish it, it won't be necessary to prepend "/"
. So, I guess, bare filepath.Clean
is enough.
33124cc
to
72eeffd
Compare
OK, so I have to add this: --- a/tests/integration/mask.bats
+++ b/tests/integration/mask.bats
@@ -65,6 +65,9 @@ function teardown() {
}
@test "mask paths [prohibit symlink /sys]" {
+ # In rootless containers, /sys is a bind mount not a real sysfs.
+ requires root
+
ln -s /symlink rootfs/sys
runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
[ "$status" -eq 1 ] because in rootless containers /sys is not a sysfs mount but a bind mount, so the sysfs case is not working. I guess it's not a problem for rootless containers anyway, so relaxing the check is fine. |
Commit 3291d66 introduced a check for /proc and /sys, making sure the destination (dest) is a directory (and not e.g. a symlink). Later, a hunk from commit 0ca91f4 switched from using filepath.Join to SecureJoin for dest. As SecureJoin follows and resolves symlinks, the check whether dest is a symlink no longer works. To fix, do the check without/before using SecureJoin. Add integration tests to make sure we won't regress. Signed-off-by: Kir Kolyshkin <[email protected]>
Thinking about one more alternative, which is:
This way we'll remove the TOCTOU race and we don't even need openat2. WDYT @cyphar ? |
This might cause rootfs escape if any parent components of dest are symlinks. So, maybe, do
|
@kolyshkin I don't really like that idea. I would prefer if we just use this solution now and we can solve this (and the many other issues we have) with libpathrs in the future. You can have container configs that mount sysfs and procfs in places other than |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Probably not for this PR, but I noticed that we're inconsistent in handling "where to return". It looks like all switch cases have a runc/libcontainer/rootfs_linux.go Lines 475 to 478 in efad7a3
Perhaps we should move that one inside the runc/libcontainer/rootfs_linux.go Line 436 in efad7a3
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@AkihiroSuda PTAL
I guess this one needs to be cherry-picked into the release-1.1 branch? |
opened #3785 |
Makes sense, opened #3787 |
Commit 3291d66 introduced a check for /proc and /sys, making sure the destination (dest) is a directory (and not e.g. a symlink).
Later, a hunk from commit 0ca91f4 switched from using
filepath.Join
toSecureJoin
fordest
. AsSecureJoin
follows and resolves symlinks, the check whether dest is a symlink no longer works.To fix, do the check without/before using SecureJoin.
Add integration tests (stolen from #3756) to make sure we won't regress.
This is an alternative to #3756.
Fixes: #3751
Fixes: CVE-2023-27561