!143 [sync] PR-140: runc:Prohibit /proc and /sys to be symlinks
From: @openeuler-sync-bot Reviewed-by: @Vanient, @duguhaotian Signed-off-by: @duguhaotian
This commit is contained in:
commit
a363af70c1
117
patch/0137-runc-Prohibit-proc-and-sys-to-be-symlinks.patch
Normal file
117
patch/0137-runc-Prohibit-proc-and-sys-to-be-symlinks.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From cfbeae219224f99be7c05c4a0e248a9f6931f941 Mon Sep 17 00:00:00 2001
|
||||
From: Kir Kolyshkin <kolyshkin@gmail.com>
|
||||
Date: Thu, 16 Mar 2023 14:35:50 -0700
|
||||
Subject: [PATCH] Prohibit /proc and /sys to be symlinks
|
||||
|
||||
Commit 3291d66b9844 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 0ca91f44f 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 <kolyshkin@gmail.com>
|
||||
(cherry picked from commit 0d72adf96dda1b687815bf89bb245b937a2f603c)
|
||||
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
|
||||
---
|
||||
libcontainer/rootfs_linux.go | 33 ++++++++++++++++++++-------------
|
||||
tests/integration/mask.bats | 19 +++++++++++++++++++
|
||||
2 files changed, 39 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
|
||||
index dc66d8a9..855bcdb0 100644
|
||||
--- a/libcontainer/rootfs_linux.go
|
||||
+++ b/libcontainer/rootfs_linux.go
|
||||
@@ -160,29 +160,25 @@ func mountCmd(cmd configs.Command) error {
|
||||
}
|
||||
|
||||
func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
|
||||
- var (
|
||||
- dest = m.Destination
|
||||
- err error
|
||||
- )
|
||||
- if !strings.HasPrefix(dest, rootfs) {
|
||||
- dest, err = securejoin.SecureJoin(rootfs, m.Destination)
|
||||
- if err != nil {
|
||||
- return err
|
||||
- }
|
||||
- }
|
||||
+ var err error
|
||||
|
||||
switch m.Device {
|
||||
case "proc", "sysfs":
|
||||
// If the destination already exists and is not a directory, we bail
|
||||
- // out This is to avoid mounting through a symlink or similar -- which
|
||||
+ // out. This is to avoid mounting through a symlink or similar -- which
|
||||
// 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 := filepath.Clean(m.Destination)
|
||||
+ if !strings.HasPrefix(dest, rootfs) {
|
||||
+ // Do not use securejoin as it resolves symlinks.
|
||||
+ dest = filepath.Join(rootfs, dest)
|
||||
+ }
|
||||
if fi, err := os.Lstat(dest); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
- } else if fi.Mode()&os.ModeDir == 0 {
|
||||
+ } else if !fi.IsDir() {
|
||||
return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device)
|
||||
}
|
||||
if strings.HasPrefix(m.Destination, "/proc/sys/") {
|
||||
@@ -191,8 +187,19 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
- // Selinux kernels do not support labeling of /proc or /sys
|
||||
+ // Selinux kernels do not support labeling of /proc or /sys.
|
||||
return mountPropagate(m, rootfs, "")
|
||||
+ }
|
||||
+
|
||||
+ var dest = m.Destination
|
||||
+ if !strings.HasPrefix(dest, rootfs) {
|
||||
+ dest, err = securejoin.SecureJoin(rootfs, m.Destination)
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ switch m.Device {
|
||||
case "mqueue":
|
||||
if err := os.MkdirAll(dest, 0755); err != nil {
|
||||
return err
|
||||
diff --git a/tests/integration/mask.bats b/tests/integration/mask.bats
|
||||
index 074b0f2e..64d53954 100644
|
||||
--- a/tests/integration/mask.bats
|
||||
+++ b/tests/integration/mask.bats
|
||||
@@ -61,3 +61,22 @@ function teardown() {
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "${output}" == *"Operation not permitted"* ]]
|
||||
}
|
||||
+
|
||||
+@test "mask paths [prohibit symlink /proc]" {
|
||||
+ ln -s /symlink rootfs/proc
|
||||
+ runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox
|
||||
+ [ "$status" -eq 1 ]
|
||||
+ [[ "${output}" == *"must be mounted on ordinary directory"* ]]
|
||||
+}
|
||||
+
|
||||
+@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 ]
|
||||
+ # On cgroup v1, this may fail before checking if /sys is a symlink,
|
||||
+ # so we merely check that it fails, and do not check the exact error
|
||||
+ # message like for /proc above.
|
||||
+}
|
||||
--
|
||||
2.33.0
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
Name: docker-runc
|
||||
Version: 1.0.0.rc3
|
||||
Release: 211
|
||||
Release: 212
|
||||
Summary: runc is a CLI tool for spawning and running containers according to the OCI specification.
|
||||
|
||||
License: ASL 2.0
|
||||
@ -41,6 +41,12 @@ install -p -m 755 runc $RPM_BUILD_ROOT/%{_bindir}/runc
|
||||
%{_bindir}/runc
|
||||
|
||||
%changelog
|
||||
* Tue Apr 4 2023 zhongjiawei<zhongjiawei1@huawei.com> - 1.0.0.rc3-212
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
- SUG:NA
|
||||
- DESC:Prohibit /proc and /sys to be symlinks
|
||||
|
||||
* Wed Mar 29 2023 zhongjiawei<zhongjiawei1@huawei.com> - 1.0.0.rc3-211
|
||||
- Type:bugfix
|
||||
- CVE:NA
|
||||
|
||||
@ -128,3 +128,4 @@
|
||||
0134-runc-fix-seccomp-add-rule-failed.patch
|
||||
0135-runc-libct-cg-fs-blkio-do-not-set-weight-0.patch
|
||||
0136-runc-run-resolve-tmpfs-mount-dest-in-container-scope.patch
|
||||
0137-runc-Prohibit-proc-and-sys-to-be-symlinks.patch
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user