spiegel_podman/pkg/specgen/generate/config_linux_seccomp_test.go
r-vdp 4ce2583ad7
compat API: accept inline seccomp profiles
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>
2026-09-24 10:31:00 +02:00

59 lines
1.7 KiB
Go

//go:build linux && !remote && seccomp
package generate
import (
"os"
"path/filepath"
"testing"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.podman.io/podman/v6/pkg/specgen"
)
const testSeccompProfile = `{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [
{
"names": ["link", "linkat"],
"action": "SCMP_ACT_ERRNO"
}
]
}`
func TestGetSeccompConfigFromFile(t *testing.T) {
profilePath := filepath.Join(t.TempDir(), "seccomp.json")
require.NoError(t, os.WriteFile(profilePath, []byte(testSeccompProfile), 0o600))
s := specgen.NewSpecGenerator("", false)
s.SeccompProfilePath = profilePath
config, err := getSeccompConfig(s, &spec.Spec{}, nil)
require.NoError(t, err)
assert.Equal(t, spec.ActAllow, config.DefaultAction)
require.Len(t, config.Syscalls, 1)
assert.Equal(t, spec.ActErrno, config.Syscalls[0].Action)
assert.Equal(t, []string{"link", "linkat"}, config.Syscalls[0].Names)
}
func TestGetSeccompConfigInline(t *testing.T) {
s := specgen.NewSpecGenerator("", false)
s.SeccompProfile = testSeccompProfile
config, err := getSeccompConfig(s, &spec.Spec{}, nil)
require.NoError(t, err)
assert.Equal(t, spec.ActAllow, config.DefaultAction)
require.Len(t, config.Syscalls, 1)
assert.Equal(t, spec.ActErrno, config.Syscalls[0].Action)
assert.Equal(t, []string{"link", "linkat"}, config.Syscalls[0].Names)
}
func TestGetSeccompConfigRejectsInvalidInlineProfile(t *testing.T) {
s := specgen.NewSpecGenerator("", false)
s.SeccompProfile = "{invalid JSON"
_, err := getSeccompConfig(s, &spec.Spec{}, nil)
require.ErrorContains(t, err, "loading inline seccomp profile failed")
}