[meta-virtualization][wrynose][PATCH] podman: fix CVE-2026-57231
"Deepak Rathore -X (deeratho - E INFOCHIPS PRIVATE LIMITED at Cisco)" <[email protected]> Thu, 23 Jul 2026 19:11:24 +0530
| Newsgroups | org.yoctoproject.lists.meta-virtualization |
|---|---|
| Message-ID | <[email protected]> |
From: Deepak Rathore <[email protected]> This patch applies the upstream v5.8 branch backport for CVE-2026-57231. The upstream fix commit is referenced in [1], and the public CVE advisory is referenced in [2]. The backported commit link is recorded in the embedded patch header. [1] https://github.com/podman-container-tools/podman/commit/85832029d537c2c0df89e47d4a03d55ba099a848 [2] https://security-tracker.debian.org/tracker/CVE-2026-57231 Signed-off-by: Deepak Rathore <[email protected]> --- .../podman/podman/CVE-2026-57231.patch | 219 ++++++++++++++++++ recipes-containers/podman/podman_git.bb | 1 + 2 files changed, 220 insertions(+) create mode 100644 recipes-containers/podman/podman/CVE-2026-57231.patch diff --git a/recipes-containers/podman/podman/CVE-2026-57231.patch b/recipes-containers/podman/podman/CVE-2026-57231.patch new file mode 100644 index 00000000..d24ee215 --- /dev/null +++ b/recipes-containers/podman/podman/CVE-2026-57231.patch @@ -0,0 +1,219 @@ +From a1c1b4c0354814cd55aac95ce98059dc8b88360d Mon Sep 17 00:00:00 2001 +From: Paul Holzinger <[email protected]> +Date: Wed, 17 Jun 2026 18:41:23 +0200 +Subject: [PATCH] fix image host env leak + +When parsing image envs we need to be strict about the format, only the +"key=value" format must be accepted. Just keys must be rejected as they +are not valid according to the image spec. + +CVE: CVE-2026-57231 +Upstream-Status: Backport [https://github.com/podman-container-tools/podman/commit/85832029d537c2c0df89e47d4a03d55ba099a848] + +Signed-off-by: Paul Holzinger <[email protected]> +(cherry picked from commit 6c431b73dbf8e4b20b778644d7a80caebdb75050) +Signed-off-by: Paul Holzinger <[email protected]> +(cherry picked from commit 85832029d537c2c0df89e47d4a03d55ba099a848) +Signed-off-by: Deepak Rathore <[email protected]> +--- + pkg/specgen/generate/container.go | 17 +++++-- + pkg/specgen/generate/container_test.go | 66 ++++++++++++++++++++++++++ + pkg/specgen/generate/kube/kube.go | 7 ++- + test/system/030-run.bats | 52 ++++++++++++++++++++ + 4 files changed, 135 insertions(+), 7 deletions(-) + create mode 100644 pkg/specgen/generate/container_test.go + +diff --git a/pkg/specgen/generate/container.go b/pkg/specgen/generate/container.go +index 4d60cb3142..fd610cfc3f 100644 +--- a/pkg/specgen/generate/container.go ++++ b/pkg/specgen/generate/container.go +@@ -123,6 +123,18 @@ func applyHealthCheckOverrides(s *specgen.SpecGenerator, healthCheckFromImage *m + return nil + } + ++func ParseImageEnvs(imageEnvs []string) (map[string]string, error) { ++ envs := make(map[string]string, len(imageEnvs)) ++ for _, env := range imageEnvs { ++ key, val, hasValue := strings.Cut(env, "=") ++ if !hasValue || key == "" { ++ return nil, fmt.Errorf("invalid image env variable %q", env) ++ } ++ envs[key] = val ++ } ++ return envs, nil ++} ++ + // Fill any missing parts of the spec generator (e.g. from the image). + // Returns a set of warnings or any fatal error that occurred. + func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerator) ([]string, error) { +@@ -168,15 +180,14 @@ func CompleteSpec(ctx context.Context, r *libpod.Runtime, s *specgen.SpecGenerat + if err != nil { + return nil, fmt.Errorf("parsing fields in containers.conf: %w", err) + } +- var envs map[string]string + + // Image Environment defaults + if inspectData != nil { + // Image envs from the image if they don't exist + // already, overriding the default environments +- envs, err = envLib.ParseSlice(inspectData.Config.Env) ++ envs, err := ParseImageEnvs(inspectData.Config.Env) + if err != nil { +- return nil, fmt.Errorf("env fields from image failed to parse: %w", err) ++ return nil, err + } + defaultEnvs = envLib.Join(envLib.DefaultEnvVariables(), envLib.Join(defaultEnvs, envs)) + } +diff --git a/pkg/specgen/generate/container_test.go b/pkg/specgen/generate/container_test.go +new file mode 100644 +index 0000000000..22a64330b1 +--- /dev/null ++++ b/pkg/specgen/generate/container_test.go +@@ -0,0 +1,66 @@ ++//go:build !remote && (linux || freebsd) ++ ++package generate ++ ++import ( ++ "testing" ++ ++ "github.com/stretchr/testify/assert" ++ "github.com/stretchr/testify/require" ++) ++ ++func TestParseImageEnvs(t *testing.T) { ++ tests := []struct { ++ name string ++ imageEnvs []string ++ want map[string]string ++ wantErr bool ++ }{ ++ { ++ name: "no env", ++ want: map[string]string{}, ++ }, ++ { ++ name: "single env", ++ imageEnvs: []string{"TEST=1"}, ++ want: map[string]string{ ++ "TEST": "1", ++ }, ++ }, ++ { ++ name: "multiple envs", ++ imageEnvs: []string{"TEST=1", "ABC=b", "PATH=/bin"}, ++ want: map[string]string{ ++ "TEST": "1", ++ "ABC": "b", ++ "PATH": "/bin", ++ }, ++ }, ++ { ++ name: "invalid env without value", ++ imageEnvs: []string{"HOST"}, ++ wantErr: true, ++ }, ++ { ++ name: "invalid env asterisk", ++ imageEnvs: []string{"*"}, ++ wantErr: true, ++ }, ++ { ++ name: "invalid env no key", ++ imageEnvs: []string{"=123"}, ++ wantErr: true, ++ }, ++ } ++ for _, tt := range tests { ++ t.Run(tt.name, func(t *testing.T) { ++ got, err := ParseImageEnvs(tt.imageEnvs) ++ if tt.wantErr { ++ require.Error(t, err) ++ return ++ } ++ ++ assert.Equal(t, tt.want, got) ++ }) ++ } ++} +diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go +index d820ce1d3e..0db1920c1b 100644 +--- a/pkg/specgen/generate/kube/kube.go ++++ b/pkg/specgen/generate/kube/kube.go +@@ -479,10 +479,9 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener + s.Annotations[define.KubeHealthCheckAnnotation] = "true" + + // Environment Variables +- envs := map[string]string{} +- for _, env := range imageData.Config.Env { +- key, val, _ := strings.Cut(env, "=") +- envs[key] = val ++ envs, err := generate.ParseImageEnvs(imageData.Config.Env) ++ if err != nil { ++ return nil, err + } + + // Process envFrom first (lower precedence) +diff --git a/test/system/030-run.bats b/test/system/030-run.bats +index ed8f148c91..9b33a6fb1d 100644 +--- a/test/system/030-run.bats ++++ b/test/system/030-run.bats +@@ -1911,4 +1911,56 @@ EOF + run_podman rmi $image + } + ++@test "podman run host env leak" { ++ # We need to create a invalid image config env value without "=" ++ skopeo copy containers-storage:$IMAGE dir:$PODMAN_TMPDIR ++ config_digest=$(jq -r .config.digest $PODMAN_TMPDIR/manifest.json) ++ plain_digest=${config_digest#*:} ++ newfile="$PODMAN_TMPDIR/newfile" ++ # Append bad env to existing image envs ++ jq '.config.Env += ["HOST*"]' $PODMAN_TMPDIR/$plain_digest >$newfile ++ # Get new digest and size so we can update the manifest ++ newdigest="$(sha256sum $newfile | cut -d" " -f 1)" ++ size=$(stat -c %s $newfile) ++ mv $newfile $PODMAN_TMPDIR/$newdigest ++ jq ".config.digest = \"sha256:$newdigest\" | .config.size=$size" $PODMAN_TMPDIR/manifest.json > $PODMAN_TMPDIR/manifest.json.new ++ mv $PODMAN_TMPDIR/manifest.json.new $PODMAN_TMPDIR/manifest.json ++ ++ image="localhost/envimage:123" ++ skopeo copy dir:$PODMAN_TMPDIR containers-storage:$image ++ ++ run_podman image inspect $image --format '{{.Config.Env}}' ++ assert "$output" =~ "HOST\*" "invalid env in image" ++ ++ HOSTENV=123 run_podman 125 run --rm $image printenv HOSTENV ++ assert "$output" =~ 'invalid image env variable "HOST\*"' "Host env leak from image env on podman run" ++ ++ podname="p-$(safename)" ++ ctrname="c-$(safename)" ++ ++ fname="$PODMAN_TMPDIR/kube_$(safename).yaml" ++ echo " ++apiVersion: v1 ++kind: Pod ++metadata: ++ labels: ++ app: test ++ name: $podname ++spec: ++ restartPolicy: Never ++ containers: ++ - name: $ctrname ++ image: $image ++ command: ++ - printenv ++ - HOSTENV ++" > $fname ++ ++ run_podman 125 kube play $fname ++ assert "$output" =~ 'invalid image env variable "HOST\*"' "Host env leak from image env on kube play" ++ ++ run_podman pod rm $podname ++ run_podman rmi $image ++} ++ + # vim: filetype=sh +-- +2.51.0 diff --git a/recipes-containers/podman/podman_git.bb b/recipes-containers/podman/podman_git.bb index 886d6e90..7dde3880 100644 --- a/recipes-containers/podman/podman_git.bb +++ b/recipes-containers/podman/podman_git.bb @@ -20,6 +20,7 @@ SRCREV = "88c5aaeec667af94c4fe3a5c2c7a42f8cf308b93" SRC_URI = " \ git://github.com/containers/podman.git;branch=v5.8;protocol=https;destsuffix=${GO_SRCURI_DESTSUFFIX} \ ${@bb.utils.contains('PACKAGECONFIG', 'rootless', 'file://50-podman-rootless.conf', '', d)} \ + file://CVE-2026-57231.patch;patchdir=src/import \ " LICENSE = "Apache-2.0" -- 2.35.6