Merge pull request #28229 from giuseppe/fix-mount-opts-leak

specgen: fix pod mount options leaking between mounts
This commit is contained in:
Jan Rodák
2026-03-10 12:40:15 +01:00
committed by GitHub
3 changed files with 68 additions and 7 deletions

2
go.mod
View File

@@ -33,6 +33,7 @@ require (
github.com/gorilla/schema v1.4.1
github.com/hashicorp/go-multierror v1.1.1
github.com/hugelgupf/p9 v0.3.1-0.20250420164440-abc96d20b308
github.com/jinzhu/copier v0.4.0
github.com/json-iterator/go v1.1.12
github.com/kevinburke/ssh_config v1.5.0
github.com/klauspost/pgzip v1.2.6
@@ -130,7 +131,6 @@ require (
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jinzhu/copier v0.4.0 // indirect
github.com/klauspost/compress v1.18.4 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect

View File

@@ -18,6 +18,7 @@ import (
"github.com/containers/podman/v6/pkg/specgen"
"github.com/containers/podman/v6/pkg/specgenutil"
"github.com/containers/podman/v6/pkg/util"
"github.com/jinzhu/copier"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/selinux/go-selinux"
"github.com/sirupsen/logrus"
@@ -740,12 +741,7 @@ func Inherit(infra *libpod.Container, s *specgen.SpecGenerator, rt *libpod.Runti
compatibleOptions.SelinuxOpts = append(compatibleOptions.SelinuxOpts, s.SelinuxOpts...)
compatibleOptions.Volumes = append(compatibleOptions.Volumes, s.Volumes...)
compatByte, err := json.Marshal(compatibleOptions)
if err != nil {
return nil, nil, nil, err
}
err = json.Unmarshal(compatByte, s)
if err != nil {
if err := applyInfraInherit(compatibleOptions, s); err != nil {
return nil, nil, nil, err
}
@@ -760,3 +756,8 @@ func Inherit(infra *libpod.Container, s *specgen.SpecGenerator, rt *libpod.Runti
}
return options, infraSpec, compatibleOptions, nil
}
// applyInfraInherit copies the InfraInherit fields into the SpecGenerator.
func applyInfraInherit(compatibleOptions *libpod.InfraInherit, s *specgen.SpecGenerator) error {
return copier.CopyWithOption(s, compatibleOptions, copier.Option{IgnoreEmpty: true})
}

View File

@@ -0,0 +1,60 @@
//go:build !remote && (linux || freebsd)
package generate
import (
"testing"
"github.com/containers/podman/v6/libpod"
"github.com/containers/podman/v6/pkg/specgen"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestApplyInfraInheritMountOptionsDoNotLeak verifies that mount options from
// one mount do not leak into another when calling applyInfraInherit.
func TestApplyInfraInheritMountOptionsDoNotLeak(t *testing.T) {
compatibleOptions := &libpod.InfraInherit{
Mounts: []spec.Mount{
{Destination: "/mylog", Source: "/a", Type: "bind"},
{Destination: "/mytmp", Source: "/b", Type: "bind", Options: []string{"ro"}},
},
}
s := &specgen.SpecGenerator{}
s.Mounts = []spec.Mount{
{Destination: "/mytmp", Source: "/b", Type: "bind", Options: []string{"ro"}},
{Destination: "/mylog", Source: "/a", Type: "bind"},
}
err := applyInfraInherit(compatibleOptions, s)
require.NoError(t, err)
for _, m := range s.Mounts {
if m.Destination == "/mylog" {
assert.Empty(t, m.Options,
"/mylog should have no options; ro from /mytmp leaked")
}
if m.Destination == "/mytmp" {
assert.Equal(t, []string{"ro"}, m.Options,
"/mytmp should keep its ro option")
}
}
}
// TestApplyInfraInheritDoesNotOverwriteSeccomp verifies that applyInfraInherit
// does not overwrite a pre-set SeccompProfilePath when the infra container has
// no seccomp profile (empty string).
func TestApplyInfraInheritDoesNotOverwriteSeccomp(t *testing.T) {
compatibleOptions := &libpod.InfraInherit{}
s := &specgen.SpecGenerator{}
s.SeccompProfilePath = "localhost/seccomp.json"
err := applyInfraInherit(compatibleOptions, s)
require.NoError(t, err)
assert.Equal(t, "localhost/seccomp.json", s.SeccompProfilePath,
"SeccompProfilePath should not be overwritten by empty infra value")
}