From: Peter Marko <peter.marko@siemens.com>
To: meta-virtualization@lists.yoctoproject.org
Cc: Peter Marko <peter.marko@siemens.com>
Subject: [meta-virtualization][wrynose][PATCH 2/2] crun: patch CVE-2026-47766
Date: Sun, 23 Aug 2026 12:03:29 +0200 [thread overview]
Message-ID: <20260823100330.3784951-2-peter.marko@siemens.com> (raw)
In-Reply-To: <20260823100330.3784951-1-peter.marko@siemens.com>
From: Peter Marko <peter.marko@siemens.com>
Pick patch per [1].
[1] https://security-tracker.debian.org/tracker/CVE-2026-47766
Signed-off-by: Peter Marko <peter.marko@siemens.com>
---
.../crun/crun/CVE-2026-47766.patch | 161 ++++++++++++++++++
recipes-containers/crun/crun_git.bb | 1 +
2 files changed, 162 insertions(+)
create mode 100644 recipes-containers/crun/crun/CVE-2026-47766.patch
diff --git a/recipes-containers/crun/crun/CVE-2026-47766.patch b/recipes-containers/crun/crun/CVE-2026-47766.patch
new file mode 100644
index 00000000..0a369b46
--- /dev/null
+++ b/recipes-containers/crun/crun/CVE-2026-47766.patch
@@ -0,0 +1,161 @@
+From c6f338ac2e26e216ab7820b91863a0b84e608097 Mon Sep 17 00:00:00 2001
+From: JUNYI LIU <moss80199.cs05@nycu.edu.tw>
+Date: Mon, 25 May 2026 22:45:06 +0800
+Subject: [PATCH] Do not follow rootfs /dev symlinks (CVE-2026-47766)
+
+Open rootfs /dev with safe_openat before creating default devices or handler-specific devices. This keeps rootfs-controlled /dev symlinks from redirecting device setup outside the container rootfs.
+
+Add a regression test covering a rootfs /dev symlink to an outside directory and verify that the outside target is not populated or replaced.
+
+Signed-off-by: JUNYI LIU <moss80199.cs05@nycu.edu.tw>
+
+CVE: CVE-2026-47766
+Upstream-Status: Backport [https://github.com/containers/crun/commit/c6f338ac2e26e216ab7820b91863a0b84e608097]
+Signed-off-by: Peter Marko <peter.marko@siemens.com>
+---
+ src/libcrun/handlers/krun.c | 4 +-
+ src/libcrun/linux.c | 4 +-
+ tests/test_devices.py | 84 +++++++++++++++++++++++++++++++++++++
+ 3 files changed, 88 insertions(+), 4 deletions(-)
+
+diff --git a/src/libcrun/handlers/krun.c b/src/libcrun/handlers/krun.c
+index 5e1f3e54..6e249a9b 100644
+--- a/src/libcrun/handlers/krun.c
++++ b/src/libcrun/handlers/krun.c
+@@ -609,9 +609,9 @@ libkrun_configure_container (void *cookie, enum handler_configure_phase phase,
+ }
+ }
+
+- devfd = openat (rootfsfd, "dev", O_PATH | O_DIRECTORY | O_CLOEXEC);
++ devfd = safe_openat (rootfsfd, rootfs, "dev", O_PATH | O_DIRECTORY | O_CLOEXEC, 0, err);
+ if (UNLIKELY (devfd < 0))
+- return crun_make_error (err, errno, "open /dev directory in `%s`", rootfs);
++ return devfd;
+
+ ret = check_running_in_user_namespace (err);
+ if (UNLIKELY (ret < 0))
+diff --git a/src/libcrun/linux.c b/src/libcrun/linux.c
+index 24569dec..fcb62dbf 100644
+--- a/src/libcrun/linux.c
++++ b/src/libcrun/linux.c
+@@ -1754,9 +1754,9 @@ create_missing_devs (libcrun_container_t *container, bool binds, libcrun_error_t
+ if (! def || ! def->linux)
+ return 0;
+
+- devfd = openat (get_private_data (container)->rootfsfd, "dev", O_CLOEXEC | O_PATH | O_DIRECTORY);
++ devfd = safe_openat (get_private_data (container)->rootfsfd, rootfs, "dev", O_CLOEXEC | O_PATH | O_DIRECTORY, 0, err);
+ if (UNLIKELY (devfd < 0))
+- return crun_make_error (err, errno, "open `/dev` directory in `%s`", rootfs);
++ return devfd;
+
+ for (i = 0; i < def->linux->devices_len; i++)
+ {
+diff --git a/tests/test_devices.py b/tests/test_devices.py
+index 1a973025..4f0a2bb6 100755
+--- a/tests/test_devices.py
++++ b/tests/test_devices.py
+@@ -18,6 +18,7 @@
+ import os
+ import subprocess
+ import shutil
++import json
+ from tests_utils import *
+
+ def test_mode_device():
+@@ -368,6 +369,88 @@ def test_mknod_char_device():
+ return -1
+ return 0
+
++def test_dev_symlink_does_not_populate_outside_rootfs():
++ if is_rootless():
++ return (77, "requires root privileges")
++
++ workdir = os.path.join(get_tests_root(), "dev-symlink")
++ bundle = os.path.join(workdir, "bundle")
++ rootfs = os.path.join(bundle, "rootfs")
++ outside_dev = os.path.join(workdir, "outside-dev")
++ runtime_root = os.path.join(workdir, "run")
++ shutil.rmtree(workdir, ignore_errors=True)
++ try:
++ os.makedirs(rootfs)
++ os.makedirs(outside_dev)
++ os.makedirs(runtime_root)
++ ptmx_marker = os.path.join(outside_dev, "ptmx")
++ with open(ptmx_marker, "w") as f:
++ f.write("outside marker\n")
++
++ os.symlink(outside_dev, os.path.join(rootfs, "dev"))
++ shutil.copy2(get_init_path(), os.path.join(rootfs, "init"))
++ os.chmod(os.path.join(rootfs, "init"), 0o755)
++
++ conf = {
++ "ociVersion": "1.0.2",
++ "process": {
++ "terminal": False,
++ "user": {"uid": 0, "gid": 0},
++ "args": ["/init", "true"],
++ "env": ["PATH=/bin"],
++ "cwd": "/",
++ },
++ "root": {
++ "path": "rootfs",
++ "readonly": True,
++ },
++ "mounts": [
++ {"destination": "/proc", "type": "proc", "source": "proc"},
++ ],
++ "linux": {
++ "namespaces": [
++ {"type": "mount"},
++ {"type": "pid"},
++ {"type": "ipc"},
++ {"type": "uts"},
++ ],
++ },
++ }
++ with open(os.path.join(bundle, "config.json"), "w") as f:
++ f.write(json.dumps(conf))
++
++ container_id = "test-dev-symlink"
++ crun = get_crun_path()
++
++ try:
++ subprocess.check_output([crun, "--root", runtime_root, "run", "-b", bundle, container_id],
++ stderr=subprocess.STDOUT)
++ logger.info("container unexpectedly started with rootfs /dev symlink")
++ return -1
++ except subprocess.CalledProcessError:
++ pass
++ finally:
++ subprocess.run([crun, "--root", runtime_root, "delete", "-f", container_id],
++ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
++
++ outside_entries = sorted(os.listdir(outside_dev))
++ if outside_entries != ["ptmx"]:
++ logger.info("rootfs /dev symlink target was populated outside rootfs: %s", outside_entries)
++ return -1
++
++ if os.path.islink(ptmx_marker):
++ logger.info("rootfs /dev symlink target ptmx marker was replaced with a symlink")
++ return -1
++
++ with open(ptmx_marker) as f:
++ if f.read() != "outside marker\n":
++ logger.info("rootfs /dev symlink target ptmx marker content changed")
++ return -1
++
++ return 0
++ finally:
++ shutil.rmtree(workdir, ignore_errors=True)
++
+ def test_allow_device_read_only():
+ if is_rootless():
+ return (77, "requires root privileges")
+@@ -425,6 +508,7 @@ def test_allow_device_read_only():
+ all_tests = {
+ "mknod-fifo-device": test_mknod_fifo_device,
+ "mknod-char-device": test_mknod_char_device,
++ "dev-symlink-does-not-populate-outside-rootfs": test_dev_symlink_does_not_populate_outside_rootfs,
+ "allow-device-read-only": test_allow_device_read_only,
+ "owner-device" : test_owner_device,
+ "deny-devices" : test_deny_devices,
diff --git a/recipes-containers/crun/crun_git.bb b/recipes-containers/crun/crun_git.bb
index e8d87484..809b6c01 100644
--- a/recipes-containers/crun/crun_git.bb
+++ b/recipes-containers/crun/crun_git.bb
@@ -18,6 +18,7 @@ SRC_URI = "git://github.com/containers/crun.git;branch=main;name=crun;protocol=h
file://0001-libocispec-correctly-parse-JSON-schema-references.patch;patchdir=libocispec \
file://0002-libocispec-fix-array-items-parsing.patch;patchdir=libocispec \
file://CVE-2026-30892.patch \
+ file://CVE-2026-47766.patch \
"
PV = "1.26.0+git"
next prev parent reply other threads:[~2026-08-23 10:04 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-23 10:03 [meta-virtualization][wrynose][PATCH 1/2] crun: patch CVE-2026-30892 Peter Marko
2026-08-23 10:03 ` Peter Marko [this message]
2026-09-01 14:57 ` [meta-virtualization][wrynose][PATCH 2/2] crun: patch CVE-2026-47766 Bruce Ashfield
2026-09-01 14:57 ` [meta-virtualization][wrynose][PATCH 1/2] crun: patch CVE-2026-30892 Bruce Ashfield
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260823100330.3784951-2-peter.marko@siemens.com \
--to=peter.marko@siemens.com \
--cc=meta-virtualization@lists.yoctoproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.