diff --git a/profiles/seccomp/fixtures/conditional_include.json b/profiles/seccomp/fixtures/conditional_include.json new file mode 100644 index 0000000000..09a3d2a700 --- /dev/null +++ b/profiles/seccomp/fixtures/conditional_include.json @@ -0,0 +1,23 @@ +{ + "defaultAction": "SCMP_ACT_ERRNO", + "syscalls": [ + { + "names": ["chmod"], + "action": "SCMP_ACT_ALLOW" + }, + { + "names": ["syslog"], + "action": "SCMP_ACT_ALLOW", + "includes": { + "caps": ["CAP_SYSLOG"] + } + }, + { + "names": ["ptrace"], + "action": "SCMP_ACT_ALLOW", + "excludes": { + "caps": ["CAP_SYS_ADMIN"] + } + } + ] +} diff --git a/profiles/seccomp/seccomp_test.go b/profiles/seccomp/seccomp_test.go index 1003001bc2..a848f3992e 100644 --- a/profiles/seccomp/seccomp_test.go +++ b/profiles/seccomp/seccomp_test.go @@ -6,7 +6,7 @@ import ( "io/ioutil" "testing" - "github.com/docker/docker/oci" + "github.com/opencontainers/runtime-spec/specs-go" ) func TestLoadProfile(t *testing.T) { @@ -14,7 +14,7 @@ func TestLoadProfile(t *testing.T) { if err != nil { t.Fatal(err) } - rs := oci.DefaultSpec() + rs := createSpec() if _, err := LoadProfile(string(f), &rs); err != nil { t.Fatal(err) } @@ -27,7 +27,7 @@ func TestLoadLegacyProfile(t *testing.T) { if err != nil { t.Fatal(err) } - rs := oci.DefaultSpec() + rs := createSpec() if _, err := LoadProfile(string(f), &rs); err != nil { t.Fatal(err) } @@ -38,8 +38,56 @@ func TestLoadDefaultProfile(t *testing.T) { if err != nil { t.Fatal(err) } - rs := oci.DefaultSpec() + rs := createSpec() if _, err := LoadProfile(string(f), &rs); err != nil { t.Fatal(err) } } + +func TestLoadConditional(t *testing.T) { + f, err := ioutil.ReadFile("fixtures/conditional_include.json") + if err != nil { + t.Fatal(err) + } + tests := []struct { + doc string + cap string + expected []string + }{ + {doc: "no caps", expected: []string{"chmod", "ptrace"}}, + {doc: "with syslog", cap: "CAP_SYSLOG", expected: []string{"chmod", "syslog", "ptrace"}}, + {doc: "no ptrace", cap: "CAP_SYS_ADMIN", expected: []string{"chmod"}}, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.doc, func(t *testing.T) { + rs := createSpec(tc.cap) + p, err := LoadProfile(string(f), &rs) + if err != nil { + t.Fatal(err) + } + if len(p.Syscalls) != len(tc.expected) { + t.Fatalf("expected %d syscalls in profile, have %d", len(tc.expected), len(p.Syscalls)) + } + for i, v := range p.Syscalls { + if v.Names[0] != tc.expected[i] { + t.Fatalf("expected %s syscall, have %s", tc.expected[i], v.Names[0]) + } + } + }) + } +} + +// createSpec() creates a minimum spec for testing +func createSpec(caps ...string) specs.Spec { + rs := specs.Spec{ + Process: &specs.Process{ + Capabilities: &specs.LinuxCapabilities{}, + }, + } + if caps != nil { + rs.Process.Capabilities.Bounding = append(rs.Process.Capabilities.Bounding, caps...) + } + return rs +}