| package daemon // import "github.com/docker/docker/daemon" | |
| import ( | |
| "testing" | |
| coci "github.com/containerd/containerd/oci" | |
| containertypes "github.com/docker/docker/api/types/container" | |
| "github.com/docker/docker/container" | |
| dconfig "github.com/docker/docker/daemon/config" | |
| "github.com/docker/docker/oci" | |
| "github.com/docker/docker/pkg/sysinfo" | |
| "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{ | |
| 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(), | |
| }, | |
| { | |
| comment: "privileged container w/ custom profile runs unconfined", | |
| 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: oci.DefaultLinuxSpec(), | |
| }, | |
| { | |
| 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 | |
| }(), | |
| }, | |
| } { | |
| x := x | |
| 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) | |
| } | |
| }) | |
| } | |
| } |