mirror of
https://github.com/podman-container-tools/podman.git
synced 2026-10-14 01:47:43 +00:00
Docker clients send the seccomp profile JSON itself in HostConfig.SecurityOpt (the docker CLI reads the profile file client-side and inlines it). The compat API treated the value as a path to a profile file, so container create failed with "file name too long". This breaks docker-compat tooling that passes seccomp profiles through the socket, like Nextcloud AIO and forgejo-runner. Add a SeccompProfile field to specgen for inline profile content, next to the existing SeccompProfilePath, as requested in review of the earlier PR that tried to fix this (#28985). The compat create handler extracts inline profiles (values starting with "{") from SecurityOpt and sets the new field. Path-based values and "unconfined" keep their current meaning, and duplicate seccomp options resolve last-one-wins, like docker. Fixes: #27710 Signed-off-by: r-vdp <ramses@well-founded.dev>
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
//go:build !remote && (linux || freebsd)
|
|
|
|
package compat
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestExtractInlineSeccompProfile(t *testing.T) {
|
|
inlineProfile := `{"defaultAction":"SCMP_ACT_ALLOW"}`
|
|
|
|
tests := []struct {
|
|
name string
|
|
opts []string
|
|
expectedProfile string
|
|
expectedRest []string
|
|
}{
|
|
{
|
|
name: "no security opts",
|
|
opts: nil,
|
|
expectedProfile: "",
|
|
expectedRest: nil,
|
|
},
|
|
{
|
|
name: "path stays untouched",
|
|
opts: []string{"seccomp=/some/path.json"},
|
|
expectedProfile: "",
|
|
expectedRest: []string{"seccomp=/some/path.json"},
|
|
},
|
|
{
|
|
name: "unconfined stays untouched",
|
|
opts: []string{"seccomp=unconfined"},
|
|
expectedProfile: "",
|
|
expectedRest: []string{"seccomp=unconfined"},
|
|
},
|
|
{
|
|
name: "inline json is extracted",
|
|
opts: []string{"seccomp=" + inlineProfile},
|
|
expectedProfile: inlineProfile,
|
|
expectedRest: []string{},
|
|
},
|
|
{
|
|
name: "inline json with leading whitespace",
|
|
opts: []string{"seccomp= \n\t" + inlineProfile},
|
|
expectedProfile: " \n\t" + inlineProfile,
|
|
expectedRest: []string{},
|
|
},
|
|
{
|
|
name: "deprecated colon separator",
|
|
opts: []string{"seccomp:" + inlineProfile},
|
|
expectedProfile: inlineProfile,
|
|
expectedRest: []string{},
|
|
},
|
|
{
|
|
name: "other options are preserved",
|
|
opts: []string{"label=disable", "seccomp=" + inlineProfile, "no-new-privileges"},
|
|
expectedProfile: inlineProfile,
|
|
expectedRest: []string{"label=disable", "no-new-privileges"},
|
|
},
|
|
{
|
|
name: "duplicate, last inline wins",
|
|
opts: []string{"seccomp=/some/path.json", "seccomp=" + inlineProfile},
|
|
expectedProfile: inlineProfile,
|
|
expectedRest: []string{},
|
|
},
|
|
{
|
|
name: "duplicate, last path wins",
|
|
opts: []string{"seccomp=" + inlineProfile, "seccomp=/some/path.json"},
|
|
expectedProfile: "",
|
|
expectedRest: []string{"seccomp=/some/path.json"},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
profile, rest := extractInlineSeccompProfile(test.opts)
|
|
assert.Equal(t, test.expectedProfile, profile)
|
|
assert.Equal(t, test.expectedRest, rest)
|
|
})
|
|
}
|
|
}
|