diff --git a/daemon/seccomp_linux_test.go b/daemon/seccomp_linux_test.go new file mode 100644 index 0000000000..013df72afd --- /dev/null +++ b/daemon/seccomp_linux_test.go @@ -0,0 +1,198 @@ +// +build linux,seccomp + +package daemon // import "github.com/docker/docker/daemon" + +import ( + "testing" + + coci "github.com/containerd/containerd/oci" + config "github.com/docker/docker/api/types/container" + "github.com/docker/docker/container" + doci "github.com/docker/docker/oci" + "github.com/docker/docker/profiles/seccomp" + specs "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 _, x := range []expected{ + { + comment: "unconfined seccompProfile runs unconfined", + daemon: &Daemon{ + seccompEnabled: true, + }, + c: &container.Container{ + SeccompProfile: "unconfined", + HostConfig: &config.HostConfig{ + Privileged: false, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: doci.DefaultLinuxSpec(), + }, + { + comment: "privileged container w/ custom profile runs unconfined", + daemon: &Daemon{ + seccompEnabled: true, + }, + c: &container.Container{ + SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_LOG\" }", + HostConfig: &config.HostConfig{ + Privileged: true, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: doci.DefaultLinuxSpec(), + }, + { + comment: "privileged container w/ default runs unconfined", + daemon: &Daemon{ + seccompEnabled: true, + }, + c: &container.Container{ + SeccompProfile: "", + HostConfig: &config.HostConfig{ + Privileged: true, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: doci.DefaultLinuxSpec(), + }, + { + comment: "privileged container w/ daemon profile runs unconfined", + daemon: &Daemon{ + seccompEnabled: true, + seccompProfile: []byte("{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }"), + }, + c: &container.Container{ + SeccompProfile: "", + HostConfig: &config.HostConfig{ + Privileged: true, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: doci.DefaultLinuxSpec(), + }, + { + comment: "custom profile when seccomp is disabled returns error", + daemon: &Daemon{ + seccompEnabled: false, + }, + c: &container.Container{ + SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }", + HostConfig: &config.HostConfig{ + Privileged: false, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: doci.DefaultLinuxSpec(), + err: "seccomp is not enabled in your kernel, cannot run a custom seccomp profile", + }, + { + comment: "empty profile name loads default profile", + daemon: &Daemon{ + seccompEnabled: true, + }, + c: &container.Container{ + SeccompProfile: "", + HostConfig: &config.HostConfig{ + Privileged: false, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: func() coci.Spec { + s := doci.DefaultLinuxSpec() + profile, _ := seccomp.GetDefaultProfile(&s) + s.Linux.Seccomp = profile + return s + }(), + }, + { + comment: "load container's profile", + daemon: &Daemon{ + seccompEnabled: true, + }, + c: &container.Container{ + SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }", + HostConfig: &config.HostConfig{ + Privileged: false, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: func() coci.Spec { + s := doci.DefaultLinuxSpec() + profile := &specs.LinuxSeccomp{ + DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_ERRNO"), + } + s.Linux.Seccomp = profile + return s + }(), + }, + { + comment: "load daemon's profile", + daemon: &Daemon{ + seccompEnabled: true, + seccompProfile: []byte("{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }"), + }, + c: &container.Container{ + SeccompProfile: "", + HostConfig: &config.HostConfig{ + Privileged: false, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: func() coci.Spec { + s := doci.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{ + seccompEnabled: true, + seccompProfile: []byte("{ \"defaultAction\": \"SCMP_ACT_ERRNO\" }"), + }, + c: &container.Container{ + SeccompProfile: "{ \"defaultAction\": \"SCMP_ACT_LOG\" }", + HostConfig: &config.HostConfig{ + Privileged: false, + }, + }, + inSpec: doci.DefaultLinuxSpec(), + outSpec: func() coci.Spec { + s := doci.DefaultLinuxSpec() + profile := &specs.LinuxSeccomp{ + DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_LOG"), + } + s.Linux.Seccomp = profile + return s + }(), + }, + } { + t.Run(x.comment, func(t *testing.T) { + opts := WithSeccomp(x.daemon, x.c) + err := opts(nil, nil, nil, &x.inSpec) + + assert.DeepEqual(t, x.inSpec, x.outSpec) + if x.err != "" { + assert.Error(t, err, x.err) + } else { + assert.NilError(t, err) + } + }) + } +}