[meta-virtualization][scarthgap][PATCH] runc-opencontainers: fix CVE-2026-41579
"Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]> Wed, 15 Jul 2026 22:57:56 +0530
| Newsgroups | org.yoctoproject.lists.meta-virtualization |
|---|---|
| Message-ID | <[email protected]> |
From: Deepak Rathore <[email protected]> This patch applies a Scarthgap backport for CVE-2026-41579. The upstream release-1.3 fix commit is referenced in [1], and the public security advisory is referenced in [2]. The target release lacks the newer internal/pathrs helpers, so the embedded patch records the equivalent fd-based adaptation. [1] https://github.com/opencontainers/runc/commit/a8e53f2c6d6d25cb3dd643cc514f118aab44b097 [2] https://github.com/opencontainers/runc/security/advisories/GHSA-xjvp-4fhw-gc47 Signed-off-by: Deepak Rathore <[email protected]> --- .../runc/files/CVE-2026-41579.patch | 109 ++++++++++++++++++ .../runc/runc-opencontainers_git.bb | 1 + 2 files changed, 110 insertions(+) create mode 100644 recipes-containers/runc/files/CVE-2026-41579.patch diff --git a/recipes-containers/runc/files/CVE-2026-41579.patch b/recipes-containers/runc/files/CVE-2026-41579.patch new file mode 100644 index 00000000..0d30c942 --- /dev/null +++ b/recipes-containers/runc/files/CVE-2026-41579.patch @@ -0,0 +1,109 @@ +From 4662e4af4680996b7d9b7100b5970b75ee6d0048 Mon Sep 17 00:00:00 2001 +From: Deepak Rathore <[email protected]> +Date: Mon, 6 Jul 2026 00:44:51 -0700 +Subject: [PATCH] rootfs: make /dev initialisation code fd-based + +These code paths operate on host-visible paths before pivot_root(2), +so a malicious image with /dev as a symlink can make runc operate on +host paths while setting up /dev symlinks and /dev/ptmx. + +Use fd-relative unlinkat(2) and symlinkat(2) against a no-follow +opened rootfs/dev directory so the final /dev component cannot be a +symlink to a host directory. + +CVE: CVE-2026-41579 +Upstream-Status: Backport [https://github.com/opencontainers/runc/commit/a8e53f2c6d6d25cb3dd643cc514f118aab44b097] + +Backport Changes: +- Scarthgap runc 1.1.14 does not contain the internal/pathrs helpers + used by the upstream release-1.3 fix. +- Added a minimal openDevInRoot helper and used unlinkat/symlinkat + directly to keep the same fd-scoped security behavior. +- Omitted internal/pathrs changes because that package is absent from + release-1.1 and the CVE path only needs fixed /dev entry handling. + +Signed-off-by: Aleksa Sarai <[email protected]> +(cherry picked from commit a8e53f2c6d6d25cb3dd643cc514f118aab44b097) +Signed-off-by: Deepak Rathore <[email protected]> +--- + src/import/libcontainer/rootfs_linux.go | 45 ++++++++++++++++++++++++++---------- + 1 file changed, 33 insertions(+), 12 deletions(-) + +diff --git a/src/import/libcontainer/rootfs_linux.go b/src/import/libcontainer/rootfs_linux.go +index 78b6998c..b8f9b238 100644 +--- a/src/import/libcontainer/rootfs_linux.go ++++ b/src/import/libcontainer/rootfs_linux.go +@@ -658,25 +658,40 @@ func checkProcMount(rootfs, dest string, m *configs.Mount, source string) error + return fmt.Errorf("%q cannot be mounted because it is inside /proc", dest) + } + ++func openDevInRoot(rootfs string) (int, error) { ++ devPath := filepath.Join(rootfs, "dev") ++ devFd, err := unix.Open(devPath, unix.O_DIRECTORY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) ++ if err != nil { ++ return -1, &os.PathError{Op: "open", Path: devPath, Err: err} ++ } ++ return devFd, nil ++} ++ + func setupDevSymlinks(rootfs string) error { ++ devFd, err := openDevInRoot(rootfs) ++ if err != nil { ++ return err ++ } ++ defer unix.Close(devFd) //nolint: errcheck ++ + links := [][2]string{ +- {"/proc/self/fd", "/dev/fd"}, +- {"/proc/self/fd/0", "/dev/stdin"}, +- {"/proc/self/fd/1", "/dev/stdout"}, +- {"/proc/self/fd/2", "/dev/stderr"}, ++ {"/proc/self/fd", "fd"}, ++ {"/proc/self/fd/0", "stdin"}, ++ {"/proc/self/fd/1", "stdout"}, ++ {"/proc/self/fd/2", "stderr"}, + } + // kcore support can be toggled with CONFIG_PROC_KCORE; only create a symlink + // in /dev if it exists in /proc. + if _, err := os.Stat("/proc/kcore"); err == nil { +- links = append(links, [2]string{"/proc/kcore", "/dev/core"}) ++ links = append(links, [2]string{"/proc/kcore", "core"}) + } + for _, link := range links { + var ( + src = link[0] +- dst = filepath.Join(rootfs, link[1]) ++ dst = link[1] + ) +- if err := os.Symlink(src, dst); err != nil && !os.IsExist(err) { +- return err ++ if err := unix.Symlinkat(src, devFd, dst); err != nil && err != unix.EEXIST { ++ return &os.PathError{Op: "symlinkat", Path: filepath.Join(rootfs, "dev", dst), Err: err} + } + } + return nil +@@ -886,12 +901,18 @@ func setReadonly() error { + } + + func setupPtmx(config *configs.Config) error { +- ptmx := filepath.Join(config.Rootfs, "dev/ptmx") +- if err := os.Remove(ptmx); err != nil && !os.IsNotExist(err) { ++ devFd, err := openDevInRoot(config.Rootfs) ++ if err != nil { + return err + } +- if err := os.Symlink("pts/ptmx", ptmx); err != nil { +- return err ++ defer unix.Close(devFd) //nolint: errcheck ++ ++ ptmx := filepath.Join(config.Rootfs, "dev", "ptmx") ++ if err := unix.Unlinkat(devFd, "ptmx", 0); err != nil && err != unix.ENOENT { ++ return &os.PathError{Op: "unlinkat", Path: ptmx, Err: err} ++ } ++ if err := unix.Symlinkat("pts/ptmx", devFd, "ptmx"); err != nil { ++ return &os.PathError{Op: "symlinkat", Path: ptmx, Err: err} + } + return nil + } +-- +2.35.6 diff --git a/recipes-containers/runc/runc-opencontainers_git.bb b/recipes-containers/runc/runc-opencontainers_git.bb index 4c831502..8e3dbc8d 100644 --- a/recipes-containers/runc/runc-opencontainers_git.bb +++ b/recipes-containers/runc/runc-opencontainers_git.bb @@ -5,6 +5,7 @@ SRC_URI = " \ git://github.com/opencontainers/runc;branch=release-1.1;protocol=https \ file://0001-Makefile-respect-GOBUILDFLAGS-for-runc-and-remove-re.patch \ file://0001-Makefile-fix-typo-in-LDFLAGS_STATIC.patch \ + file://CVE-2026-41579.patch \ " RUNC_VERSION = "1.1.14" -- 2.35.6