diff --git a/.gitignore b/.gitignore index d42edf0..81ab3db 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/v1.2.5.tar.gz +SOURCES/v1.3.0.tar.gz diff --git a/.runc.metadata b/.runc.metadata index d8eb787..6ee8356 100644 --- a/.runc.metadata +++ b/.runc.metadata @@ -1 +1 @@ -35e5289a5b1ac1a12a35c3475b7d0bee2232ef39 SOURCES/v1.2.5.tar.gz +0ea2488912e9ae562782f5980971f7fb0d73df38 SOURCES/v1.3.0.tar.gz diff --git a/SOURCES/0001-1.2-openat2-improve-resilience-on-busy-systems.patch b/SOURCES/0001-1.3-openat2-improve-resilience-on-busy-systems.patch similarity index 95% rename from SOURCES/0001-1.2-openat2-improve-resilience-on-busy-systems.patch rename to SOURCES/0001-1.3-openat2-improve-resilience-on-busy-systems.patch index ce491cf..cea6d79 100644 --- a/SOURCES/0001-1.2-openat2-improve-resilience-on-busy-systems.patch +++ b/SOURCES/0001-1.3-openat2-improve-resilience-on-busy-systems.patch @@ -1,7 +1,7 @@ -From 4ad5d01eeda006ba9ae067cbf999a77fe096fe00 Mon Sep 17 00:00:00 2001 +From 2df42d4db6bc57ee914fa9cc4455ad3b8daff1d9 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sat, 1 Nov 2025 17:21:36 +1100 -Subject: [PATCH 1/2] [1.2] openat2: improve resilience on busy systems +Subject: [PATCH 1/2] [1.3] openat2: improve resilience on busy systems Previously, we would see a ~3% failure rate when starting containers with mounts that contain ".." (which can trigger -EAGAIN). To counteract @@ -41,26 +41,26 @@ Signed-off-by: Kir Kolyshkin rename vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/internal/{errors.go => errors_linux.go} (70%) diff --git a/go.mod b/go.mod -index 5f00a576..90fa2e5b 100644 +index f2deafc3..a551a4ec 100644 --- a/go.mod +++ b/go.mod -@@ -12,7 +12,7 @@ require ( - github.com/cilium/ebpf v0.16.0 +@@ -6,7 +6,7 @@ require ( + github.com/checkpoint-restore/go-criu/v6 v6.3.0 github.com/containerd/console v1.0.5 github.com/coreos/go-systemd/v22 v22.5.0 - github.com/cyphar/filepath-securejoin v0.5.0 + github.com/cyphar/filepath-securejoin v0.5.1 github.com/docker/go-units v0.5.0 github.com/godbus/dbus/v5 v5.1.0 - github.com/moby/sys/mountinfo v0.7.1 + github.com/moby/sys/capability v0.4.0 diff --git a/go.sum b/go.sum -index 1f930ce4..049597b6 100644 +index ba395bf0..fb357b43 100644 --- a/go.sum +++ b/go.sum -@@ -9,8 +9,8 @@ github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8 - github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= - github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +@@ -10,8 +10,8 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= + github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= + github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw= -github.com/cyphar/filepath-securejoin v0.5.0/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48= @@ -399,11 +399,11 @@ index 23053083..3e937fe3 100644 - return nil, &os.PathError{Op: "openat2", Path: fullPath, Err: internal.ErrPossibleAttack} } diff --git a/vendor/modules.txt b/vendor/modules.txt -index 4e7e0ef8..64524598 100644 +index f22001c8..18276b61 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt -@@ -25,7 +25,7 @@ github.com/coreos/go-systemd/v22/dbus - # github.com/cpuguy83/go-md2man/v2 v2.0.2 +@@ -27,7 +27,7 @@ github.com/coreos/go-systemd/v22/dbus + # github.com/cpuguy83/go-md2man/v2 v2.0.5 ## explicit; go 1.11 github.com/cpuguy83/go-md2man/v2/md2man -# github.com/cyphar/filepath-securejoin v0.5.0 diff --git a/SOURCES/0001-1.2.5-1.el9-CVEs-mega-patch.patch b/SOURCES/0001-1.3.0-CVEs-mega-patch.patch similarity index 96% rename from SOURCES/0001-1.2.5-1.el9-CVEs-mega-patch.patch rename to SOURCES/0001-1.3.0-CVEs-mega-patch.patch index 28701ea..f11b462 100644 --- a/SOURCES/0001-1.2.5-1.el9-CVEs-mega-patch.patch +++ b/SOURCES/0001-1.3.0-CVEs-mega-patch.patch @@ -1,9 +1,9 @@ -From b6cebe30cbb1d41a357087ec8fc6c01ac4e6d317 Mon Sep 17 00:00:00 2001 +From 7a76bd855ca135d36ab8b4e41e101deae5bee8a1 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Tue, 30 Sep 2025 23:04:02 +1000 -Subject: [PATCH] [1.2.5-1.el9] CVEs mega patch +Subject: [PATCH] 1.3.0 CVEs mega patch -> This is a combination of 27 commits. +> This is a combination of 28 commits. > This is the 1st commit message: internal: linux: add package doc-comment @@ -238,6 +238,27 @@ Signed-off-by: Aleksa Sarai > This is the commit message #15: +ci: add lint to forbid the usage of os.Create + +os.Create is shorthand for open(O_CREAT|O_TRUNC) *without* O_EXCL, which +is incredibly unsafe for us to do when interacting with a container +rootfs (especially before pivot_root) as an attacker could swap the +target path with a symlink that points to the host filesystem, causing +us to delete the contents of or create host files. + +We did have a similar bug in CVE-2024-45310, but in that case we +(luckily) didn't have O_TRUNC set which avoided the worst possible case. +However, os.Create does set O_TRUNC and we were using it in scenarios +that may have been exploitable. + +Because of how easy it us for us to accidentally introduce this kind of +bug, we should simply not allow the usage of os.Create in our entire +codebase. + +Signed-off-by: Aleksa Sarai + +> This is the commit message #16: + apparmor: use safe procfs API for labels EnsureProcHandle only protects us against a tmpfs mount, but the risk of @@ -248,7 +269,7 @@ switch to it. Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881 Signed-off-by: Aleksa Sarai -> This is the commit message #16: +> This is the commit message #17: utils: use safe procfs for /proc/self/fd loop code @@ -257,7 +278,7 @@ paves the way for us to remove utils.ProcThreadSelf. Signed-off-by: Aleksa Sarai -> This is the commit message #17: +> This is the commit message #18: utils: remove unneeded EnsureProcHandle @@ -268,7 +289,7 @@ simplistic filesystem type check. Signed-off-by: Aleksa Sarai -> This is the commit message #18: +> This is the commit message #19: init: write sysctls using safe procfs API @@ -280,25 +301,25 @@ writes. Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881 Signed-off-by: Aleksa Sarai -> This is the commit message #19: +> This is the commit message #20: init: use securejoin for /proc/self/setgroups Signed-off-by: Aleksa Sarai -> This is the commit message #20: +> This is the commit message #21: libct/system: use securejoin for /proc/$pid/stat Signed-off-by: Aleksa Sarai -> This is the commit message #21: +> This is the commit message #22: libct: align param type for mountCgroupV1/V2 functions Signed-off-by: lifubang -> This is the commit message #22: +> This is the commit message #23: criu: improve prepareCriuRestoreMounts @@ -312,8 +333,10 @@ This commit is best reviewed with --ignore-all-space or similar. Signed-off-by: Kir Kolyshkin (cherry picked from commit 0c93d41c65b6a1055e945d1d3e56943b07b8405b) Signed-off-by: Kir Kolyshkin +(cherry picked from commit 017d6b693f9a8bfc64f9ba2afa9526b47e03c871) +Signed-off-by: Kir Kolyshkin -> This is the commit message #23: +> This is the commit message #24: criu: ignore cgroup early in prepareCriuRestoreMounts @@ -323,8 +346,10 @@ saving some time on unnecessary operations. Signed-off-by: Kir Kolyshkin (cherry picked from commit b8aa5481db42b5222b1725e5af939bec829937c5) Signed-off-by: Kir Kolyshkin +(cherry picked from commit a97c49f96ed7d18ae721da86661d92fc30d522ee) +Signed-off-by: Kir Kolyshkin -> This is the commit message #24: +> This is the commit message #25: criu: inline makeCriuRestoreMountpoints @@ -334,8 +359,10 @@ place, it does not make sense to have it as a separate function. Signed-off-by: Kir Kolyshkin (cherry picked from commit f91fbd34d9e819a833c7da00c6c88f5371a82ac5) Signed-off-by: Kir Kolyshkin +(cherry picked from commit 69a3439c31aabeb4e86c6c584736132863707b40) +Signed-off-by: Kir Kolyshkin -> This is the commit message #25: +> This is the commit message #26: criu: simplify isOnTmpfs check in prepareCriuRestoreMounts @@ -346,8 +373,10 @@ mounts directly. This simplifies the code and improves readability. Signed-off-by: Kir Kolyshkin (cherry picked from commit ce3cd4234c9cd90f8109a33ab86f3456c2edf947) Signed-off-by: Kir Kolyshkin +(cherry picked from commit 02c412828817665cf008a40c5382486d8f0b7ce5) +Signed-off-by: Kir Kolyshkin -> This is the commit message #26: +> This is the commit message #27: rootfs: switch to fd-based handling of mountpoint targets @@ -390,7 +419,7 @@ Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881 Co-developed-by: lifubang Signed-off-by: Aleksa Sarai -> This is the commit message #27: +> This is the commit message #28: selinux: use safe procfs API for labels @@ -411,8 +440,8 @@ disallows "replace" directives. Fixes: GHSA-cgrx-mc8f-2prm CVE-2025-52881 Signed-off-by: Aleksa Sarai -Signed-off-by: Kir Kolyshkin --- + .golangci.yml | 15 + go.mod | 11 +- go.sum | 10 +- internal/linux/doc.go | 3 + @@ -461,8 +490,8 @@ Signed-off-by: Kir Kolyshkin .../selinux/pkg/pwalkdir/pwalkdir_test.go | 239 +++ libcontainer/apparmor/apparmor_linux.go | 13 +- libcontainer/console_linux.go | 163 +- - libcontainer/criu_linux.go | 103 +- - libcontainer/dmz/cloned_binary_linux.go | 3 +- + libcontainer/criu_linux.go | 105 +- + libcontainer/exeseal/cloned_binary_linux.go | 3 +- libcontainer/init_linux.go | 27 +- libcontainer/integration/exec_test.go | 15 +- libcontainer/rootfs_linux.go | 419 +++-- @@ -528,16 +557,13 @@ Signed-off-by: Kir Kolyshkin .../filepath-securejoin/procfs_linux.go | 452 ------ .../cyphar/filepath-securejoin/vfs.go | 2 + .../selinux/go-selinux/label/label.go | 67 - - .../selinux/go-selinux/label/label_linux.go | 22 +- - .../selinux/go-selinux/label/label_stub.go | 20 +- + .../selinux/go-selinux/label/label_linux.go | 17 +- + .../selinux/go-selinux/label/label_stub.go | 6 - .../selinux/go-selinux/selinux.go | 26 +- - .../selinux/go-selinux/selinux_linux.go | 322 ++-- - .../selinux/go-selinux/selinux_stub.go | 52 +- - .../selinux/go-selinux/xattrs_linux.go | 4 +- - .../selinux/pkg/pwalkdir/README.md | 6 +- - .../selinux/pkg/pwalkdir/pwalkdir.go | 7 + + .../selinux/go-selinux/selinux_linux.go | 311 ++-- + .../selinux/go-selinux/selinux_stub.go | 8 +- vendor/modules.txt | 17 +- - 124 files changed, 9452 insertions(+), 1571 deletions(-) + 122 files changed, 9419 insertions(+), 1530 deletions(-) create mode 100644 internal/linux/doc.go create mode 100644 internal/linux/linux.go create mode 100644 internal/pathrs/doc.go @@ -621,14 +647,47 @@ Signed-off-by: Kir Kolyshkin create mode 100644 vendor/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs/procfs_linux.go delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/procfs_linux.go +diff --git a/.golangci.yml b/.golangci.yml +index 954a2bc0..1a802316 100644 +--- a/.golangci.yml ++++ b/.golangci.yml +@@ -11,6 +11,7 @@ formatters: + linters: + enable: + - errorlint ++ - forbidigo + - unconvert + - unparam + settings: +@@ -24,6 +25,20 @@ linters: + - -ST1003 # https://staticcheck.dev/docs/checks/#ST1003 Poorly chosen identifier. + - -ST1005 # https://staticcheck.dev/docs/checks/#ST1005 Incorrectly formatted error string. + - -QF1008 # https://staticcheck.dev/docs/checks/#QF1008 Omit embedded fields from selector expression. ++ forbidigo: ++ forbid: ++ # os.Create implies O_TRUNC without O_CREAT|O_EXCL, which can lead to ++ # an even more severe attacks than CVE-2024-45310, where host files ++ # could be wiped. Always use O_EXCL or otherwise ensure we are not ++ # going to be tricked into overwriting host files. ++ - pattern: ^os\.Create$ ++ pkg: ^os$ ++ analyze-types: true + exclusions: ++ rules: ++ # forbidigo lints are only relevant for main code. ++ - path: '(.+)_test\.go' ++ linters: ++ - forbidigo + presets: + - std-error-handling diff --git a/go.mod b/go.mod -index 8281d740..5f00a576 100644 +index c0b146b6..f2deafc3 100644 --- a/go.mod +++ b/go.mod -@@ -10,9 +10,9 @@ toolchain go1.22.4 +@@ -4,9 +4,9 @@ go 1.23.0 + require ( github.com/checkpoint-restore/go-criu/v6 v6.3.0 - github.com/cilium/ebpf v0.16.0 - github.com/containerd/console v1.0.4 + github.com/containerd/console v1.0.5 github.com/coreos/go-systemd/v22 v22.5.0 @@ -636,19 +695,19 @@ index 8281d740..5f00a576 100644 + github.com/cyphar/filepath-securejoin v0.5.0 github.com/docker/go-units v0.5.0 github.com/godbus/dbus/v5 v5.1.0 - github.com/moby/sys/mountinfo v0.7.1 -@@ -20,7 +20,7 @@ require ( - github.com/moby/sys/userns v0.1.0 + github.com/moby/sys/capability v0.4.0 +@@ -16,7 +16,7 @@ require ( github.com/mrunalp/fileutils v0.5.1 - github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95 -- github.com/opencontainers/selinux v1.11.0 + github.com/opencontainers/cgroups v0.0.1 + github.com/opencontainers/runtime-spec v1.2.1 +- github.com/opencontainers/selinux v1.11.1 + github.com/opencontainers/selinux v1.12.0 github.com/seccomp/libseccomp-golang v0.10.0 github.com/sirupsen/logrus v1.9.3 - github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 -@@ -37,3 +37,8 @@ require ( - github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df // indirect - golang.org/x/exp v0.0.0-20230224173230-c95f2b4c22f2 // indirect + github.com/urfave/cli v1.22.16 +@@ -32,3 +32,8 @@ require ( + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/vishvananda/netns v0.0.4 // indirect ) + +// FIXME: This is only intended as a short-term solution to include a patch for @@ -656,21 +715,22 @@ index 8281d740..5f00a576 100644 +// should be removed as soon as possible after the embargo is lifted. +replace github.com/opencontainers/selinux => ./internal/third_party/selinux diff --git a/go.sum b/go.sum -index a6d81357..1f930ce4 100644 +index 1503380c..ba395bf0 100644 --- a/go.sum +++ b/go.sum -@@ -3,14 +3,14 @@ github.com/checkpoint-restore/go-criu/v6 v6.3.0 h1:mIdrSO2cPNWQY1truPg6uHLXyKHk3 +@@ -3,15 +3,15 @@ github.com/checkpoint-restore/go-criu/v6 v6.3.0 h1:mIdrSO2cPNWQY1truPg6uHLXyKHk3 github.com/checkpoint-restore/go-criu/v6 v6.3.0/go.mod h1:rrRTN/uSwY2X+BPRl/gkulo9gsKOSAeVp9/K2tv7xZI= - github.com/cilium/ebpf v0.16.0 h1:+BiEnHL6Z7lXnlGUsXQPPAE7+kenAd4ES8MQ5min0Ok= - github.com/cilium/ebpf v0.16.0/go.mod h1:L7u2Blt2jMM/vLAVgjxluxtBKlz3/GWjB0dMOEngfwE= + github.com/cilium/ebpf v0.17.3 h1:FnP4r16PWYSE4ux6zN+//jMcW4nMVRvuTLVTvCjyyjg= + github.com/cilium/ebpf v0.17.3/go.mod h1:G5EDHij8yiLzaqn0WjyfJHvRa+3aDlReIaLVRMvOyJk= -github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= -github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/containerd/console v1.0.5 h1:R0ymNeydRqH2DmakFNdmjR2k0t7UPuiOV/N/27/qqsc= +github.com/containerd/console v1.0.5/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= - github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= + github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= + github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= -github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/cyphar/filepath-securejoin v0.5.0 h1:hIAhkRBMQ8nIeuVwcAoymp7MY4oherZdAxD+m0u9zaw= @@ -678,12 +738,12 @@ index a6d81357..1f930ce4 100644 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -@@ -48,8 +48,6 @@ github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm - github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= - github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95 h1:Ghl8Z3l+yPQUDSxAp7Kg7fJLRNNXjOsR6ooDcca7PjU= - github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= --github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= --github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +@@ -53,8 +53,6 @@ github.com/opencontainers/cgroups v0.0.1 h1:MXjMkkFpKv6kpuirUa4USFBas573sSAY082B + github.com/opencontainers/cgroups v0.0.1/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs= + github.com/opencontainers/runtime-spec v1.2.1 h1:S4k4ryNgEpxW1dzyqffOmhI1BHYcjzU8lpJfSlR0xww= + github.com/opencontainers/runtime-spec v1.2.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +-github.com/opencontainers/selinux v1.11.1 h1:nHFvthhM0qY8/m+vfhJylliSshm8G1jJ2jDMcgULaH8= +-github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= @@ -6481,10 +6541,10 @@ index e506853e..c93151bc 100644 return nil } diff --git a/libcontainer/criu_linux.go b/libcontainer/criu_linux.go -index 4c6ae714..18d7b906 100644 +index 8cd8fa5a..53a0202a 100644 --- a/libcontainer/criu_linux.go +++ b/libcontainer/criu_linux.go -@@ -519,34 +519,9 @@ func (c *Container) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) { +@@ -523,34 +523,9 @@ func (c *Container) restoreNetwork(req *criurpc.CriuReq, criuOpts *CriuOpts) { } } @@ -6522,7 +6582,7 @@ index 4c6ae714..18d7b906 100644 return true } } -@@ -560,17 +535,6 @@ func isPathInPrefixList(path string, prefix []string) bool { +@@ -564,17 +539,6 @@ func isPathInPrefixList(path string, prefix []string) bool { // This function also creates missing mountpoints as long as they // are not on top of a tmpfs, as CRIU will restore tmpfs content anyway. func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error { @@ -6540,7 +6600,7 @@ index 4c6ae714..18d7b906 100644 umounts := []string{} defer func() { for _, u := range umounts { -@@ -586,28 +550,51 @@ func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error { +@@ -590,28 +554,51 @@ func (c *Container) prepareCriuRestoreMounts(mounts []*configs.Mount) error { }) } }() @@ -6611,10 +6671,19 @@ index 4c6ae714..18d7b906 100644 } } return nil -diff --git a/libcontainer/dmz/cloned_binary_linux.go b/libcontainer/dmz/cloned_binary_linux.go -index 1c034e4e..9d392760 100644 ---- a/libcontainer/dmz/cloned_binary_linux.go -+++ b/libcontainer/dmz/cloned_binary_linux.go +@@ -1101,7 +1088,7 @@ func (c *Container) criuNotifications(resp *criurpc.CriuResp, process *Process, + logrus.Debugf("notify: %s\n", script) + switch script { + case "post-dump": +- f, err := os.Create(filepath.Join(c.stateDir, "checkpoint")) ++ f, err := os.Create(filepath.Join(c.stateDir, "checkpoint")) //nolint:forbidigo // this is a host-side operation in a runc-controlled directory + if err != nil { + return err + } +diff --git a/libcontainer/exeseal/cloned_binary_linux.go b/libcontainer/exeseal/cloned_binary_linux.go +index 3bafc96a..4d4d0dc0 100644 +--- a/libcontainer/exeseal/cloned_binary_linux.go ++++ b/libcontainer/exeseal/cloned_binary_linux.go @@ -10,6 +10,7 @@ import ( "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -6623,7 +6692,7 @@ index 1c034e4e..9d392760 100644 "github.com/opencontainers/runc/libcontainer/system" ) -@@ -67,7 +68,7 @@ func sealFile(f **os.File) error { +@@ -71,7 +72,7 @@ func sealFile(f **os.File) error { // When sealing an O_TMPFILE-style descriptor we need to // re-open the path as O_PATH to clear the existing write // handle we have. @@ -6633,7 +6702,7 @@ index 1c034e4e..9d392760 100644 return fmt.Errorf("reopen tmpfile: %w", err) } diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go -index eddbfba6..ee402095 100644 +index b6bcddc1..40529200 100644 --- a/libcontainer/init_linux.go +++ b/libcontainer/init_linux.go @@ -5,6 +5,7 @@ import ( @@ -6644,15 +6713,15 @@ index eddbfba6..ee402095 100644 "net" "os" "path/filepath" -@@ -21,6 +22,7 @@ import ( - "github.com/vishvananda/netlink" +@@ -20,6 +21,7 @@ import ( "golang.org/x/sys/unix" + "github.com/opencontainers/cgroups" + "github.com/opencontainers/runc/internal/pathrs" "github.com/opencontainers/runc/libcontainer/capabilities" - "github.com/opencontainers/runc/libcontainer/cgroups" "github.com/opencontainers/runc/libcontainer/configs" -@@ -379,12 +381,13 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error { + "github.com/opencontainers/runc/libcontainer/system" +@@ -376,12 +378,13 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error { // the UID owner of the console to be the user the process will run as (so // they can actually control their console). @@ -6667,7 +6736,7 @@ index eddbfba6..ee402095 100644 if config.ConsoleHeight != 0 && config.ConsoleWidth != 0 { err = pty.Resize(console.WinSize{ -@@ -398,7 +401,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error { +@@ -395,7 +398,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error { // Mount the console inside our rootfs. if mount { @@ -6676,7 +6745,7 @@ index eddbfba6..ee402095 100644 return err } } -@@ -409,7 +412,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error { +@@ -406,7 +409,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error { runtime.KeepAlive(pty) // Now, dup over all the things. @@ -6685,7 +6754,7 @@ index eddbfba6..ee402095 100644 } // syncParentReady sends to the given pipe a JSON payload which indicates that -@@ -511,7 +514,12 @@ func setupUser(config *initConfig) error { +@@ -468,7 +471,12 @@ func setupUser(config *initConfig) error { // We don't need to use /proc/thread-self here because setgroups is a // per-userns file and thus is global to all threads in a thread-group. // This lets us avoid having to do runtime.LockOSThread. @@ -6699,10 +6768,10 @@ index eddbfba6..ee402095 100644 if err != nil && !os.IsNotExist(err) { return err } -@@ -555,19 +563,16 @@ func setupUser(config *initConfig) error { +@@ -504,19 +512,16 @@ func setupUser(config *initConfig) error { // The ownership needs to match because it is created outside of the container and needs to be // localized. - func fixStdioPermissions(u *user.ExecUser) error { + func fixStdioPermissions(uid int) error { - var null unix.Stat_t - if err := unix.Stat("/dev/null", &null); err != nil { - return &os.PathError{Op: "stat", Path: "/dev/null", Err: err} @@ -6715,34 +6784,32 @@ index eddbfba6..ee402095 100644 - // Skip chown if uid is already the one we want or any of the STDIO descriptors - // were redirected to /dev/null. -- if int(s.Uid) == u.Uid || s.Rdev == null.Rdev { +- if int(s.Uid) == uid || s.Rdev == null.Rdev { + // Skip chown if: + // - uid is already the one we want, or + // - fd is opened to /dev/null. -+ if int(s.Uid) == u.Uid || isDevNull(&s) { ++ if int(s.Uid) == uid || isDevNull(&s) { continue } diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go -index e8a2dc53..c0fbd101 100644 +index f18dd50f..22804776 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go -@@ -14,12 +14,13 @@ import ( - "syscall" - "testing" +@@ -16,10 +16,11 @@ import ( + "github.com/opencontainers/cgroups" + "github.com/opencontainers/cgroups/systemd" + "github.com/opencontainers/runc/internal/linux" + "github.com/opencontainers/runc/internal/pathrs" "github.com/opencontainers/runc/libcontainer" - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/internal/userns" - "github.com/opencontainers/runc/libcontainer/utils" "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" -@@ -1695,11 +1696,9 @@ func TestFdLeaksSystemd(t *testing.T) { +@@ -1693,11 +1694,9 @@ func TestFdLeaksSystemd(t *testing.T) { } func fdList(t *testing.T) []string { @@ -6756,7 +6823,7 @@ index e8a2dc53..c0fbd101 100644 defer fdDir.Close() fds, err := fdDir.Readdirnames(-1) -@@ -1738,8 +1737,10 @@ func testFdLeaks(t *testing.T, systemd bool) { +@@ -1736,8 +1735,10 @@ func testFdLeaks(t *testing.T, systemd bool) { count := 0 @@ -6768,7 +6835,7 @@ index e8a2dc53..c0fbd101 100644 next_fd: for _, fd1 := range fds1 { -@@ -1748,7 +1749,7 @@ next_fd: +@@ -1746,7 +1747,7 @@ next_fd: continue next_fd } } @@ -6778,7 +6845,7 @@ index e8a2dc53..c0fbd101 100644 if ex == dst { continue next_fd diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go -index f7cd95dd..377642c9 100644 +index 4ecb3d45..d85e7321 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -5,14 +5,15 @@ import ( @@ -6798,15 +6865,15 @@ index f7cd95dd..377642c9 100644 "github.com/moby/sys/mountinfo" "github.com/moby/sys/userns" "github.com/mrunalp/fileutils" -@@ -21,6 +22,8 @@ import ( - "github.com/sirupsen/logrus" - "golang.org/x/sys/unix" - +@@ -24,6 +25,8 @@ import ( + "github.com/opencontainers/cgroups" + devices "github.com/opencontainers/cgroups/devices/config" + "github.com/opencontainers/cgroups/fs2" + "github.com/opencontainers/runc/internal/pathrs" + "github.com/opencontainers/runc/internal/sys" - "github.com/opencontainers/runc/libcontainer/cgroups" - "github.com/opencontainers/runc/libcontainer/cgroups/fs2" "github.com/opencontainers/runc/libcontainer/configs" + "github.com/opencontainers/runc/libcontainer/utils" + ) @@ -43,6 +46,7 @@ type mountConfig struct { type mountEntry struct { *configs.Mount @@ -6815,7 +6882,7 @@ index f7cd95dd..377642c9 100644 } // srcName is only meant for error messages, it returns a "friendly" name. -@@ -281,8 +285,8 @@ func cleanupTmp(tmpdir string) { +@@ -282,8 +286,8 @@ func cleanupTmp(tmpdir string) { _ = os.RemoveAll(tmpdir) } @@ -6826,7 +6893,7 @@ index f7cd95dd..377642c9 100644 if err != nil { return err } -@@ -313,7 +317,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error { +@@ -314,7 +318,7 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error { // inside the tmpfs, so we don't want to resolve symlinks). subsystemPath := filepath.Join(c.root, b.Destination) subsystemName := filepath.Base(b.Destination) @@ -6835,7 +6902,7 @@ index f7cd95dd..377642c9 100644 return err } if err := utils.WithProcfd(c.root, b.Destination, func(dstFd string) error { -@@ -352,8 +356,8 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error { +@@ -353,8 +357,8 @@ func mountCgroupV1(m *configs.Mount, c *mountConfig) error { return nil } @@ -6845,8 +6912,8 @@ index f7cd95dd..377642c9 100644 + err := utils.WithProcfdFile(m.dstFile, func(dstFd string) error { return mountViaFds(m.Source, nil, m.Destination, dstFd, "cgroup2", uintptr(m.Flags), m.Data) }) - if err == nil || !(errors.Is(err, unix.EPERM) || errors.Is(err, unix.EBUSY)) { -@@ -382,14 +386,14 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error { + if err == nil || (!errors.Is(err, unix.EPERM) && !errors.Is(err, unix.EBUSY)) { +@@ -383,14 +387,14 @@ func mountCgroupV2(m *configs.Mount, c *mountConfig) error { // // Mask `/sys/fs/cgroup` to ensure it is read-only, even when `/sys` is mounted // with `rbind,ro` (`runc spec --rootless` produces `rbind,ro` for `/sys`). @@ -6864,7 +6931,7 @@ index f7cd95dd..377642c9 100644 // Set up a scratch dir for the tmpfs on the host. tmpdir, err := prepareTmp("/tmp") if err != nil { -@@ -402,13 +406,19 @@ func doTmpfsCopyUp(m mountEntry, rootfs, mountLabel string) (Err error) { +@@ -403,13 +407,19 @@ func doTmpfsCopyUp(m mountEntry, rootfs, mountLabel string) (Err error) { } defer os.RemoveAll(tmpDir) @@ -6890,7 +6957,7 @@ index f7cd95dd..377642c9 100644 return err } defer func() { -@@ -419,7 +429,7 @@ func doTmpfsCopyUp(m mountEntry, rootfs, mountLabel string) (Err error) { +@@ -420,7 +430,7 @@ func doTmpfsCopyUp(m mountEntry, rootfs, mountLabel string) (Err error) { } }() @@ -6899,7 +6966,7 @@ index f7cd95dd..377642c9 100644 // Copy the container data to the host tmpdir. We append "/" to force // CopyDirectory to resolve the symlink rather than trying to copy the // symlink itself. -@@ -481,72 +491,76 @@ func statfsToMountFlags(st unix.Statfs_t) int { +@@ -482,72 +492,76 @@ func statfsToMountFlags(st unix.Statfs_t) int { var errRootfsToFile = errors.New("config tries to change rootfs to file") @@ -7031,7 +7098,7 @@ index f7cd95dd..377642c9 100644 } func mountToRootfs(c *mountConfig, m mountEntry) error { -@@ -562,7 +576,7 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { +@@ -563,7 +577,7 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { // 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) @@ -7040,7 +7107,7 @@ index f7cd95dd..377642c9 100644 // Do not use securejoin as it resolves symlinks. dest = filepath.Join(rootfs, dest) } -@@ -576,36 +590,47 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { +@@ -577,36 +591,47 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { } else if !fi.IsDir() { return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device) } @@ -7100,7 +7167,7 @@ index f7cd95dd..377642c9 100644 return err } -@@ -619,7 +644,7 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { +@@ -620,7 +645,7 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { // contrast to mount(8)'s current behaviour, but is what users probably // expect. See . if m.Flags & ^(unix.MS_BIND|unix.MS_REC|unix.MS_REMOUNT) != 0 || m.ClearedFlags != 0 { @@ -7109,7 +7176,7 @@ index f7cd95dd..377642c9 100644 flags := m.Flags | unix.MS_BIND | unix.MS_REMOUNT // The runtime-spec says we SHOULD map to the relevant mount(8) // behaviour. However, it's not clear whether we want the -@@ -712,14 +737,14 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { +@@ -721,14 +746,14 @@ func mountToRootfs(c *mountConfig, m mountEntry) error { return err } } @@ -7128,7 +7195,7 @@ index f7cd95dd..377642c9 100644 } } -@@ -867,20 +892,20 @@ func setupDevSymlinks(rootfs string) error { +@@ -876,20 +901,20 @@ func setupDevSymlinks(rootfs string) error { // needs to be called after we chroot/pivot into the container's rootfs so that any // symlinks are resolved locally. func reOpenDevNull() error { @@ -7154,7 +7221,7 @@ index f7cd95dd..377642c9 100644 // Close and re-open the fd. if err := unix.Dup3(int(file.Fd()), fd, 0); err != nil { return &os.PathError{ -@@ -913,16 +938,15 @@ func createDevices(config *configs.Config) error { +@@ -922,16 +947,15 @@ func createDevices(config *configs.Config) error { return nil } @@ -7179,7 +7246,7 @@ index f7cd95dd..377642c9 100644 }) } -@@ -932,31 +956,33 @@ func createDeviceNode(rootfs string, node *devices.Device, bind bool) error { +@@ -941,31 +965,33 @@ func createDeviceNode(rootfs string, node *devices.Device, bind bool) error { // The node only exists for cgroup reasons, ignore it here. return nil } @@ -7221,7 +7288,7 @@ index f7cd95dd..377642c9 100644 fileMode := node.FileMode switch node.Type { case devices.BlockDevice: -@@ -972,14 +998,44 @@ func mknodDevice(dest string, node *devices.Device) error { +@@ -981,14 +1007,44 @@ func mknodDevice(dest string, node *devices.Device) error { if err != nil { return err } @@ -7271,7 +7338,7 @@ index f7cd95dd..377642c9 100644 } // rootfsParentMountPrivate ensures rootfs parent mount is private. -@@ -1233,31 +1289,111 @@ func remountReadonly(m *configs.Mount) error { +@@ -1242,31 +1298,111 @@ func remountReadonly(m *configs.Mount) error { return fmt.Errorf("unable to mount %s as readonly max retries reached", dest) } @@ -7349,7 +7416,7 @@ index f7cd95dd..377642c9 100644 -// writeSystemProperty writes the value to a path under /proc/sys as determined from the key. -// For e.g. net.ipv4.ip_forward translated to /proc/sys/net/ipv4/ip_forward. -func writeSystemProperty(key, value string) error { -- keyPath := strings.Replace(key, ".", "/", -1) +- keyPath := strings.ReplaceAll(key, ".", "/") - return os.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0o644) +func reopenAfterMount(rootfs string, f *os.File, flags int) (_ *os.File, Err error) { + fullPath, err := procfs.ProcSelfFdReadlink(f) @@ -7395,7 +7462,7 @@ index f7cd95dd..377642c9 100644 var ( data = label.FormatMountLabel(m.Data, mountLabel) flags = m.Flags -@@ -1270,19 +1406,30 @@ func mountPropagate(m mountEntry, rootfs string, mountLabel string) error { +@@ -1279,19 +1415,30 @@ func mountPropagate(m mountEntry, rootfs string, mountLabel string) error { flags &= ^unix.MS_RDONLY } @@ -7432,7 +7499,7 @@ index f7cd95dd..377642c9 100644 for _, pflag := range m.PropagationFlags { if err := mountViaFds("", nil, m.Destination, dstFd, "", uintptr(pflag), ""); err != nil { return err -@@ -1295,11 +1442,11 @@ func mountPropagate(m mountEntry, rootfs string, mountLabel string) error { +@@ -1304,11 +1451,11 @@ func mountPropagate(m mountEntry, rootfs string, mountLabel string) error { return nil } @@ -7447,7 +7514,7 @@ index f7cd95dd..377642c9 100644 }) } diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go -index 9f7fa45d..6a46eff7 100644 +index 384750bf..21516bd3 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -11,6 +11,8 @@ import ( @@ -7485,7 +7552,7 @@ index 9f7fa45d..6a46eff7 100644 } pdeath, err := system.GetParentDeathSignal() if err != nil { -@@ -244,19 +243,17 @@ func (l *linuxStandardInit) Init() error { +@@ -252,19 +251,17 @@ func (l *linuxStandardInit) Init() error { return fmt.Errorf("close log pipe: %w", err) } @@ -7510,19 +7577,19 @@ index 9f7fa45d..6a46eff7 100644 } // Close the O_PATH fifofd fd before exec because the kernel resets -@@ -265,6 +262,7 @@ func (l *linuxStandardInit) Init() error { +@@ -273,6 +270,7 @@ func (l *linuxStandardInit) Init() error { // N.B. the core issue itself (passing dirfds to the host filesystem) has // since been resolved. // https://github.com/torvalds/linux/blob/v4.9/fs/exec.c#L1290-L1318 + _ = fifoFile.Close() _ = l.fifoFile.Close() - s := l.config.SpecState + if s := l.config.SpecState; s != nil { diff --git a/libcontainer/system/linux.go b/libcontainer/system/linux.go -index 7bbf92a3..da3dbf53 100644 +index e8ce0eca..5e558c4f 100644 --- a/libcontainer/system/linux.go +++ b/libcontainer/system/linux.go -@@ -214,3 +214,23 @@ func SetLinuxPersonality(personality int) error { +@@ -169,3 +169,23 @@ func SetLinuxPersonality(personality int) error { } return nil } @@ -7584,11 +7651,11 @@ index 774443ec..34850dd8 100644 return stat, err } diff --git a/libcontainer/utils/utils.go b/libcontainer/utils/utils.go -index db420ea6..3e008bd4 100644 +index 23003e17..46da94f4 100644 --- a/libcontainer/utils/utils.go +++ b/libcontainer/utils/utils.go @@ -65,11 +65,11 @@ func CleanPath(path string) string { - return filepath.Clean(path) + return path } -// stripRoot returns the passed path, stripping the root path if it was @@ -7618,7 +7685,7 @@ index 06c042f5..4b5fd833 100644 } } diff --git a/libcontainer/utils/utils_unix.go b/libcontainer/utils/utils_unix.go -index 8f179b6a..638878d7 100644 +index f6b3fefb..7dbec54d 100644 --- a/libcontainer/utils/utils_unix.go +++ b/libcontainer/utils/utils_unix.go @@ -9,27 +9,15 @@ import ( @@ -7673,7 +7740,7 @@ index 8f179b6a..638878d7 100644 fdList, err := fdDir.Readdirnames(-1) if err != nil { return err -@@ -164,8 +146,8 @@ func NewSockPair(name string) (parent, child *os.File, err error) { +@@ -170,8 +152,8 @@ func NewSockPair(name string) (parent, child *os.File, err error) { // the passed closure (the file handle will be freed once the closure returns). func WithProcfd(root, unsafePath string, fn func(procfd string) error) error { // Remove the root then forcefully resolve inside the root. @@ -7684,7 +7751,7 @@ index 8f179b6a..638878d7 100644 if err != nil { return fmt.Errorf("resolving path inside rootfs failed: %w", err) } -@@ -174,7 +156,7 @@ func WithProcfd(root, unsafePath string, fn func(procfd string) error) error { +@@ -180,7 +162,7 @@ func WithProcfd(root, unsafePath string, fn func(procfd string) error) error { defer closer() // Open the target path. @@ -7693,7 +7760,7 @@ index 8f179b6a..638878d7 100644 if err != nil { return fmt.Errorf("open o_path procfd: %w", err) } -@@ -184,13 +166,24 @@ func WithProcfd(root, unsafePath string, fn func(procfd string) error) error { +@@ -190,13 +172,24 @@ func WithProcfd(root, unsafePath string, fn func(procfd string) error) error { // Double-check the path is the one we expected. if realpath, err := os.Readlink(procfd); err != nil { return fmt.Errorf("procfd verification failed: %w", err) @@ -7719,7 +7786,7 @@ index 8f179b6a..638878d7 100644 type ProcThreadSelfCloser func() var ( -@@ -262,88 +255,6 @@ func ProcThreadSelfFd(fd uintptr) (string, ProcThreadSelfCloser) { +@@ -268,88 +261,6 @@ func ProcThreadSelfFd(fd uintptr) (string, ProcThreadSelfCloser) { return ProcThreadSelf("fd/" + strconv.FormatUint(uint64(fd), 10)) } @@ -7809,10 +7876,10 @@ index 8f179b6a..638878d7 100644 func Openat(dir *os.File, path string, flags int, mode uint32) (*os.File, error) { dirFd := unix.AT_FDCWD diff --git a/utils_linux.go b/utils_linux.go -index 013dbcf4..0657faf5 100644 +index 9c9e1e83..a4cc5bdf 100644 --- a/utils_linux.go +++ b/utils_linux.go -@@ -15,6 +15,7 @@ import ( +@@ -16,6 +16,7 @@ import ( "github.com/urfave/cli" "golang.org/x/sys/unix" @@ -7820,7 +7887,7 @@ index 013dbcf4..0657faf5 100644 "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/specconv" -@@ -234,10 +235,14 @@ func (r *runner) run(config *specs.Process) (int, error) { +@@ -240,10 +241,14 @@ func (r *runner) run(config *specs.Process) (int, error) { process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...) } baseFd := 3 + len(process.ExtraFiles) @@ -12922,7 +12989,7 @@ index 07e0f77d..884a8b80 100644 // the SELinux `context` mount option. Changing labels of files on mount // points with this option can never be changed. diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go -index f61a5601..95f29e21 100644 +index e49e6d53..95f29e21 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_linux.go @@ -18,7 +18,7 @@ var validOptions = map[string]bool{ @@ -12961,15 +13028,8 @@ index f61a5601..95f29e21 100644 // SetFileLabel modifies the "path" label to the specified file label func SetFileLabel(path string, fileLabel string) error { if !selinux.GetEnabled() || fileLabel == "" { -@@ -120,17 +114,9 @@ func Relabel(path string, fileLabel string, shared bool) error { - c["level"] = "s0" - fileLabel = c.Get() - } -- if err := selinux.Chcon(path, fileLabel, true); err != nil { -- return err -- } -- return nil -+ return selinux.Chcon(path, fileLabel, true) +@@ -123,11 +117,6 @@ func Relabel(path string, fileLabel string, shared bool) error { + return selinux.Chcon(path, fileLabel, true) } -// DisableSecOpt returns a security opt that can disable labeling @@ -12981,59 +13041,22 @@ index f61a5601..95f29e21 100644 func Validate(label string) error { if strings.Contains(label, "z") && strings.Contains(label, "Z") { diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go -index f21c80c5..7a54afc5 100644 +index 1c260cb2..7a54afc5 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go -@@ -6,25 +6,19 @@ package label - // InitLabels returns the process label and file labels to be used within - // the container. A list of options can be passed into this function to alter - // the labels. --func InitLabels(options []string) (string, string, error) { -+func InitLabels([]string) (string, string, error) { +@@ -10,12 +10,6 @@ func InitLabels([]string) (string, string, error) { return "", "", nil } -// Deprecated: The GenLabels function is only to be used during the transition -// to the official API. Use InitLabels(strings.Fields(options)) instead. --func GenLabels(options string) (string, string, error) { +-func GenLabels(string) (string, string, error) { - return "", "", nil -} - --func SetFileLabel(path string, fileLabel string) error { -+func SetFileLabel(string, string) error { + func SetFileLabel(string, string) error { return nil } - --func SetFileCreateLabel(fileLabel string) error { -+func SetFileCreateLabel(string) error { - return nil - } - --func Relabel(path string, fileLabel string, shared bool) error { -+func Relabel(string, string, bool) error { - return nil - } - -@@ -35,16 +29,16 @@ func DisableSecOpt() []string { - } - - // Validate checks that the label does not include unexpected options --func Validate(label string) error { -+func Validate(string) error { - return nil - } - - // RelabelNeeded checks whether the user requested a relabel --func RelabelNeeded(label string) bool { -+func RelabelNeeded(string) bool { - return false - } - - // IsShared checks that the label includes a "shared" mark --func IsShared(label string) bool { -+func IsShared(string) bool { - return false - } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index af058b84..15150d47 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -13110,7 +13133,7 @@ index af058b84..15150d47 100644 // Get returns the Context as a string diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go -index f1e95977..70392d98 100644 +index c80c1097..70392d98 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go @@ -17,8 +17,11 @@ import ( @@ -13146,14 +13169,7 @@ index f1e95977..70392d98 100644 // for policyRoot() policyRootOnce sync.Once policyRootVal string -@@ -132,12 +131,13 @@ func verifySELinuxfsMount(mnt string) bool { - if err == nil { - break - } -- if err == unix.EAGAIN || err == unix.EINTR { //nolint:errorlint // unix errors are bare -+ if err == unix.EAGAIN || err == unix.EINTR { - continue - } +@@ -138,6 +137,7 @@ func verifySELinuxfsMount(mnt string) bool { return false } @@ -13180,7 +13196,7 @@ index f1e95977..70392d98 100644 - if err == nil { - break - } -- if err != unix.EINTR { //nolint:errorlint // unix errors are bare +- if err != unix.EINTR { - return &os.PathError{Op: "fstatfs", Path: fh.Name(), Err: err} - } +func writeConFd(out *os.File, val string) error { @@ -13372,28 +13388,6 @@ index f1e95977..70392d98 100644 } // classIndex returns the int index for an object class in the loaded policy, -@@ -328,8 +467,8 @@ func lSetFileLabel(fpath string, label string) error { - if err == nil { - break - } -- if err != unix.EINTR { //nolint:errorlint // unix errors are bare -- return &os.PathError{Op: "lsetxattr", Path: fpath, Err: err} -+ if err != unix.EINTR { -+ return &os.PathError{Op: fmt.Sprintf("lsetxattr(label=%s)", label), Path: fpath, Err: err} - } - } - -@@ -347,8 +486,8 @@ func setFileLabel(fpath string, label string) error { - if err == nil { - break - } -- if err != unix.EINTR { //nolint:errorlint // unix errors are bare -- return &os.PathError{Op: "setxattr", Path: fpath, Err: err} -+ if err != unix.EINTR { -+ return &os.PathError{Op: fmt.Sprintf("setxattr(label=%s)", label), Path: fpath, Err: err} - } - } - @@ -392,78 +531,34 @@ func lFileLabel(fpath string) (string, error) { } @@ -13549,10 +13543,11 @@ index f1e95977..70392d98 100644 if m.high.cats != nil && m.high.cats.BitLen() > 0 { high += ":" + bitsetToStr(m.high.cats) } -@@ -639,14 +736,16 @@ func (m mlsRange) String() string { +@@ -639,15 +736,16 @@ func (m mlsRange) String() string { return low + "-" + high } +-// TODO: remove min and max once Go < 1.21 is not supported. -func max(a, b uint) uint { +// TODO: remove these in favor of built-in min/max +// once we stop supporting Go < 1.21. @@ -13568,7 +13563,7 @@ index f1e95977..70392d98 100644 if a < b { return a } -@@ -675,10 +774,10 @@ func calculateGlbLub(sourceRange, targetRange string) (string, error) { +@@ -676,10 +774,10 @@ func calculateGlbLub(sourceRange, targetRange string) (string, error) { outrange := &mlsRange{low: &level{}, high: &level{}} /* take the greatest of the low */ @@ -13581,7 +13576,7 @@ index f1e95977..70392d98 100644 /* find the intersecting categories */ if s.low.cats != nil && t.low.cats != nil { -@@ -723,16 +822,29 @@ func peerLabel(fd uintptr) (string, error) { +@@ -724,16 +822,29 @@ func peerLabel(fd uintptr) (string, error) { // setKeyLabel takes a process label and tells the kernel to assign the // label to the next kernel keyring that gets created func setKeyLabel(label string) error { @@ -13612,7 +13607,7 @@ index f1e95977..70392d98 100644 // get returns the Context as a string func (c Context) get() string { if l := c["level"]; l != "" { -@@ -808,8 +920,7 @@ func enforceMode() int { +@@ -809,8 +920,7 @@ func enforceMode() int { // setEnforceMode sets the current SELinux mode Enforcing, Permissive. // Disabled is not valid, since this needs to be set at boot time. func setEnforceMode(mode int) error { @@ -13622,7 +13617,7 @@ index f1e95977..70392d98 100644 } // defaultEnforceMode returns the systems default SELinux mode Enforcing, -@@ -1016,8 +1127,7 @@ func addMcs(processLabel, fileLabel string) (string, string) { +@@ -1017,8 +1127,7 @@ func addMcs(processLabel, fileLabel string) (string, string) { // securityCheckContext validates that the SELinux label is understood by the kernel func securityCheckContext(val string) error { @@ -13632,24 +13627,15 @@ index f1e95977..70392d98 100644 } // copyLevel returns a label with the MLS/MCS level from src label replaced on -@@ -1134,7 +1244,7 @@ func rchcon(fpath, label string) error { //revive:disable:cognitive-complexity - } - return pwalkdir.Walk(fpath, func(p string, _ fs.DirEntry, _ error) error { - if fastMode { -- if cLabel, err := lFileLabel(fpath); err == nil && cLabel == label { -+ if cLabel, err := lFileLabel(p); err == nil && cLabel == label { - return nil - } - } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go -index bc3fd3b3..26792123 100644 +index 0889fbe0..26792123 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go @@ -7,11 +7,11 @@ func attrPath(string) string { return "" } --func readCon(fpath string) (string, error) { +-func readCon(string) (string, error) { +func readConThreadSelf(string) (string, error) { return "", nil } @@ -13659,75 +13645,7 @@ index bc3fd3b3..26792123 100644 return nil } -@@ -21,27 +21,27 @@ func getEnabled() bool { - return false - } - --func classIndex(class string) (int, error) { -+func classIndex(string) (int, error) { - return -1, nil - } - --func setFileLabel(fpath string, label string) error { -+func setFileLabel(string, string) error { - return nil - } - --func lSetFileLabel(fpath string, label string) error { -+func lSetFileLabel(string, string) error { - return nil - } - --func fileLabel(fpath string) (string, error) { -+func fileLabel(string) (string, error) { - return "", nil - } - --func lFileLabel(fpath string) (string, error) { -+func lFileLabel(string) (string, error) { - return "", nil - } - --func setFSCreateLabel(label string) error { -+func setFSCreateLabel(string) error { - return nil - } - -@@ -53,7 +53,7 @@ func currentLabel() (string, error) { - return "", nil - } - --func pidLabel(pid int) (string, error) { -+func pidLabel(int) (string, error) { - return "", nil - } - -@@ -61,38 +61,42 @@ func execLabel() (string, error) { - return "", nil - } - --func canonicalizeContext(val string) (string, error) { -+func canonicalizeContext(string) (string, error) { - return "", nil - } - --func computeCreateContext(source string, target string, class string) (string, error) { -+func computeCreateContext(string, string, string) (string, error) { - return "", nil - } - --func calculateGlbLub(sourceRange, targetRange string) (string, error) { -+func calculateGlbLub(string, string) (string, error) { - return "", nil - } - --func peerLabel(fd uintptr) (string, error) { -+func peerLabel(uintptr) (string, error) { - return "", nil - } - --func setKeyLabel(label string) error { -+func setKeyLabel(string) error { +@@ -81,6 +81,10 @@ func setKeyLabel(string) error { return nil } @@ -13738,145 +13656,11 @@ index bc3fd3b3..26792123 100644 func (c Context) get() string { return "" } - --func newContext(label string) (Context, error) { -+func newContext(string) (Context, error) { - return Context{}, nil - } - - func clearLabels() { - } - --func reserveLabel(label string) { -+func reserveLabel(string) { - } - - func isMLSEnabled() bool { -@@ -103,7 +107,7 @@ func enforceMode() int { - return Disabled - } - --func setEnforceMode(mode int) error { -+func setEnforceMode(int) error { - return nil - } - -@@ -111,7 +115,7 @@ func defaultEnforceMode() int { - return Disabled - } - --func releaseLabel(label string) { -+func releaseLabel(string) { - } - - func roFileLabel() string { -@@ -126,27 +130,27 @@ func initContainerLabels() (string, string) { - return "", "" - } - --func containerLabels() (processLabel string, fileLabel string) { -+func containerLabels() (string, string) { - return "", "" - } - --func securityCheckContext(val string) error { -+func securityCheckContext(string) error { - return nil - } - --func copyLevel(src, dest string) (string, error) { -+func copyLevel(string, string) (string, error) { - return "", nil - } - --func chcon(fpath string, label string, recurse bool) error { -+func chcon(string, string, bool) error { - return nil - } - --func dupSecOpt(src string) ([]string, error) { -+func dupSecOpt(string) ([]string, error) { - return nil, nil - } - --func getDefaultContextWithLevel(user, level, scon string) (string, error) { -+func getDefaultContextWithLevel(string, string, string) (string, error) { - return "", nil - } - -diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go -index 9e473ca1..559c8510 100644 ---- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go -+++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs_linux.go -@@ -31,7 +31,7 @@ func lgetxattr(path, attr string) ([]byte, error) { - func doLgetxattr(path, attr string, dest []byte) (int, error) { - for { - sz, err := unix.Lgetxattr(path, attr, dest) -- if err != unix.EINTR { //nolint:errorlint // unix errors are bare -+ if err != unix.EINTR { - return sz, err - } - } -@@ -64,7 +64,7 @@ func getxattr(path, attr string) ([]byte, error) { - func dogetxattr(path, attr string, dest []byte) (int, error) { - for { - sz, err := unix.Getxattr(path, attr, dest) -- if err != unix.EINTR { //nolint:errorlint // unix errors are bare -+ if err != unix.EINTR { - return sz, err - } - } -diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md b/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md -index 068ac400..b827e7dd 100644 ---- a/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md -+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/README.md -@@ -28,7 +28,9 @@ Please note the following limitations of this code: - - * fs.SkipDir is not supported; - -- * no errors are ever passed to WalkDirFunc; -+ * ErrNotExist errors from filepath.WalkDir are silently ignored for any path -+ except the top directory (WalkDir argument); any other error is returned to -+ the caller of WalkDir; - - * once any error is returned from any walkDirFunc instance, no more calls - to WalkDirFunc are made, and the error is returned to the caller of WalkDir; -@@ -51,4 +53,4 @@ filepath.WalkDir. - Otherwise (if a WalkDirFunc is actually doing something) this is usually - faster, except when the WalkDirN(..., 1) is used. Run `go test -bench .` - to see how different operations can benefit from it, as well as how the --level of paralellism affects the speed. -+level of parallelism affects the speed. -diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go b/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go -index 0f5d9f58..5d2d09a2 100644 ---- a/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go -+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalkdir/pwalkdir.go -@@ -4,6 +4,7 @@ - package pwalkdir - - import ( -+ "errors" - "fmt" - "io/fs" - "path/filepath" -@@ -60,6 +61,12 @@ func WalkN(root string, walkFn fs.WalkDirFunc, num int) error { - go func() { - err = filepath.WalkDir(root, func(p string, entry fs.DirEntry, err error) error { - if err != nil { -+ // Walking a file tree can race with removal, -+ // so ignore ENOENT, except for root. -+ // https://github.com/opencontainers/selinux/issues/199. -+ if errors.Is(err, fs.ErrNotExist) && len(p) != rootLen { -+ return nil -+ } - close(files) - return err - } diff --git a/vendor/modules.txt b/vendor/modules.txt -index d5aeb5f2..4e7e0ef8 100644 +index 0ead139c..f22001c8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt -@@ -15,7 +15,7 @@ github.com/cilium/ebpf/internal/sysenc +@@ -17,7 +17,7 @@ github.com/cilium/ebpf/internal/testutils/fdtrace github.com/cilium/ebpf/internal/tracefs github.com/cilium/ebpf/internal/unix github.com/cilium/ebpf/link @@ -13885,8 +13669,8 @@ index d5aeb5f2..4e7e0ef8 100644 ## explicit; go 1.13 github.com/containerd/console # github.com/coreos/go-systemd/v22 v22.5.0 -@@ -25,9 +25,19 @@ github.com/coreos/go-systemd/v22/dbus - # github.com/cpuguy83/go-md2man/v2 v2.0.2 +@@ -27,9 +27,19 @@ github.com/coreos/go-systemd/v22/dbus + # github.com/cpuguy83/go-md2man/v2 v2.0.5 ## explicit; go 1.11 github.com/cpuguy83/go-md2man/v2/md2man -# github.com/cyphar/filepath-securejoin v0.4.1 @@ -13906,16 +13690,16 @@ index d5aeb5f2..4e7e0ef8 100644 # github.com/docker/go-units v0.5.0 ## explicit github.com/docker/go-units -@@ -50,7 +60,7 @@ github.com/mrunalp/fileutils +@@ -66,7 +76,7 @@ github.com/opencontainers/cgroups/systemd ## explicit github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/runtime-spec/specs-go/features --# github.com/opencontainers/selinux v1.11.0 +-# github.com/opencontainers/selinux v1.11.1 +# github.com/opencontainers/selinux v1.12.0 => ./internal/third_party/selinux ## explicit; go 1.19 github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux/label -@@ -116,3 +126,4 @@ google.golang.org/protobuf/reflect/protoreflect +@@ -127,3 +137,4 @@ google.golang.org/protobuf/reflect/protoreflect google.golang.org/protobuf/reflect/protoregistry google.golang.org/protobuf/runtime/protoiface google.golang.org/protobuf/runtime/protoimpl diff --git a/SOURCES/0001-Bump-runtime-spec-to-latest-git-HEAD.patch b/SOURCES/0001-Bump-runtime-spec-to-latest-git-HEAD.patch deleted file mode 100644 index 8268405..0000000 --- a/SOURCES/0001-Bump-runtime-spec-to-latest-git-HEAD.patch +++ /dev/null @@ -1,103 +0,0 @@ -From c6dad73d617864f3a281ac1fdaacd5ed971fa317 Mon Sep 17 00:00:00 2001 -From: Kir Kolyshkin -Date: Thu, 27 Jun 2024 09:00:51 -0700 -Subject: [PATCH 1/2] Bump runtime-spec to latest git HEAD - -This is to include - - https://github.com/opencontainers/runtime-spec/pull/1261 - - https://github.com/opencontainers/runtime-spec/pull/1253 - -Signed-off-by: Kir Kolyshkin -(cherry picked from commit 2cac22b1e29e6be4c004f35ce582aa2b7e1c2fda) -Signed-off-by: Kir Kolyshkin ---- - go.mod | 2 +- - go.sum | 4 ++-- - .../opencontainers/runtime-spec/specs-go/config.go | 8 ++++++++ - .../opencontainers/runtime-spec/specs-go/version.go | 2 +- - vendor/modules.txt | 2 +- - 5 files changed, 13 insertions(+), 5 deletions(-) - -diff --git a/go.mod b/go.mod -index 348bc9c6..db2d7ef1 100644 ---- a/go.mod -+++ b/go.mod -@@ -19,7 +19,7 @@ require ( - github.com/moby/sys/user v0.3.0 - github.com/moby/sys/userns v0.1.0 - github.com/mrunalp/fileutils v0.5.1 -- github.com/opencontainers/runtime-spec v1.2.0 -+ github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95 - github.com/opencontainers/selinux v1.11.0 - github.com/seccomp/libseccomp-golang v0.10.0 - github.com/sirupsen/logrus v1.9.3 -diff --git a/go.sum b/go.sum -index 225d5860..4c863cc9 100644 ---- a/go.sum -+++ b/go.sum -@@ -46,8 +46,8 @@ github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g - github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= - github.com/mrunalp/fileutils v0.5.1 h1:F+S7ZlNKnrwHfSwdlgNSkKo67ReVf8o9fel6C3dkm/Q= - github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= --github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= --github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -+github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95 h1:Ghl8Z3l+yPQUDSxAp7Kg7fJLRNNXjOsR6ooDcca7PjU= -+github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= - github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU= - github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= - github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -index d1236ba7..671f0d01 100644 ---- a/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/config.go -@@ -94,6 +94,8 @@ type Process struct { - SelinuxLabel string `json:"selinuxLabel,omitempty" platform:"linux"` - // IOPriority contains the I/O priority settings for the cgroup. - IOPriority *LinuxIOPriority `json:"ioPriority,omitempty" platform:"linux"` -+ // ExecCPUAffinity specifies CPU affinity for exec processes. -+ ExecCPUAffinity *CPUAffinity `json:"execCPUAffinity,omitempty" platform:"linux"` - } - - // LinuxCapabilities specifies the list of allowed capabilities that are kept for a process. -@@ -127,6 +129,12 @@ const ( - IOPRIO_CLASS_IDLE IOPriorityClass = "IOPRIO_CLASS_IDLE" - ) - -+// CPUAffinity specifies process' CPU affinity. -+type CPUAffinity struct { -+ Initial string `json:"initial,omitempty"` -+ Final string `json:"final,omitempty"` -+} -+ - // Box specifies dimensions of a rectangle. Used for specifying the size of a console. - type Box struct { - // Height is the vertical dimension of a box. -diff --git a/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go b/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go -index 503971e0..f6c15f6c 100644 ---- a/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go -+++ b/vendor/github.com/opencontainers/runtime-spec/specs-go/version.go -@@ -11,7 +11,7 @@ const ( - VersionPatch = 0 - - // VersionDev indicates development branch. Releases will be empty string. -- VersionDev = "" -+ VersionDev = "+dev" - ) - - // Version is the specification version that the package types support. -diff --git a/vendor/modules.txt b/vendor/modules.txt -index 3b245e0d..df520923 100644 ---- a/vendor/modules.txt -+++ b/vendor/modules.txt -@@ -46,7 +46,7 @@ github.com/moby/sys/userns - # github.com/mrunalp/fileutils v0.5.1 - ## explicit; go 1.13 - github.com/mrunalp/fileutils --# github.com/opencontainers/runtime-spec v1.2.0 -+# github.com/opencontainers/runtime-spec v1.2.1-0.20240625190033-701738418b95 - ## explicit - github.com/opencontainers/runtime-spec/specs-go - github.com/opencontainers/runtime-spec/specs-go/features --- -2.47.1 - diff --git a/SOURCES/0002-1.2-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch b/SOURCES/0002-1.3-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch similarity index 88% rename from SOURCES/0002-1.2-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch rename to SOURCES/0002-1.3-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch index 20db404..feda435 100644 --- a/SOURCES/0002-1.2-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch +++ b/SOURCES/0002-1.3-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch @@ -1,7 +1,7 @@ -From e949092d469c3ee3ea9bf1002649b6a692895da9 Mon Sep 17 00:00:00 2001 +From 2a9b44aabfa52bb071ff2e3564427da0bb82312e Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Wed, 5 Nov 2025 02:04:02 +1100 -Subject: [PATCH 2/2] [1.2] rootfs: re-allow dangling symlinks in mount targets +Subject: [PATCH 2/2] [1.3] rootfs: re-allow dangling symlinks in mount targets It seems there are a fair few images where dangling symlinks are used as path components for mount targets, which pathrs-lite does not support @@ -23,10 +23,10 @@ Signed-off-by: Kir Kolyshkin 1 file changed, 11 insertions(+) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go -index 377642c9..6ea7cd47 100644 +index d85e7321..2fda3c9d 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go -@@ -518,6 +518,17 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) { +@@ -519,6 +519,17 @@ func (m *mountEntry) createOpenMountpoint(rootfs string) (Err error) { dstIsFile = !fi.IsDir() } diff --git a/SOURCES/0002-runc-exec-implement-CPU-affinity.patch b/SOURCES/0002-runc-exec-implement-CPU-affinity.patch deleted file mode 100644 index 90de1a6..0000000 --- a/SOURCES/0002-runc-exec-implement-CPU-affinity.patch +++ /dev/null @@ -1,521 +0,0 @@ -From 73786942b7176eae1e676cf2f78af548f090e418 Mon Sep 17 00:00:00 2001 -From: Kir Kolyshkin -Date: Mon, 21 Oct 2024 15:50:38 -0700 -Subject: [PATCH 2/2] runc exec: implement CPU affinity - -As per -- https://github.com/opencontainers/runtime-spec/pull/1253 -- https://github.com/opencontainers/runtime-spec/pull/1261 - -CPU affinity can be set in two ways: -1. When creating/starting a container, in config.json's - Process.ExecCPUAffinity, which is when applied to all execs. -2. When running an exec, in process.json's CPUAffinity, which - applied to a given exec and overrides the value from (1). - -Add some basic tests. - -Note that older kernels (RHEL8, Ubuntu 20.04) change CPU affinity of a -process to that of a container's cgroup, as soon as it is moved to that -cgroup, while newer kernels (Ubuntu 24.04, Fedora 41) don't do that. - -Because of the above, - - it's impossible to really test initial CPU affinity without adding - debug logging to libcontainer/nsenter; - - for older kernels, there can be a brief moment when exec's affinity - is different than either initial or final affinity being set; - - exec's final CPU affinity, if not specified, can be different - depending on the kernel, therefore we don't test it. - -Signed-off-by: Kir Kolyshkin -(cherry picked from commit 57237b31de367a722c5d49088912d57c28c6fb46) -Signed-off-by: Kir Kolyshkin ---- - libcontainer/configs/config.go | 72 ++++++++++++++++++++ - libcontainer/container_linux.go | 4 ++ - libcontainer/init_linux.go | 3 +- - libcontainer/nsenter/log.c | 9 ++- - libcontainer/nsenter/log.h | 3 + - libcontainer/nsenter/nsexec.c | 29 ++++++++ - libcontainer/process.go | 2 + - libcontainer/process_linux.go | 49 +++++++++++++- - libcontainer/specconv/spec_linux.go | 5 ++ - tests/integration/cpu_affinity.bats | 101 ++++++++++++++++++++++++++++ - utils_linux.go | 6 ++ - 11 files changed, 277 insertions(+), 6 deletions(-) - create mode 100644 tests/integration/cpu_affinity.bats - -diff --git a/libcontainer/configs/config.go b/libcontainer/configs/config.go -index 22fe0f9b..daffd130 100644 ---- a/libcontainer/configs/config.go -+++ b/libcontainer/configs/config.go -@@ -3,8 +3,11 @@ package configs - import ( - "bytes" - "encoding/json" -+ "errors" - "fmt" - "os/exec" -+ "strconv" -+ "strings" - "time" - - "github.com/sirupsen/logrus" -@@ -225,6 +228,9 @@ type Config struct { - - // IOPriority is the container's I/O priority. - IOPriority *IOPriority `json:"io_priority,omitempty"` -+ -+ // ExecCPUAffinity is CPU affinity for a non-init process to be run in the container. -+ ExecCPUAffinity *CPUAffinity `json:"exec_cpu_affinity,omitempty"` - } - - // Scheduler is based on the Linux sched_setattr(2) syscall. -@@ -294,6 +300,72 @@ var IOPrioClassMapping = map[specs.IOPriorityClass]int{ - - type IOPriority = specs.LinuxIOPriority - -+type CPUAffinity struct { -+ Initial, Final *unix.CPUSet -+} -+ -+func toCPUSet(str string) (*unix.CPUSet, error) { -+ if str == "" { -+ return nil, nil -+ } -+ s := new(unix.CPUSet) -+ for _, r := range strings.Split(str, ",") { -+ // Allow extra spaces around. -+ r = strings.TrimSpace(r) -+ // Allow empty elements (extra commas). -+ if r == "" { -+ continue -+ } -+ if r0, r1, found := strings.Cut(r, "-"); found { -+ start, err := strconv.ParseUint(r0, 10, 32) -+ if err != nil { -+ return nil, err -+ } -+ end, err := strconv.ParseUint(r1, 10, 32) -+ if err != nil { -+ return nil, err -+ } -+ if start > end { -+ return nil, errors.New("invalid range: " + r) -+ } -+ for i := int(start); i <= int(end); i++ { -+ s.Set(i) -+ } -+ } else { -+ val, err := strconv.ParseUint(r, 10, 32) -+ if err != nil { -+ return nil, err -+ } -+ s.Set(int(val)) -+ } -+ } -+ -+ return s, nil -+} -+ -+// ConvertCPUAffinity converts [specs.CPUAffinity] to [CPUAffinity]. -+func ConvertCPUAffinity(sa *specs.CPUAffinity) (*CPUAffinity, error) { -+ if sa == nil { -+ return nil, nil -+ } -+ initial, err := toCPUSet(sa.Initial) -+ if err != nil { -+ return nil, fmt.Errorf("bad CPUAffinity.Initial: %w", err) -+ } -+ final, err := toCPUSet(sa.Final) -+ if err != nil { -+ return nil, fmt.Errorf("bad CPUAffinity.Final: %w", err) -+ } -+ if initial == nil && final == nil { -+ return nil, nil -+ } -+ -+ return &CPUAffinity{ -+ Initial: initial, -+ Final: final, -+ }, nil -+} -+ - type ( - HookName string - HookList []Hook -diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go -index c0211617..1fc590a5 100644 ---- a/libcontainer/container_linux.go -+++ b/libcontainer/container_linux.go -@@ -692,6 +692,7 @@ func (c *Container) newInitConfig(process *Process) *initConfig { - AppArmorProfile: c.config.AppArmorProfile, - ProcessLabel: c.config.ProcessLabel, - Rlimits: c.config.Rlimits, -+ CPUAffinity: c.config.ExecCPUAffinity, - CreateConsole: process.ConsoleSocket != nil, - ConsoleWidth: process.ConsoleWidth, - ConsoleHeight: process.ConsoleHeight, -@@ -708,6 +709,9 @@ func (c *Container) newInitConfig(process *Process) *initConfig { - if len(process.Rlimits) > 0 { - cfg.Rlimits = process.Rlimits - } -+ if process.CPUAffinity != nil { -+ cfg.CPUAffinity = process.CPUAffinity -+ } - if cgroups.IsCgroup2UnifiedMode() { - cfg.Cgroup2Path = c.cgroupManager.Path("") - } -diff --git a/libcontainer/init_linux.go b/libcontainer/init_linux.go -index 1eb0279d..eddbfba6 100644 ---- a/libcontainer/init_linux.go -+++ b/libcontainer/init_linux.go -@@ -72,6 +72,7 @@ type initConfig struct { - RootlessCgroups bool `json:"rootless_cgroups,omitempty"` - SpecState *specs.State `json:"spec_state,omitempty"` - Cgroup2Path string `json:"cgroup2_path,omitempty"` -+ CPUAffinity *configs.CPUAffinity `json:"cpu_affinity,omitempty"` - } - - // Init is part of "runc init" implementation. -@@ -151,7 +152,7 @@ func startInitialization() (retErr error) { - - logrus.SetOutput(logPipe) - logrus.SetFormatter(new(logrus.JSONFormatter)) -- logrus.Debug("child process in init()") -+ logrus.Debugf("child process in init()") - - // Only init processes have FIFOFD. - var fifoFile *os.File -diff --git a/libcontainer/nsenter/log.c b/libcontainer/nsenter/log.c -index 086b5398..72774cb0 100644 ---- a/libcontainer/nsenter/log.c -+++ b/libcontainer/nsenter/log.c -@@ -31,6 +31,11 @@ void setup_logpipe(void) - loglevel = i; - } - -+bool log_enabled_for(int level) -+{ -+ return (logfd >= 0 && level <= loglevel); -+} -+ - /* Defined in nsexec.c */ - extern int current_stage; - -@@ -40,8 +45,8 @@ void write_log(int level, const char *format, ...) - va_list args; - int ret; - -- if (logfd < 0 || level > loglevel) -- goto out; -+ if (!log_enabled_for(level)) -+ return; - - va_start(args, format); - ret = vasprintf(&message, format, args); -diff --git a/libcontainer/nsenter/log.h b/libcontainer/nsenter/log.h -index 1fe95a11..3e18de68 100644 ---- a/libcontainer/nsenter/log.h -+++ b/libcontainer/nsenter/log.h -@@ -1,6 +1,7 @@ - #ifndef NSENTER_LOG_H - #define NSENTER_LOG_H - -+#include - #include - - /* -@@ -20,6 +21,8 @@ - */ - void setup_logpipe(void); - -+bool log_enabled_for(int level); -+ - void write_log(int level, const char *format, ...) __attribute__((format(printf, 2, 3))); - - extern int logfd; -diff --git a/libcontainer/nsenter/nsexec.c b/libcontainer/nsenter/nsexec.c -index 565b2ca2..aa4976d6 100644 ---- a/libcontainer/nsenter/nsexec.c -+++ b/libcontainer/nsenter/nsexec.c -@@ -558,6 +558,25 @@ static void update_timens_offsets(pid_t pid, char *map, size_t map_len) - bail("failed to update /proc/%d/timens_offsets", pid); - } - -+void print_cpu_affinity() -+{ -+ cpu_set_t cpus = { }; -+ size_t i, mask = 0; -+ -+ if (sched_getaffinity(0, sizeof(cpus), &cpus) < 0) { -+ write_log(WARNING, "sched_getaffinity: %m"); -+ return; -+ } -+ -+ /* Do not print the complete mask, we only need a few first CPUs. */ -+ for (i = 0; i < sizeof(mask) * 8; i++) { -+ if (CPU_ISSET(i, &cpus)) -+ mask |= 1 << i; -+ } -+ -+ write_log(DEBUG, "affinity: 0x%zx", mask); -+} -+ - void nsexec(void) - { - int pipenum; -@@ -584,6 +603,16 @@ void nsexec(void) - - write_log(DEBUG, "=> nsexec container setup"); - -+ /* This is for ../../tests/integration/cpu_affinity.bats test only. -+ * -+ * Printing this from Go code might be too late as some kernels -+ * change the process' CPU affinity to that of container's cpuset -+ * as soon as the process is moved into container's cgroup. -+ */ -+ if (log_enabled_for(DEBUG)) { -+ print_cpu_affinity(); -+ } -+ - /* Parse all of the netlink configuration. */ - nl_parse(pipenum, &config); - -diff --git a/libcontainer/process.go b/libcontainer/process.go -index 114b3f2b..5339583f 100644 ---- a/libcontainer/process.go -+++ b/libcontainer/process.go -@@ -102,6 +102,8 @@ type Process struct { - Scheduler *configs.Scheduler - - IOPriority *configs.IOPriority -+ -+ CPUAffinity *configs.CPUAffinity - } - - // Wait waits for the process to exit. -diff --git a/libcontainer/process_linux.go b/libcontainer/process_linux.go -index fcbb54a3..477c8a77 100644 ---- a/libcontainer/process_linux.go -+++ b/libcontainer/process_linux.go -@@ -122,6 +122,46 @@ func (p *setnsProcess) signal(sig os.Signal) error { - return unix.Kill(p.pid(), s) - } - -+// Starts setns process with specified initial CPU affinity. -+func (p *setnsProcess) startWithCPUAffinity() error { -+ aff := p.config.CPUAffinity -+ if aff == nil || aff.Initial == nil { -+ return p.cmd.Start() -+ } -+ errCh := make(chan error) -+ defer close(errCh) -+ -+ // Use a goroutine to dedicate an OS thread. -+ go func() { -+ runtime.LockOSThread() -+ // Command inherits the CPU affinity. -+ if err := unix.SchedSetaffinity(unix.Gettid(), aff.Initial); err != nil { -+ runtime.UnlockOSThread() -+ errCh <- fmt.Errorf("error setting initial CPU affinity: %w", err) -+ return -+ } -+ -+ errCh <- p.cmd.Start() -+ // Deliberately omit runtime.UnlockOSThread here. -+ // https://pkg.go.dev/runtime#LockOSThread says: -+ // "If the calling goroutine exits without unlocking the -+ // thread, the thread will be terminated". -+ }() -+ -+ return <-errCh -+} -+ -+func (p *setnsProcess) setFinalCPUAffinity() error { -+ aff := p.config.CPUAffinity -+ if aff == nil || aff.Final == nil { -+ return nil -+ } -+ if err := unix.SchedSetaffinity(p.pid(), aff.Final); err != nil { -+ return fmt.Errorf("error setting final CPU affinity: %w", err) -+ } -+ return nil -+} -+ - func (p *setnsProcess) start() (retErr error) { - defer p.comm.closeParent() - -@@ -133,8 +173,8 @@ func (p *setnsProcess) start() (retErr error) { - - // get the "before" value of oom kill count - oom, _ := p.manager.OOMKillCount() -- err := p.cmd.Start() -- // close the child-side of the pipes (controlled by child) -+ err := p.startWithCPUAffinity() -+ // Close the child-side of the pipes (controlled by child). - p.comm.closeChild() - if err != nil { - return fmt.Errorf("error starting setns process: %w", err) -@@ -184,6 +224,10 @@ func (p *setnsProcess) start() (retErr error) { - } - } - } -+ // Set final CPU affinity right after the process is moved into container's cgroup. -+ if err := p.setFinalCPUAffinity(); err != nil { -+ return err -+ } - if p.intelRdtPath != "" { - // if Intel RDT "resource control" filesystem path exists - _, err := os.Stat(p.intelRdtPath) -@@ -193,7 +237,6 @@ func (p *setnsProcess) start() (retErr error) { - } - } - } -- - if err := utils.WriteJSON(p.comm.initSockParent, p.config); err != nil { - return fmt.Errorf("error writing config to pipe: %w", err) - } -diff --git a/libcontainer/specconv/spec_linux.go b/libcontainer/specconv/spec_linux.go -index 95ada499..2d0db342 100644 ---- a/libcontainer/specconv/spec_linux.go -+++ b/libcontainer/specconv/spec_linux.go -@@ -556,6 +556,11 @@ func CreateLibcontainerConfig(opts *CreateOpts) (*configs.Config, error) { - ioPriority := *spec.Process.IOPriority - config.IOPriority = &ioPriority - } -+ config.ExecCPUAffinity, err = configs.ConvertCPUAffinity(spec.Process.ExecCPUAffinity) -+ if err != nil { -+ return nil, err -+ } -+ - } - createHooks(spec, config) - config.Version = specs.Version -diff --git a/tests/integration/cpu_affinity.bats b/tests/integration/cpu_affinity.bats -new file mode 100644 -index 00000000..f6adfa2a ---- /dev/null -+++ b/tests/integration/cpu_affinity.bats -@@ -0,0 +1,101 @@ -+#!/usr/bin/env bats -+# Exec CPU affinity tests. For more details, see: -+# - https://github.com/opencontainers/runtime-spec/pull/1253 -+ -+load helpers -+ -+function setup() { -+ requires smp cgroups_cpuset -+ setup_busybox -+} -+ -+function teardown() { -+ teardown_bundle -+} -+ -+function first_cpu() { -+ sed 's/[-,].*//g' "-". -+ cpus=${cpus//-/ } # 2. "-" --> " ". -+ -+ for c in $cpus; do -+ mask=$((mask | 1 << c)) -+ done -+ -+ printf "0x%x" $mask -+} -+ -+@test "runc exec [CPU affinity, only initial set from process.json]" { -+ first="$(first_cpu)" -+ second=$((first + 1)) # Hacky; might not work in all environments. -+ -+ runc run -d --console-socket "$CONSOLE_SOCKET" ct1 -+ [ "$status" -eq 0 ] -+ -+ for cpus in "$second" "$first-$second" "$first,$second" "$first"; do -+ proc=' -+{ -+ "terminal": false, -+ "execCPUAffinity": { -+ "initial": "'$cpus'" -+ }, -+ "args": [ "/bin/true" ], -+ "cwd": "/" -+}' -+ mask=$(cpus_to_mask "$cpus") -+ echo "CPUS: $cpus, mask: $mask" -+ runc --debug exec --process <(echo "$proc") ct1 -+ [[ "$output" == *"nsexec"*": affinity: $mask"* ]] -+ done -+} -+ -+@test "runc exec [CPU affinity, initial and final set from process.json]" { -+ first="$(first_cpu)" -+ second=$((first + 1)) # Hacky; might not work in all environments. -+ -+ runc run -d --console-socket "$CONSOLE_SOCKET" ct1 -+ [ "$status" -eq 0 ] -+ -+ for cpus in "$second" "$first-$second" "$first,$second" "$first"; do -+ proc=' -+{ -+ "terminal": false, -+ "execCPUAffinity": { -+ "initial": "'$cpus'", -+ "final": "'$cpus'" -+ }, -+ "args": [ "/bin/grep", "-F", "Cpus_allowed_list:", "/proc/self/status" ], -+ "cwd": "/" -+}' -+ mask=$(cpus_to_mask "$cpus") -+ exp=${cpus//,/-} # "," --> "-". -+ echo "CPUS: $cpus, mask: $mask, final: $exp" -+ runc --debug exec --process <(echo "$proc") ct1 -+ [[ "$output" == *"nsexec"*": affinity: $mask"* ]] -+ [[ "$output" == *"Cpus_allowed_list: $exp"* ]] # Mind the literal tab. -+ done -+} -+ -+@test "runc exec [CPU affinity, initial and final set from config.json]" { -+ initial="$(first_cpu)" -+ final=$((initial + 1)) # Hacky; might not work in all environments. -+ -+ update_config " .process.execCPUAffinity.initial = \"$initial\" -+ | .process.execCPUAffinity.final = \"$final\"" -+ -+ runc run -d --console-socket "$CONSOLE_SOCKET" ct1 -+ [ "$status" -eq 0 ] -+ -+ runc --debug exec ct1 grep "Cpus_allowed_list:" /proc/self/status -+ [ "$status" -eq 0 ] -+ mask=$(cpus_to_mask "$initial") -+ [[ "$output" == *"nsexec"*": affinity: $mask"* ]] -+ [[ "$output" == *"Cpus_allowed_list: $final"* ]] # Mind the literal tab. -+} -diff --git a/utils_linux.go b/utils_linux.go -index feb6ef80..013dbcf4 100644 ---- a/utils_linux.go -+++ b/utils_linux.go -@@ -90,6 +90,12 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) { - } - lp.Rlimits = append(lp.Rlimits, rl) - } -+ aff, err := configs.ConvertCPUAffinity(p.ExecCPUAffinity) -+ if err != nil { -+ return nil, err -+ } -+ lp.CPUAffinity = aff -+ - return lp, nil - } - --- -2.47.1 - diff --git a/SPECS/runc.spec b/SPECS/runc.spec index 566771f..10290f8 100644 --- a/SPECS/runc.spec +++ b/SPECS/runc.spec @@ -19,8 +19,8 @@ go build -buildmode pie -compiler gc -tags="rpm_crashtraceback libtrust_openssl Epoch: 4 Name: %{repo} -Version: 1.2.5 -Release: 3%{?dist} +Version: 1.3.0 +Release: 4%{?dist} Summary: CLI for running Open Containers # https://fedoraproject.org/wiki/PackagingDrafts/Go#Go_Language_Architectures #ExclusiveArch: %%{go_arches} @@ -30,11 +30,9 @@ ExcludeArch: %{ix86} License: ASL 2.0 URL: %{git0} Source0: %{git0}/archive/v%{version}.tar.gz -Patch0: 0001-Bump-runtime-spec-to-latest-git-HEAD.patch -Patch1: 0002-runc-exec-implement-CPU-affinity.patch -Patch2: 0001-1.2.5-1.el9-CVEs-mega-patch.patch -Patch3: 0001-1.2-openat2-improve-resilience-on-busy-systems.patch -Patch4: 0002-1.2-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch +Patch0: 0001-1.3.0-CVEs-mega-patch.patch +Patch1: 0001-1.3-openat2-improve-resilience-on-busy-systems.patch +Patch2: 0002-1.3-rootfs-re-allow-dangling-symlinks-in-mount-targe.patch Provides: oci-runtime BuildRequires: golang >= 1.22.4 BuildRequires: git @@ -89,15 +87,27 @@ make install install-man install-bash DESTDIR=$RPM_BUILD_ROOT PREFIX=%{_prefix} %{_datadir}/bash-completion/completions/%{name} %changelog -* Wed Nov 05 2025 Jindrich Novy - 4:1.2.5-3 -- Add relevant patches to CVEs -- Resolves: RHEL-122402 +* Thu Nov 06 2025 Jindrich Novy - 4:1.3.0-4 +- rename errors.go to errors_linux.go +- Related: RHEL-122400 -* Fri Oct 31 2025 Jindrich Novy - 4:1.2.5-2 +* Wed Nov 05 2025 Jindrich Novy - 4:1.3.0-3 +- Add relevant patches to CVEs +- Resolves: RHEL-122400 + +* Fri Oct 31 2025 Jindrich Novy - 4:1.3.0-2 - fix CVE-2025-31133 CVE-2025-52565 CVE-2025-52881 -- Resolves: RHEL-122402 -- Resolves: RHEL-122404 -- Resolves: RHEL-122415 +- Resolves: RHEL-122400 +- Resolves: RHEL-122403 +- Resolves: RHEL-122414 + +* Wed Apr 30 2025 Jindrich Novy - 4:1.3.0-1 +- update to https://github.com/opencontainers/runc/releases/tag/v1.3.0 +- Related: RHEL-80816 + +* Tue Mar 18 2025 Jindrich Novy - 4:1.2.6-1 +- update to https://github.com/opencontainers/runc/releases/tag/v1.2.6 +- Related: RHEL-80816 * Tue Feb 18 2025 Jindrich Novy - 4:1.2.5-1 - update to https://github.com/opencontainers/runc/releases/tag/v1.2.5