Files
moby/daemon/seccomp_linux_test.go
Derek McGowan f74e5d48b3 Create github.com/moby/moby/v2 module
Signed-off-by: Derek McGowan <derek@mcg.dev>
2025-07-31 10:13:29 -07:00

207 lines
5.7 KiB
Go

package daemon
import (
"testing"
coci "github.com/containerd/containerd/v2/pkg/oci"
containertypes "github.com/moby/moby/api/types/container"
dconfig "github.com/moby/moby/v2/daemon/config"
"github.com/moby/moby/v2/daemon/container"
"github.com/moby/moby/v2/daemon/pkg/oci"
"github.com/moby/moby/v2/pkg/sysinfo"
"github.com/moby/profiles/seccomp"
"github.com/opencontainers/runtime-spec/specs-go"
"gotest.tools/v3/assert"
)
func TestWithSeccomp(t *testing.T) {
type expected struct {
daemon *Daemon
c *container.Container
inSpec coci.Spec
outSpec coci.Spec
err string
comment string
}
for _, tc := range []expected{
{
comment: "unconfined seccompProfile runs unconfined",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: dconfig.SeccompProfileUnconfined},
HostConfig: &containertypes.HostConfig{
Privileged: false,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: oci.DefaultLinuxSpec(),
},
{
// Prior to Docker v27, it had resulted in unconfined.
// https://github.com/moby/moby/pull/47500
comment: "privileged container w/ custom profile",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: `{"defaultAction": "SCMP_ACT_LOG"}`},
HostConfig: &containertypes.HostConfig{
Privileged: true,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: func() coci.Spec {
s := oci.DefaultLinuxSpec()
profile := &specs.LinuxSeccomp{
DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_LOG"),
}
s.Linux.Seccomp = profile
return s
}(),
},
{
comment: "privileged container w/ default runs unconfined",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: ""},
HostConfig: &containertypes.HostConfig{
Privileged: true,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: oci.DefaultLinuxSpec(),
},
{
comment: "privileged container w/ daemon profile runs unconfined",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
seccompProfile: []byte(`{"defaultAction": "SCMP_ACT_ERRNO"}`),
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: ""},
HostConfig: &containertypes.HostConfig{
Privileged: true,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: oci.DefaultLinuxSpec(),
},
{
comment: "custom profile when seccomp is disabled returns error",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: false},
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: `{"defaultAction": "SCMP_ACT_ERRNO"}`},
HostConfig: &containertypes.HostConfig{
Privileged: false,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: oci.DefaultLinuxSpec(),
err: "seccomp is not enabled in your kernel, cannot run a custom seccomp profile",
},
{
comment: "empty profile name loads default profile",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: ""},
HostConfig: &containertypes.HostConfig{
Privileged: false,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: func() coci.Spec {
s := oci.DefaultLinuxSpec()
profile, _ := seccomp.GetDefaultProfile(&s)
s.Linux.Seccomp = profile
return s
}(),
},
{
comment: "load container's profile",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: `{"defaultAction": "SCMP_ACT_ERRNO"}`},
HostConfig: &containertypes.HostConfig{
Privileged: false,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: func() coci.Spec {
s := oci.DefaultLinuxSpec()
profile := &specs.LinuxSeccomp{
DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_ERRNO"),
}
s.Linux.Seccomp = profile
return s
}(),
},
{
comment: "load daemon's profile",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
seccompProfile: []byte(`{"defaultAction": "SCMP_ACT_ERRNO"}`),
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: ""},
HostConfig: &containertypes.HostConfig{
Privileged: false,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: func() coci.Spec {
s := oci.DefaultLinuxSpec()
profile := &specs.LinuxSeccomp{
DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_ERRNO"),
}
s.Linux.Seccomp = profile
return s
}(),
},
{
comment: "load prioritise container profile over daemon's",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
seccompProfile: []byte(`{"defaultAction": "SCMP_ACT_ERRNO"}`),
},
c: &container.Container{
SecurityOptions: container.SecurityOptions{SeccompProfile: `{"defaultAction": "SCMP_ACT_LOG"}`},
HostConfig: &containertypes.HostConfig{
Privileged: false,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: func() coci.Spec {
s := oci.DefaultLinuxSpec()
profile := &specs.LinuxSeccomp{
DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_LOG"),
}
s.Linux.Seccomp = profile
return s
}(),
},
} {
t.Run(tc.comment, func(t *testing.T) {
opts := WithSeccomp(tc.daemon, tc.c)
err := opts(nil, nil, nil, &tc.inSpec)
assert.DeepEqual(t, tc.inSpec, tc.outSpec)
if tc.err != "" {
assert.Error(t, err, tc.err)
} else {
assert.NilError(t, err)
}
})
}
}