diff --git a/0011-fix-CVE-2025-9566.patch b/0011-fix-CVE-2025-9566.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6f3595cd28e98e369355d198bf10527d9954246 --- /dev/null +++ b/0011-fix-CVE-2025-9566.patch @@ -0,0 +1,145 @@ +From ca994186f07822b9048fe711b6903e51614d3e15 Mon Sep 17 00:00:00 2001 +From: Paul Holzinger +Date: Fri, 29 Aug 2025 15:39:38 +0200 +Subject: [PATCH] kube play: don't follow volume symlinks onto the host + +For ConfigMap and Secret kube play volumes podman populates the data +from the yaml. However the volume content is not controlled by us and we +can be tricked following a symlink to a file on the host instead. + +Fixes: CVE-2025-9566 + +Signed-off-by: Paul Holzinger +(cherry picked from commit 43fbde4e665fe6cee6921868f04b7ccd3de5ad89) +Signed-off-by: Paul Holzinger +--- + pkg/domain/infra/abi/play.go | 5 ++- + pkg/domain/infra/abi/play_linux.go | 18 +++++++++++ + pkg/domain/infra/abi/play_unsupported.go | 13 ++++++++ + pkg/domain/infra/abi/play_utils.go | 39 +++++++++++++++++++++++- + 4 files changed, 71 insertions(+), 4 deletions(-) + create mode 100644 pkg/domain/infra/abi/play_linux.go + create mode 100644 pkg/domain/infra/abi/play_unsupported.go + +diff --git a/pkg/domain/infra/abi/play.go b/pkg/domain/infra/abi/play.go +index 9d22e88cdb..6ee8f3ae90 100644 +--- a/pkg/domain/infra/abi/play.go ++++ b/pkg/domain/infra/abi/play.go +@@ -810,8 +810,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY + defaultMode := v.DefaultMode + // Create files and add data to the volume mountpoint based on the Items in the volume + for k, v := range v.Items { +- dataPath := filepath.Join(mountPoint, k) +- f, err := os.Create(dataPath) ++ f, err := openPathSafely(mountPoint, k) + if err != nil { + return nil, nil, fmt.Errorf("cannot create file %q at volume mountpoint %q: %w", k, mountPoint, err) + } +@@ -821,7 +820,7 @@ func (ic *ContainerEngine) playKubePod(ctx context.Context, podName string, podY + return nil, nil, err + } + // Set file permissions +- if err := os.Chmod(f.Name(), os.FileMode(defaultMode)); err != nil { ++ if err := f.Chmod(os.FileMode(defaultMode)); err != nil { + return nil, nil, err + } + } +diff --git a/pkg/domain/infra/abi/play_linux.go b/pkg/domain/infra/abi/play_linux.go +new file mode 100644 +index 0000000000..a0f9811516 +--- /dev/null ++++ b/pkg/domain/infra/abi/play_linux.go +@@ -0,0 +1,18 @@ ++//go:build !remote ++ ++package abi ++ ++import ( ++ "os" ++ ++ securejoin "github.com/cyphar/filepath-securejoin" ++) ++ ++// openSymlinkPath opens the path under root using securejoin.OpenatInRoot(). ++func openSymlinkPath(root *os.File, unsafePath string, flags int) (*os.File, error) { ++ file, err := securejoin.OpenatInRoot(root, unsafePath) ++ if err != nil { ++ return nil, err ++ } ++ return securejoin.Reopen(file, flags) ++} +diff --git a/pkg/domain/infra/abi/play_unsupported.go b/pkg/domain/infra/abi/play_unsupported.go +new file mode 100644 +index 0000000000..3ecbae7cc1 +--- /dev/null ++++ b/pkg/domain/infra/abi/play_unsupported.go +@@ -0,0 +1,13 @@ ++//go:build !linux && !remote ++ ++package abi ++ ++import ( ++ "errors" ++ "os" ++) ++ ++// openSymlinkPath is not supported on this platform. ++func openSymlinkPath(root *os.File, unsafePath string, flags int) (*os.File, error) { ++ return nil, errors.New("cannot safely open symlink on this platform") ++} +diff --git a/pkg/domain/infra/abi/play_utils.go b/pkg/domain/infra/abi/play_utils.go +index 7285d9c9b9..217b656997 100644 +--- a/pkg/domain/infra/abi/play_utils.go ++++ b/pkg/domain/infra/abi/play_utils.go +@@ -1,6 +1,13 @@ + package abi + +-import "github.com/containers/podman/v4/libpod/define" ++import ( ++ "fmt" ++ "os" ++ "strings" ++ ++ "github.com/containers/podman/v5/libpod/define" ++ "golang.org/x/sys/unix" ++) + + // getSdNotifyMode returns the `sdNotifyAnnotation/$name` for the specified + // name. If name is empty, it'll only look for `sdNotifyAnnotation`. +@@ -16,3 +23,33 @@ func getSdNotifyMode(annotations map[string]string, name string) (string, error) + } + return mode, define.ValidateSdNotifyMode(mode) + } ++ ++// openPathSafely opens the given name under the trusted root path, the unsafeName ++// must be a single path component and not contain "/". ++// The resulting path will be opened or created if it does not exists. ++// Following of symlink is done within staying under root, escapes outsides ++// of root are not allowed and prevent. ++// ++// This custom function is needed because securejoin.SecureJoin() is not race safe ++// and the volume might be mounted in another container that could swap in a symlink ++// after the function ahs run. securejoin.OpenInRoot() doesn't work either because ++// it cannot create files and doesn't work on freebsd. ++func openPathSafely(root, unsafeName string) (*os.File, error) { ++ if strings.Contains(unsafeName, "/") { ++ return nil, fmt.Errorf("name %q must not contain path separator", unsafeName) ++ } ++ fdDir, err := os.OpenFile(root, unix.O_RDONLY, 0) ++ if err != nil { ++ return nil, err ++ } ++ defer fdDir.Close() ++ flags := unix.O_CREAT | unix.O_WRONLY | unix.O_TRUNC | unix.O_CLOEXEC ++ fd, err := unix.Openat(int(fdDir.Fd()), unsafeName, flags|unix.O_NOFOLLOW, 0o644) ++ if err == nil { ++ return os.NewFile(uintptr(fd), unsafeName), nil ++ } ++ if err == unix.ELOOP { ++ return openSymlinkPath(fdDir, unsafeName, flags) ++ } ++ return nil, &os.PathError{Op: "openat", Path: unsafeName, Err: err} ++} +-- +2.20.1 + diff --git a/podman.spec b/podman.spec index 9a2cf544c9a1c7efa8961f06c69c9095106dd89b..ddb0a2c6a41a648ebc90d4efb1754ecb99873613 100644 --- a/podman.spec +++ b/podman.spec @@ -2,7 +2,7 @@ Name: podman Version: 4.9.4 -Release: 15 +Release: 16 Summary: A tool for managing OCI containers and pods. Epoch: 1 License: Apache-2.0 and MIT @@ -22,6 +22,7 @@ Patch0007: 0007-fix-CVE-2024-37298.patch Patch0008: 0008-fix-CVE-2024-6104.patch Patch0009: 0009-fix-CVE-2024-28176.patch Patch0010: 0010-fix-CVE-2024-3727.patch +Patch0011: 0011-fix-CVE-2025-9566.patch BuildRequires: gcc golang btrfs-progs-devel glib2-devel glibc-devel glibc-static BuildRequires: gpgme-devel libassuan-devel libgpg-error-devel libseccomp-devel libselinux-devel @@ -142,6 +143,7 @@ tar zxf %{SOURCE3} %patch 0008 -p1 %patch 0009 -p1 %patch 0010 -p1 +#%patch 0011 -p1 %ifarch loongarch64 cd dnsname-18822f9a4fb35d1349eb256f4cd2bfd372474d84 @@ -316,6 +318,9 @@ cp -pav test/system %{buildroot}/%{_datadir}/%{name}/test/ %{_bindir}/%{name}sh %changelog +* Mon Sep 08 2025 Yu Peng - 1:4.9.4-16 +- Fix CVE-2025-9566. + * Fri Jul 25 2025 lijian - 1:4.9.4-15 - Fix build error in go1.24 - Replace deprecated %patchN syntax with %patch -P N