mirror of
https://github.com/containers/podman.git
synced 2026-03-13 08:01:19 +08:00
Replace the JSON marshal/unmarshal round-trip in Inherit() with
copier.Copy. json.Unmarshal reuses existing slice backing arrays
and does not zero struct fields absent from the JSON (omitempty),
so mount options like "ro" from one mount would leak into another
mount at the same backing-array position.
Fixes the case where running:
podman run --pod mypod \
--mount type=bind,src=/a,target=/mylog \
--mount type=bind,src=/b,target=/mytmp,ro=true \
alpine touch /mylog/a
incorrectly fails with "Read-only file system" because /mylog
inherits "ro" from /mytmp.
Fixes: https://issues.redhat.com/browse/RHEL-154348
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
61 lines
1.8 KiB
Go
61 lines
1.8 KiB
Go
//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")
|
|
}
|