app-containers/runc: fix CVE-2023-27561

Cherry-pick patch for CVE-2023-27561.

BUG=b/272893990
TEST=presubmit, make integration
RELEASE_NOTE=Fixed CVE-2023-27561.

cos-patch: security-high
Change-Id: I58cb74c7d8d7003fff9c623480756b9aa746109d
Reviewed-on: https://cos-review.googlesource.com/c/cos/overlays/board-overlays/+/45631
Main-Branch-Verified: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Reviewed-by: Meena Shanmugam <meenashanmugam@google.com>
Tested-by: Cusky Presubmit Bot <presubmit@cos-infra-prod.iam.gserviceaccount.com>
Reviewed-on: https://cos-review.googlesource.com/c/cos/overlays/board-overlays/+/45668
diff --git a/project-lakitu/app-emulation/runc/files/1.1.4-fix-CVE-2023-27561.patch b/project-lakitu/app-emulation/runc/files/1.1.4-fix-CVE-2023-27561.patch
new file mode 100644
index 0000000..876602f
--- /dev/null
+++ b/project-lakitu/app-emulation/runc/files/1.1.4-fix-CVE-2023-27561.patch
@@ -0,0 +1,109 @@
+From 75a8f5acaabb024a1cbbd451b15f3d95d6e624e2 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 | 27 +++++++++++++++++++--------
+ tests/integration/mask.bats  | 19 +++++++++++++++++++
+ 2 files changed, 38 insertions(+), 8 deletions(-)
+
+diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go
+index f96268194754..140ad26e26fa 100644
+--- a/libcontainer/rootfs_linux.go
++++ b/libcontainer/rootfs_linux.go
+@@ -378,31 +378,42 @@ func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
+ 
+ func mountToRootfs(m *configs.Mount, c *mountConfig) error {
+ 	rootfs := c.root
+-	mountLabel := c.label
+-	dest, err := securejoin.SecureJoin(rootfs, m.Destination)
+-	if err != nil {
+-		return err
+-	}
+ 
++	// procfs and sysfs are special because we need to ensure they are actually
++	// mounted on a specific path in a container without any funny business.
+ 	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 err := os.MkdirAll(dest, 0o755); 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, "")
++	}
++
++	mountLabel := c.label
++	dest, err := securejoin.SecureJoin(rootfs, m.Destination)
++	if err != nil {
++		return err
++	}
++
++	switch m.Device {
+ 	case "mqueue":
+ 		if err := os.MkdirAll(dest, 0o755); err != nil {
+ 			return err
+diff --git a/tests/integration/mask.bats b/tests/integration/mask.bats
+index 272c879c6857..7730807f1bb6 100644
+--- a/tests/integration/mask.bats
++++ b/tests/integration/mask.bats
+@@ -75,3 +75,22 @@ function teardown() {
+ 	# so we merely check that it fails, and do not check the exact error
+ 	# message like for /proc above.
+ }
++
++@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.29.3
+
diff --git a/project-lakitu/app-emulation/runc/runc-1.0.3-r1.ebuild b/project-lakitu/app-emulation/runc/runc-1.0.3-r2.ebuild
similarity index 100%
rename from project-lakitu/app-emulation/runc/runc-1.0.3-r1.ebuild
rename to project-lakitu/app-emulation/runc/runc-1.0.3-r2.ebuild
diff --git a/project-lakitu/app-emulation/runc/runc-1.0.3.ebuild b/project-lakitu/app-emulation/runc/runc-1.0.3.ebuild
index 62a035f..9662021 100644
--- a/project-lakitu/app-emulation/runc/runc-1.0.3.ebuild
+++ b/project-lakitu/app-emulation/runc/runc-1.0.3.ebuild
@@ -42,6 +42,7 @@
 
 PATCHES="
 	${FILESDIR}/1.0.0-runc-do-not-set-inheritable-capabilities.patch
+	${FILESDIR}/1.1.4-fix-CVE-2023-27561.patch
 "
 
 src_compile() {