From f098b9b06ec47e76fa04394a6b5d7390abd9ac4d Mon Sep 17 00:00:00 2001 From: Etienne Perot Date: Tue, 10 Oct 2023 14:07:40 -0700 Subject: [PATCH] `seccomp`: Make `SyscallRules` map type opaque. This wraps the `map[uintptry]SyscallRule` into an unexported field of a struct so that it cannot be accessed directly. This is helpful for the `runsc` and `fsgofer` seccomp filters which are quite complex and built across multiple files and multiple functions, where it is not always clear which order they are executed in. By forcing mutations to be more explicit about their intent (especially "merge with this new rule" vs "override what happens for this syscall with this new rule"), we can crash if that intent isn't what's actually happening. PiperOrigin-RevId: 572361619 --- pkg/seccomp/seccomp.go | 10 +- pkg/seccomp/seccomp_rules.go | 124 +++++++++++++----- pkg/seccomp/seccomp_test.go | 98 +++++++------- pkg/seccomp/victim/seccomp_test_victim.go | 10 +- .../victim/seccomp_test_victim_amd64.go | 8 +- .../victim/seccomp_test_victim_arm64.go | 2 +- pkg/sentry/devices/accel/seccomp_filters.go | 4 +- pkg/sentry/devices/nvproxy/seccomp_filters.go | 4 +- pkg/sentry/platform/kvm/filters.go | 6 +- pkg/sentry/platform/kvm/filters_amd64.go | 4 +- pkg/sentry/platform/kvm/filters_arm64.go | 4 +- pkg/sentry/platform/kvm/machine.go | 4 +- pkg/sentry/platform/ptrace/filters.go | 4 +- .../platform/ptrace/subprocess_amd64.go | 8 +- .../platform/ptrace/subprocess_linux.go | 4 +- pkg/sentry/platform/systrap/filters.go | 6 +- pkg/sentry/platform/systrap/filters_arm64.go | 4 +- .../platform/systrap/subprocess_amd64.go | 8 +- .../platform/systrap/subprocess_linux.go | 4 +- pkg/sentry/platform/systrap/sysmsg_thread.go | 4 +- .../platform/systrap/sysmsg_thread_amd64.go | 8 +- runsc/boot/filter/config.go | 12 +- runsc/boot/filter/config_amd64.go | 4 +- runsc/boot/filter/config_arm64.go | 4 +- runsc/boot/filter/config_profile.go | 4 +- runsc/boot/filter/extra_filters.go | 2 +- runsc/boot/filter/extra_filters_asan.go | 4 +- runsc/boot/filter/extra_filters_hostinet.go | 12 +- runsc/boot/filter/extra_filters_msan.go | 4 +- runsc/boot/filter/extra_filters_race.go | 4 +- runsc/boot/filter/extra_filters_race_amd64.go | 4 +- runsc/fsgofer/filter/config.go | 20 +-- runsc/fsgofer/filter/config_amd64.go | 7 +- runsc/fsgofer/filter/config_arm64.go | 7 +- runsc/fsgofer/filter/config_profile.go | 4 +- runsc/fsgofer/filter/extra_filters.go | 2 +- runsc/fsgofer/filter/extra_filters_msan.go | 4 +- runsc/fsgofer/filter/extra_filters_race.go | 4 +- .../filter/extra_filters_race_amd64.go | 4 +- runsc/specutils/seccomp/seccomp.go | 2 +- test/secbench/secbench.go | 5 +- 41 files changed, 247 insertions(+), 194 deletions(-) diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index 1f018fd96..e73930b3c 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -66,7 +66,7 @@ func Install(rules SyscallRules, denyRules SyscallRules) error { // below to get a panic stack trace when there is a violation. // defaultAction = linux.BPFAction(linux.SECCOMP_RET_TRAP) - log.Infof("Installing seccomp filters for %d syscalls (action=%v)", len(rules), defaultAction) + log.Infof("Installing seccomp filters for %d syscalls (action=%v)", rules.Size(), defaultAction) instrs, _, err := BuildProgram([]RuleSet{ { @@ -342,7 +342,7 @@ func buildIndex(rules []RuleSet, program *syscallProgram) error { // with different actions. The matchers are evaluated linearly. requiredSyscalls := make(map[uintptr]struct{}) for _, rs := range rules { - for sysno := range rs.Rules { + for sysno := range rs.Rules.rules { requiredSyscalls[sysno] = struct{}{} } } @@ -354,8 +354,8 @@ func buildIndex(rules []RuleSet, program *syscallProgram) error { for _, sysno := range syscalls { for _, rs := range rules { // Print only if there is a corresponding set of rules. - if _, ok := rs.Rules[sysno]; ok { - log.Debugf("syscall filter %v: %s => 0x%x", SyscallName(sysno), rs.Rules[sysno], rs.Action) + if r, ok := rs.Rules.rules[sysno]; ok { + log.Debugf("syscall filter %v: %s => 0x%x", SyscallName(sysno), r, rs.Action) } } } @@ -428,7 +428,7 @@ func buildBSTProgram(n *node, rules []RuleSet, program *syscallProgram) error { program.Label(checkArgsLabel) for ruleSetIdx, rs := range rules { - rule, ok := rs.Rules[sysno] + rule, ok := rs.Rules.rules[sysno] if !ok { continue } diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index 24bf8bf1f..7ec721268 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -399,35 +399,44 @@ func (pa PerArg) String() (s string) { // // For example: // -// rules := SyscallRules{ -// syscall.SYS_FUTEX: Or{ -// PerArg{ -// AnyValue{}, -// EqualTo(linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG), -// }, -// PerArg{ -// AnyValue{}, -// EqualTo(linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG), -// }, -// }, -// syscall.SYS_GETPID: MatchAll{}, -// -// } -type SyscallRules map[uintptr]SyscallRule +// rules := MakeSyscallRules(map[uintptr]SyscallRule{ +// syscall.SYS_FUTEX: Or{ +// PerArg{ +// AnyValue{}, +// EqualTo(linux.FUTEX_WAIT | linux.FUTEX_PRIVATE_FLAG), +// }, +// PerArg{ +// AnyValue{}, +// EqualTo(linux.FUTEX_WAKE | linux.FUTEX_PRIVATE_FLAG), +// }, +// }, +// syscall.SYS_GETPID: MatchAll{}, +// }) +type SyscallRules struct { + rules map[uintptr]SyscallRule +} // NewSyscallRules returns a new SyscallRules. func NewSyscallRules() SyscallRules { - return make(map[uintptr]SyscallRule) + return MakeSyscallRules(nil) +} + +// MakeSyscallRules returns a new SyscallRules with the given set of rules. +func MakeSyscallRules(rules map[uintptr]SyscallRule) SyscallRules { + if rules == nil { + rules = make(map[uintptr]SyscallRule) + } + return SyscallRules{rules: rules} } // String returns a string representation of the syscall rules, one syscall // per line. func (sr SyscallRules) String() string { - if len(sr) == 0 { + if len(sr.rules) == 0 { return "(no rules)" } - sysnums := make([]uintptr, 0, len(sr)) - for sysno := range sr { + sysnums := make([]uintptr, 0, len(sr.rules)) + for sysno := range sr.rules { sysnums = append(sysnums, sysno) } sort.Slice(sysnums, func(i, j int) bool { @@ -435,35 +444,82 @@ func (sr SyscallRules) String() string { }) var sb strings.Builder for _, sysno := range sysnums { - sb.WriteString(fmt.Sprintf("syscall %d: %v\n", sysno, sr[sysno])) + sb.WriteString(fmt.Sprintf("syscall %d: %v\n", sysno, sr.rules[sysno])) } return strings.TrimSpace(sb.String()) } -// AddRule adds the given rule. It will create a new entry for a new syscall, otherwise +// Size returns the number of syscall numbers for which a rule is defined. +func (sr SyscallRules) Size() int { + return len(sr.rules) +} + +// Get returns the rule defined for the given syscall number. +func (sr SyscallRules) Get(sysno uintptr) SyscallRule { + return sr.rules[sysno] +} + +// Has returns whether there is a rule defined for the given syscall number. +func (sr SyscallRules) Has(sysno uintptr) bool { + _, has := sr.rules[sysno] + return has +} + +// Add adds the given rule. It will create a new entry for a new syscall, otherwise // it will append to the existing rules. -func (sr SyscallRules) AddRule(sysno uintptr, r SyscallRule) { - if cur, ok := sr[sysno]; ok { - sr[sysno] = merge(cur, r) +// Returns itself for chainability. +func (sr SyscallRules) Add(sysno uintptr, r SyscallRule) SyscallRules { + if cur, ok := sr.rules[sysno]; ok { + sr.rules[sysno] = merge(cur, r) } else { - sr[sysno] = r + sr.rules[sysno] = r } + return sr +} + +// Set sets the rule for the given syscall number. +// Panics if there is already a rule for this syscall number. +// This is useful for deterministic rules where the set of syscall rules is +// added in multiple chunks but is known to never overlap by syscall number. +// Returns itself for chainability. +func (sr SyscallRules) Set(sysno uintptr, r SyscallRule) SyscallRules { + if cur, ok := sr.rules[sysno]; ok { + panic(fmt.Sprintf("tried to set syscall rule for sysno=%d to %v but it is already set to %v", sysno, r, cur)) + } + sr.rules[sysno] = r + return sr +} + +// Remove clears the syscall rule for the given syscall number. +// It will panic if there is no syscall rule for this syscall number. +func (sr SyscallRules) Remove(sysno uintptr) { + if !sr.Has(sysno) { + panic(fmt.Sprintf("tried to remove syscall rule for sysno=%d but it is not set", sysno)) + } + delete(sr.rules, sysno) } // Merge merges the given SyscallRules. -func (sr SyscallRules) Merge(other SyscallRules) { - for sysno, r := range other { - if cur, ok := sr[sysno]; ok { - sr[sysno] = merge(cur, r) - } else { - sr[sysno] = r - } +// Returns itself for chainability. +func (sr SyscallRules) Merge(other SyscallRules) SyscallRules { + for sysno, r := range other.rules { + sr.Add(sysno, r) } + return sr +} + +// Copy returns a copy of these SyscallRules. +func (sr SyscallRules) Copy() SyscallRules { + rulesCopy := make(map[uintptr]SyscallRule, len(sr.rules)) + for sysno, r := range sr.rules { + rulesCopy[sysno] = r + } + return MakeSyscallRules(rulesCopy) } // DenyNewExecMappings is a set of rules that denies creating new executable // mappings and converting existing ones. -var DenyNewExecMappings = SyscallRules{ +var DenyNewExecMappings = MakeSyscallRules(map[uintptr]SyscallRule{ unix.SYS_MMAP: PerArg{ AnyValue{}, AnyValue{}, @@ -474,4 +530,4 @@ var DenyNewExecMappings = SyscallRules{ AnyValue{}, MaskedEqual(unix.PROT_EXEC, unix.PROT_EXEC), }, -} +}) diff --git a/pkg/seccomp/seccomp_test.go b/pkg/seccomp/seccomp_test.go index 8954c5468..2675a2074 100644 --- a/pkg/seccomp/seccomp_test.go +++ b/pkg/seccomp/seccomp_test.go @@ -89,7 +89,7 @@ func TestBasic(t *testing.T) { name: "Single syscall", ruleSets: []RuleSet{ { - Rules: SyscallRules{1: MatchAll{}}, + Rules: MakeSyscallRules(map[uintptr]SyscallRule{1: MatchAll{}}), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -112,18 +112,18 @@ func TestBasic(t *testing.T) { name: "Multiple rulesets", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ EqualTo(0x1), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: MatchAll{}, 2: MatchAll{}, - }, + }), Action: linux.SECCOMP_RET_TRAP, }, }, @@ -156,11 +156,11 @@ func TestBasic(t *testing.T) { name: "Multiple syscalls", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: MatchAll{}, 3: MatchAll{}, 5: MatchAll{}, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -213,9 +213,9 @@ func TestBasic(t *testing.T) { name: "Wrong architecture", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: MatchAll{}, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -233,9 +233,9 @@ func TestBasic(t *testing.T) { name: "Syscall disallowed", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: MatchAll{}, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -253,12 +253,12 @@ func TestBasic(t *testing.T) { name: "Syscall arguments", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ AnyValue{}, EqualTo(0xf), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -281,7 +281,7 @@ func TestBasic(t *testing.T) { name: "Multiple arguments", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: Or{ PerArg{ EqualTo(0xf), @@ -290,7 +290,7 @@ func TestBasic(t *testing.T) { EqualTo(0xe), }, }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -318,13 +318,13 @@ func TestBasic(t *testing.T) { name: "EqualTo", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ EqualTo(0), EqualTo(math.MaxUint64 - 1), EqualTo(math.MaxUint32), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -364,13 +364,13 @@ func TestBasic(t *testing.T) { name: "NotEqual", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ NotEqual(0x7aabbccdd), NotEqual(math.MaxUint64 - 1), NotEqual(math.MaxUint32), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -410,7 +410,7 @@ func TestBasic(t *testing.T) { name: "GreaterThan", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ // 4294967298 // Both upper 32 bits and lower 32 bits are non-zero. @@ -418,7 +418,7 @@ func TestBasic(t *testing.T) { // 00000000000000000000000000000010 GreaterThan(0x00000002_00000002), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -456,12 +456,12 @@ func TestBasic(t *testing.T) { name: "GreaterThan (multi)", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ GreaterThan(0xf), GreaterThan(0xabcd000d), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -499,7 +499,7 @@ func TestBasic(t *testing.T) { name: "GreaterThanOrEqual", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ // 4294967298 // Both upper 32 bits and lower 32 bits are non-zero. @@ -507,7 +507,7 @@ func TestBasic(t *testing.T) { // 00000000000000000000000000000010 GreaterThanOrEqual(0x00000002_00000002), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -545,12 +545,12 @@ func TestBasic(t *testing.T) { name: "GreaterThanOrEqual (multi)", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ GreaterThanOrEqual(0xf), GreaterThanOrEqual(0xabcd000d), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -593,7 +593,7 @@ func TestBasic(t *testing.T) { name: "LessThan", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ // 4294967298 // Both upper 32 bits and lower 32 bits are non-zero. @@ -601,7 +601,7 @@ func TestBasic(t *testing.T) { // 00000000000000000000000000000010 LessThan(0x00000002_00000002), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -639,12 +639,12 @@ func TestBasic(t *testing.T) { name: "LessThan (multi)", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ LessThan(0x1), LessThan(0xabcd000d), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -687,7 +687,7 @@ func TestBasic(t *testing.T) { name: "LessThanOrEqual", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ // 4294967298 // Both upper 32 bits and lower 32 bits are non-zero. @@ -695,7 +695,7 @@ func TestBasic(t *testing.T) { // 00000000000000000000000000000010 LessThanOrEqual(0x00000002_00000002), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -734,12 +734,12 @@ func TestBasic(t *testing.T) { name: "LessThanOrEqual (multi)", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ LessThanOrEqual(0x1), LessThanOrEqual(0xabcd000d), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -782,14 +782,14 @@ func TestBasic(t *testing.T) { name: "MaskedEqual", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ // x & 00000001 00000011 (0x103) == 00000000 00000001 (0x1) // Input x must have lowest order bit set and // must *not* have 8th or second lowest order bit set. MaskedEqual(0x103, 0x1), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -852,11 +852,11 @@ func TestBasic(t *testing.T) { name: "Instruction Pointer", ruleSets: []RuleSet{ { - Rules: SyscallRules{ + Rules: MakeSyscallRules(map[uintptr]SyscallRule{ 1: PerArg{ RuleIP: EqualTo(0x7aabbccdd), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }, @@ -904,11 +904,11 @@ func TestBasic(t *testing.T) { func TestRandom(t *testing.T) { rand.Seed(time.Now().UnixNano()) size := rand.Intn(50) + 1 - syscallRules := make(map[uintptr]SyscallRule) - for len(syscallRules) < size { + syscallRules := NewSyscallRules() + for syscallRules.Size() < size { n := uintptr(rand.Intn(200)) - if _, ok := syscallRules[n]; !ok { - syscallRules[n] = MatchAll{} + if !syscallRules.Has(n) { + syscallRules.Set(n, MatchAll{}) } } @@ -934,7 +934,7 @@ func TestRandom(t *testing.T) { continue } want := linux.SECCOMP_RET_TRAP - if _, ok := syscallRules[uintptr(i)]; ok { + if syscallRules.Has(uintptr(i)) { want = linux.SECCOMP_RET_ALLOW } if got != uint32(want) { @@ -1027,10 +1027,12 @@ func TestMerge(t *testing.T) { }, } { t.Run(tst.name, func(t *testing.T) { - mainRules := SyscallRules{1: tst.main} - mergeRules := SyscallRules{1: tst.merge} - mainRules.Merge(mergeRules) - wantRules := SyscallRules{1: tst.want} + mainRules := MakeSyscallRules(map[uintptr]SyscallRule{ + 1: tst.main, + }).Merge(MakeSyscallRules(map[uintptr]SyscallRule{ + 1: tst.merge, + })) + wantRules := MakeSyscallRules(map[uintptr]SyscallRule{1: tst.want}) if !reflect.DeepEqual(mainRules, wantRules) { t.Errorf("got rules:\n%v\nwant rules:\n%v\n", mainRules, wantRules) } diff --git a/pkg/seccomp/victim/seccomp_test_victim.go b/pkg/seccomp/victim/seccomp_test_victim.go index 8b55d3a4f..88d0a40f1 100644 --- a/pkg/seccomp/victim/seccomp_test_victim.go +++ b/pkg/seccomp/victim/seccomp_test_victim.go @@ -29,7 +29,7 @@ func main() { dieFlag := flag.Bool("die", false, "trips over the filter if true") flag.Parse() - syscalls := seccomp.SyscallRules{ + syscalls := seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ACCEPT: seccomp.MatchAll{}, unix.SYS_BIND: seccomp.MatchAll{}, unix.SYS_BRK: seccomp.MatchAll{}, @@ -93,7 +93,7 @@ func main() { unix.SYS_UTIMENSAT: seccomp.MatchAll{}, unix.SYS_WRITE: seccomp.MatchAll{}, unix.SYS_WRITEV: seccomp.MatchAll{}, - } + }) arch_syscalls(syscalls) // We choose a syscall that is unlikely to be called by Go runtime, @@ -102,12 +102,12 @@ func main() { die := *dieFlag if !die { - syscalls[syscall] = seccomp.PerArg{ + syscalls.Set(syscall, seccomp.PerArg{ seccomp.EqualTo(0), - } + }) } - if err := seccomp.Install(syscalls, nil); err != nil { + if err := seccomp.Install(syscalls, seccomp.NewSyscallRules()); err != nil { fmt.Printf("Failed to install seccomp: %v\n", err) os.Exit(1) } diff --git a/pkg/seccomp/victim/seccomp_test_victim_amd64.go b/pkg/seccomp/victim/seccomp_test_victim_amd64.go index 264ee2e75..44541ba55 100644 --- a/pkg/seccomp/victim/seccomp_test_victim_amd64.go +++ b/pkg/seccomp/victim/seccomp_test_victim_amd64.go @@ -26,8 +26,8 @@ import ( ) func arch_syscalls(syscalls seccomp.SyscallRules) { - syscalls[unix.SYS_ARCH_PRCTL] = seccomp.MatchAll{} - syscalls[unix.SYS_EPOLL_WAIT] = seccomp.MatchAll{} - syscalls[unix.SYS_NEWFSTATAT] = seccomp.MatchAll{} - syscalls[unix.SYS_OPEN] = seccomp.MatchAll{} + syscalls.Set(unix.SYS_ARCH_PRCTL, seccomp.MatchAll{}) + syscalls.Set(unix.SYS_EPOLL_WAIT, seccomp.MatchAll{}) + syscalls.Set(unix.SYS_NEWFSTATAT, seccomp.MatchAll{}) + syscalls.Set(unix.SYS_OPEN, seccomp.MatchAll{}) } diff --git a/pkg/seccomp/victim/seccomp_test_victim_arm64.go b/pkg/seccomp/victim/seccomp_test_victim_arm64.go index 73ea69ea5..81317e4f0 100644 --- a/pkg/seccomp/victim/seccomp_test_victim_arm64.go +++ b/pkg/seccomp/victim/seccomp_test_victim_arm64.go @@ -26,5 +26,5 @@ import ( ) func arch_syscalls(syscalls seccomp.SyscallRules) { - syscalls[unix.SYS_FSTATAT] = seccomp.MatchAll{} + syscalls.Set(unix.SYS_FSTATAT, seccomp.MatchAll{}) } diff --git a/pkg/sentry/devices/accel/seccomp_filters.go b/pkg/sentry/devices/accel/seccomp_filters.go index ee3809eef..978fd4cb3 100644 --- a/pkg/sentry/devices/accel/seccomp_filters.go +++ b/pkg/sentry/devices/accel/seccomp_filters.go @@ -24,7 +24,7 @@ import ( // Filters returns seccomp-bpf filters for this package. func Filters() seccomp.SyscallRules { nonNegativeFD := seccomp.NonNegativeFDCheck() - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_OPENAT: seccomp.PerArg{ // All paths that we openat() are absolute, so we pass a dirfd // of -1 (which is invalid for relative paths, but ignored for @@ -108,5 +108,5 @@ func Filters() seccomp.SyscallRules { seccomp.AnyValue{}, seccomp.EqualTo(0), }, - } + }) } diff --git a/pkg/sentry/devices/nvproxy/seccomp_filters.go b/pkg/sentry/devices/nvproxy/seccomp_filters.go index 25b75998f..42bcd951b 100644 --- a/pkg/sentry/devices/nvproxy/seccomp_filters.go +++ b/pkg/sentry/devices/nvproxy/seccomp_filters.go @@ -25,7 +25,7 @@ import ( func Filters() seccomp.SyscallRules { nonNegativeFD := seccomp.NonNegativeFDCheck() notIocSizeMask := ^(((uintptr(1) << linux.IOC_SIZEBITS) - 1) << linux.IOC_SIZESHIFT) // for ioctls taking arbitrary size - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_OPENAT: seccomp.PerArg{ // All paths that we openat() are absolute, so we pass a dirfd // of -1 (which is invalid for relative paths, but ignored for @@ -192,5 +192,5 @@ func Filters() seccomp.SyscallRules { seccomp.AnyValue{}, seccomp.EqualTo(0), }, - } + }) } diff --git a/pkg/sentry/platform/kvm/filters.go b/pkg/sentry/platform/kvm/filters.go index c00a12895..82694d65e 100644 --- a/pkg/sentry/platform/kvm/filters.go +++ b/pkg/sentry/platform/kvm/filters.go @@ -23,8 +23,7 @@ import ( // SyscallFilters returns syscalls made exclusively by the KVM platform. func (k *KVM) SyscallFilters() seccomp.SyscallRules { - r := k.archSyscallFilters() - r.Merge(seccomp.SyscallRules{ + return k.archSyscallFilters().Merge(seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_IOCTL: seccomp.Or{ seccomp.PerArg{ seccomp.AnyValue{}, @@ -51,6 +50,5 @@ func (k *KVM) SyscallFilters() seccomp.SyscallRules { unix.SYS_RT_SIGSUSPEND: seccomp.MatchAll{}, unix.SYS_RT_SIGTIMEDWAIT: seccomp.MatchAll{}, _SYS_KVM_RETURN_TO_HOST: seccomp.MatchAll{}, - }) - return r + })) } diff --git a/pkg/sentry/platform/kvm/filters_amd64.go b/pkg/sentry/platform/kvm/filters_amd64.go index 7e83ab360..4a79ce0b9 100644 --- a/pkg/sentry/platform/kvm/filters_amd64.go +++ b/pkg/sentry/platform/kvm/filters_amd64.go @@ -24,7 +24,7 @@ import ( // archSyscallFilters returns arch-specific syscalls made exclusively by the // KVM platform. func (k *KVM) archSyscallFilters() seccomp.SyscallRules { - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ARCH_PRCTL: seccomp.Or{ seccomp.PerArg{ seccomp.EqualTo(linux.ARCH_GET_FS), @@ -47,5 +47,5 @@ func (k *KVM) archSyscallFilters() seccomp.SyscallRules { seccomp.EqualTo(KVM_GET_REGS), }, }, - } + }) } diff --git a/pkg/sentry/platform/kvm/filters_arm64.go b/pkg/sentry/platform/kvm/filters_arm64.go index 99ffcc4cc..20884f2dc 100644 --- a/pkg/sentry/platform/kvm/filters_arm64.go +++ b/pkg/sentry/platform/kvm/filters_arm64.go @@ -26,10 +26,10 @@ import ( // archSyscallFilters returns arch-specific syscalls made exclusively by the // KVM platform. func (*KVM) archSyscallFilters() seccomp.SyscallRules { - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_IOCTL: seccomp.PerArg{ seccomp.AnyValue{}, seccomp.EqualTo(KVM_SET_VCPU_EVENTS), }, - } + }) } diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 87cc4e883..756e84bf1 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -779,7 +779,7 @@ func seccompMmapRules(m *machine) { rules := []seccomp.RuleSet{ // Trap mmap system calls and handle them in sigsysGoHandler { - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_MMAP: seccomp.PerArg{ seccomp.AnyValue{}, seccomp.AnyValue{}, @@ -787,7 +787,7 @@ func seccompMmapRules(m *machine) { /* MAP_DENYWRITE is ignored and used only for filtering. */ seccomp.MaskedEqual(unix.MAP_DENYWRITE, 0), }, - }, + }), Action: linux.SECCOMP_RET_TRAP, }, } diff --git a/pkg/sentry/platform/ptrace/filters.go b/pkg/sentry/platform/ptrace/filters.go index 5a34bf161..c9177b907 100644 --- a/pkg/sentry/platform/ptrace/filters.go +++ b/pkg/sentry/platform/ptrace/filters.go @@ -21,9 +21,9 @@ import ( // SyscallFilters returns syscalls made exclusively by the ptrace platform. func (*PTrace) SyscallFilters() seccomp.SyscallRules { - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_PTRACE: seccomp.MatchAll{}, unix.SYS_TGKILL: seccomp.MatchAll{}, unix.SYS_WAIT4: seccomp.MatchAll{}, - } + }) } diff --git a/pkg/sentry/platform/ptrace/subprocess_amd64.go b/pkg/sentry/platform/ptrace/subprocess_amd64.go index c957487b7..b42d5f833 100644 --- a/pkg/sentry/platform/ptrace/subprocess_amd64.go +++ b/pkg/sentry/platform/ptrace/subprocess_amd64.go @@ -183,23 +183,23 @@ func appendArchSeccompRules(rules []seccomp.RuleSet, defaultAction linux.BPFActi rules = append(rules, // Rules for trapping vsyscall access. seccomp.RuleSet{ - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_GETTIMEOFDAY: seccomp.MatchAll{}, unix.SYS_TIME: seccomp.MatchAll{}, unix.SYS_GETCPU: seccomp.MatchAll{}, // SYS_GETCPU was not defined in package syscall on amd64. - }, + }), Action: linux.SECCOMP_RET_TRAP, Vsyscall: true, }) if defaultAction != linux.SECCOMP_RET_ALLOW { rules = append(rules, seccomp.RuleSet{ - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ARCH_PRCTL: seccomp.PerArg{ seccomp.EqualTo(linux.ARCH_SET_CPUID), seccomp.EqualTo(0), }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }) } diff --git a/pkg/sentry/platform/ptrace/subprocess_linux.go b/pkg/sentry/platform/ptrace/subprocess_linux.go index 02f4c31da..15cfbca45 100644 --- a/pkg/sentry/platform/ptrace/subprocess_linux.go +++ b/pkg/sentry/platform/ptrace/subprocess_linux.go @@ -79,7 +79,7 @@ func attachedThread(flags uintptr, defaultAction linux.BPFAction) (*thread, erro rules := []seccomp.RuleSet{} if defaultAction != linux.SECCOMP_RET_ALLOW { rules = append(rules, seccomp.RuleSet{ - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_CLONE: seccomp.Or{ // Allow creation of new subprocesses (used by the master). seccomp.PerArg{seccomp.EqualTo(unix.CLONE_FILES | unix.SIGKILL)}, @@ -109,7 +109,7 @@ func attachedThread(flags uintptr, defaultAction linux.BPFAction) (*thread, erro // Injected to support the address space operations. unix.SYS_MMAP: seccomp.MatchAll{}, unix.SYS_MUNMAP: seccomp.MatchAll{}, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }) } diff --git a/pkg/sentry/platform/systrap/filters.go b/pkg/sentry/platform/systrap/filters.go index 00c37b679..989e6bb0c 100644 --- a/pkg/sentry/platform/systrap/filters.go +++ b/pkg/sentry/platform/systrap/filters.go @@ -22,7 +22,7 @@ import ( // SyscallFilters returns syscalls made exclusively by the systrap platform. func (p *Systrap) SyscallFilters() seccomp.SyscallRules { - r := seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_PTRACE: seccomp.Or{ seccomp.PerArg{ seccomp.EqualTo(unix.PTRACE_ATTACH), @@ -77,7 +77,5 @@ func (p *Systrap) SyscallFilters() seccomp.SyscallRules { seccomp.AnyValue{}, seccomp.EqualTo(sysmsgThreadPriority), }, - } - r.Merge(p.archSyscallFilters()) - return r + }).Merge(p.archSyscallFilters()) } diff --git a/pkg/sentry/platform/systrap/filters_arm64.go b/pkg/sentry/platform/systrap/filters_arm64.go index 53f7d036b..a379d0fcb 100644 --- a/pkg/sentry/platform/systrap/filters_arm64.go +++ b/pkg/sentry/platform/systrap/filters_arm64.go @@ -25,7 +25,7 @@ import ( // SyscallFilters returns syscalls made exclusively by the systrap platform. func (*Systrap) archSyscallFilters() seccomp.SyscallRules { - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_PTRACE: seccomp.Or{ seccomp.PerArg{ seccomp.EqualTo(unix.PTRACE_GETREGSET), @@ -38,5 +38,5 @@ func (*Systrap) archSyscallFilters() seccomp.SyscallRules { seccomp.EqualTo(linux.NT_ARM_TLS), }, }, - } + }) } diff --git a/pkg/sentry/platform/systrap/subprocess_amd64.go b/pkg/sentry/platform/systrap/subprocess_amd64.go index 5cc9262aa..6a2f105ed 100644 --- a/pkg/sentry/platform/systrap/subprocess_amd64.go +++ b/pkg/sentry/platform/systrap/subprocess_amd64.go @@ -184,22 +184,22 @@ func appendArchSeccompRules(rules []seccomp.RuleSet) []seccomp.RuleSet { return append(rules, []seccomp.RuleSet{ // Rules for trapping vsyscall access. { - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_GETTIMEOFDAY: seccomp.MatchAll{}, unix.SYS_TIME: seccomp.MatchAll{}, unix.SYS_GETCPU: seccomp.MatchAll{}, // SYS_GETCPU was not defined in package syscall on amd64. - }, + }), Action: linux.SECCOMP_RET_TRAP, Vsyscall: true, }, { - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ARCH_PRCTL: seccomp.Or{ seccomp.PerArg{seccomp.EqualTo(linux.ARCH_SET_CPUID), seccomp.EqualTo(0)}, seccomp.PerArg{seccomp.EqualTo(linux.ARCH_SET_FS)}, seccomp.PerArg{seccomp.EqualTo(linux.ARCH_GET_FS)}, }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }...) diff --git a/pkg/sentry/platform/systrap/subprocess_linux.go b/pkg/sentry/platform/systrap/subprocess_linux.go index 33485fa7a..818fb06f6 100644 --- a/pkg/sentry/platform/systrap/subprocess_linux.go +++ b/pkg/sentry/platform/systrap/subprocess_linux.go @@ -54,7 +54,7 @@ func attachedThread(flags uintptr, defaultAction linux.BPFAction) (*thread, erro rules := []seccomp.RuleSet{} if defaultAction != linux.SECCOMP_RET_ALLOW { ruleSet := seccomp.RuleSet{ - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_CLONE: seccomp.Or{ // Allow creation of new subprocesses (used by the master). seccomp.PerArg{seccomp.EqualTo(unix.CLONE_FILES | unix.SIGKILL)}, @@ -124,7 +124,7 @@ func attachedThread(flags uintptr, defaultAction linux.BPFAction) (*thread, erro seccomp.EqualTo(0), seccomp.AnyValue{}, }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, } rules = append(rules, ruleSet) diff --git a/pkg/sentry/platform/systrap/sysmsg_thread.go b/pkg/sentry/platform/systrap/sysmsg_thread.go index d63f73061..cb6f04a3d 100644 --- a/pkg/sentry/platform/systrap/sysmsg_thread.go +++ b/pkg/sentry/platform/systrap/sysmsg_thread.go @@ -103,7 +103,7 @@ func sysmsgThreadRules(stubStart uintptr) []bpf.Instruction { rules = append(rules, []seccomp.RuleSet{ // Allow instructions from the sysmsg code stub, which is limited by one page. { - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_FUTEX: seccomp.Or{ seccomp.PerArg{ seccomp.GreaterThan(stubStart), @@ -142,7 +142,7 @@ func sysmsgThreadRules(stubStart uintptr) []bpf.Instruction { seccomp.AnyValue{}, seccomp.GreaterThan(stubStart), // rip }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }...) diff --git a/pkg/sentry/platform/systrap/sysmsg_thread_amd64.go b/pkg/sentry/platform/systrap/sysmsg_thread_amd64.go index dc83a51dc..ddb1dcb95 100644 --- a/pkg/sentry/platform/systrap/sysmsg_thread_amd64.go +++ b/pkg/sentry/platform/systrap/sysmsg_thread_amd64.go @@ -24,16 +24,16 @@ func appendSysThreadArchSeccompRules(rules []seccomp.RuleSet) []seccomp.RuleSet return append(rules, []seccomp.RuleSet{ { // Rules for trapping vsyscall access. - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_GETTIMEOFDAY: seccomp.MatchAll{}, unix.SYS_TIME: seccomp.MatchAll{}, unix.SYS_GETCPU: seccomp.MatchAll{}, // SYS_GETCPU was not defined in package syscall on amd64. - }, + }), Action: linux.SECCOMP_RET_TRAP, Vsyscall: true, }, { - Rules: seccomp.SyscallRules{ + Rules: seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ARCH_PRCTL: seccomp.Or{ seccomp.PerArg{ seccomp.EqualTo(linux.ARCH_SET_FS), @@ -54,7 +54,7 @@ func appendSysThreadArchSeccompRules(rules []seccomp.RuleSet) []seccomp.RuleSet seccomp.GreaterThan(stubStart), // rip }, }, - }, + }), Action: linux.SECCOMP_RET_ALLOW, }, }...) diff --git a/runsc/boot/filter/config.go b/runsc/boot/filter/config.go index 0a0866d0b..100c62171 100644 --- a/runsc/boot/filter/config.go +++ b/runsc/boot/filter/config.go @@ -24,7 +24,7 @@ import ( ) // allowedSyscalls is the set of syscalls executed by the Sentry to the host OS. -var allowedSyscalls = seccomp.SyscallRules{ +var allowedSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_CLOCK_GETTIME: seccomp.MatchAll{}, unix.SYS_CLOSE: seccomp.MatchAll{}, unix.SYS_DUP: seccomp.MatchAll{}, @@ -315,10 +315,10 @@ var allowedSyscalls = seccomp.SyscallRules{ seccomp.AnyValue{}, seccomp.GreaterThan(0), }, -} +}) func controlServerFilters(fd int) seccomp.SyscallRules { - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ACCEPT4: seccomp.PerArg{ seccomp.EqualTo(fd), }, @@ -331,7 +331,7 @@ func controlServerFilters(fd int) seccomp.SyscallRules { seccomp.EqualTo(unix.SOL_SOCKET), seccomp.EqualTo(unix.SO_PEERCRED), }, - } + }) } // hostFilesystemFilters contains syscalls that are needed by directfs. @@ -341,7 +341,7 @@ func hostFilesystemFilters() seccomp.SyscallRules { // restrictive as possible because any restriction here improves security. We // don't know what set of arguments will trigger a future vulnerability. validFDCheck := seccomp.NonNegativeFDCheck() - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_FCHOWNAT: seccomp.PerArg{ validFDCheck, seccomp.AnyValue{}, @@ -421,5 +421,5 @@ func hostFilesystemFilters() seccomp.SyscallRules { seccomp.AnyValue{}, seccomp.AnyValue{}, }, - } + }) } diff --git a/runsc/boot/filter/config_amd64.go b/runsc/boot/filter/config_amd64.go index 2f2020c17..a56abad9b 100644 --- a/runsc/boot/filter/config_amd64.go +++ b/runsc/boot/filter/config_amd64.go @@ -23,7 +23,7 @@ import ( ) func init() { - allowedSyscalls[unix.SYS_CLONE] = seccomp.PerArg{ + allowedSyscalls.Set(unix.SYS_CLONE, seccomp.PerArg{ // parent_tidptr and child_tidptr are always 0 because neither // CLONE_PARENT_SETTID nor CLONE_CHILD_SETTID are used. seccomp.EqualTo( @@ -38,7 +38,7 @@ func init() { seccomp.EqualTo(0), // parent_tidptr seccomp.EqualTo(0), // child_tidptr seccomp.AnyValue{}, // tls - } + }) } func archFstatAtSysNo() uintptr { diff --git a/runsc/boot/filter/config_arm64.go b/runsc/boot/filter/config_arm64.go index 73a9fdb14..778cb5fd9 100644 --- a/runsc/boot/filter/config_arm64.go +++ b/runsc/boot/filter/config_arm64.go @@ -23,7 +23,7 @@ import ( ) func init() { - allowedSyscalls[unix.SYS_CLONE] = seccomp.PerArg{ + allowedSyscalls.Set(unix.SYS_CLONE, seccomp.PerArg{ seccomp.EqualTo( unix.CLONE_VM | unix.CLONE_FS | @@ -38,7 +38,7 @@ func init() { seccomp.AnyValue{}, // parent_tidptr seccomp.AnyValue{}, // tls seccomp.AnyValue{}, // child_tidptr - } + }) } func archFstatAtSysNo() uintptr { diff --git a/runsc/boot/filter/config_profile.go b/runsc/boot/filter/config_profile.go index a16dd53fb..29024e64b 100644 --- a/runsc/boot/filter/config_profile.go +++ b/runsc/boot/filter/config_profile.go @@ -24,11 +24,11 @@ import ( // profileFilters returns extra syscalls made by runtime/pprof package. func profileFilters() seccomp.SyscallRules { - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_OPENAT: seccomp.PerArg{ seccomp.AnyValue{}, seccomp.AnyValue{}, seccomp.EqualTo(unix.O_RDONLY | unix.O_LARGEFILE | unix.O_CLOEXEC), }, - } + }) } diff --git a/runsc/boot/filter/extra_filters.go b/runsc/boot/filter/extra_filters.go index 1d06f9669..3588cafc8 100644 --- a/runsc/boot/filter/extra_filters.go +++ b/runsc/boot/filter/extra_filters.go @@ -24,5 +24,5 @@ import ( // Go instrumentation tools, e.g. -race, -msan. // Returns empty when disabled. func instrumentationFilters() seccomp.SyscallRules { - return nil + return seccomp.NewSyscallRules() } diff --git a/runsc/boot/filter/extra_filters_asan.go b/runsc/boot/filter/extra_filters_asan.go index 279359814..bb2607b8f 100644 --- a/runsc/boot/filter/extra_filters_asan.go +++ b/runsc/boot/filter/extra_filters_asan.go @@ -25,10 +25,10 @@ import ( // instrumentationFilters returns additional filters for syscalls used by ASAN. func instrumentationFilters() seccomp.SyscallRules { Report("ASAN is enabled: syscall filters less restrictive!") - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_CLONE: seccomp.MatchAll{}, unix.SYS_MMAP: seccomp.MatchAll{}, unix.SYS_SCHED_GETAFFINITY: seccomp.MatchAll{}, unix.SYS_SET_ROBUST_LIST: seccomp.MatchAll{}, - } + }) } diff --git a/runsc/boot/filter/extra_filters_hostinet.go b/runsc/boot/filter/extra_filters_hostinet.go index 977e388e7..44092237e 100644 --- a/runsc/boot/filter/extra_filters_hostinet.go +++ b/runsc/boot/filter/extra_filters_hostinet.go @@ -23,7 +23,7 @@ import ( // hostInetFilters contains syscalls that are needed by sentry/socket/hostinet. func hostInetFilters(allowRawSockets bool) seccomp.SyscallRules { - rules := seccomp.SyscallRules{ + rules := seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ACCEPT4: seccomp.PerArg{ seccomp.AnyValue{}, seccomp.AnyValue{}, @@ -97,7 +97,7 @@ func hostInetFilters(allowRawSockets bool) seccomp.SyscallRules { }, }, unix.SYS_WRITEV: seccomp.MatchAll{}, - } + }) // Need NETLINK_ROUTE and stream sockets to query host interfaces and // routes. @@ -139,13 +139,13 @@ func hostInetFilters(allowRawSockets bool) seccomp.SyscallRules { } socketRules = append(socketRules, rule) } - rules[unix.SYS_SOCKET] = socketRules + rules.Set(unix.SYS_SOCKET, socketRules) // Generate rules for socket options based on hostinet's supported // socket options. for _, opt := range hostinet.SockOpts { if opt.AllowGet { - rules.AddRule(unix.SYS_GETSOCKOPT, seccomp.PerArg{ + rules.Add(unix.SYS_GETSOCKOPT, seccomp.PerArg{ seccomp.AnyValue{}, seccomp.EqualTo(opt.Level), seccomp.EqualTo(opt.Name), @@ -153,7 +153,7 @@ func hostInetFilters(allowRawSockets bool) seccomp.SyscallRules { } if opt.AllowSet { if opt.Size > 0 { - rules.AddRule(unix.SYS_SETSOCKOPT, seccomp.PerArg{ + rules.Add(unix.SYS_SETSOCKOPT, seccomp.PerArg{ seccomp.AnyValue{}, seccomp.EqualTo(opt.Level), seccomp.EqualTo(opt.Name), @@ -161,7 +161,7 @@ func hostInetFilters(allowRawSockets bool) seccomp.SyscallRules { seccomp.EqualTo(opt.Size), }) } else { - rules.AddRule(unix.SYS_SETSOCKOPT, seccomp.PerArg{ + rules.Add(unix.SYS_SETSOCKOPT, seccomp.PerArg{ seccomp.AnyValue{}, seccomp.EqualTo(opt.Level), seccomp.EqualTo(opt.Name), diff --git a/runsc/boot/filter/extra_filters_msan.go b/runsc/boot/filter/extra_filters_msan.go index 942f347c5..fe7b18a45 100644 --- a/runsc/boot/filter/extra_filters_msan.go +++ b/runsc/boot/filter/extra_filters_msan.go @@ -25,10 +25,10 @@ import ( // instrumentationFilters returns additional filters for syscalls used by MSAN. func instrumentationFilters() seccomp.SyscallRules { Report("MSAN is enabled: syscall filters less restrictive!") - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_CLONE: seccomp.MatchAll{}, unix.SYS_MMAP: seccomp.MatchAll{}, unix.SYS_SCHED_GETAFFINITY: seccomp.MatchAll{}, unix.SYS_SET_ROBUST_LIST: seccomp.MatchAll{}, - } + }) } diff --git a/runsc/boot/filter/extra_filters_race.go b/runsc/boot/filter/extra_filters_race.go index 04955dcce..86302c65c 100644 --- a/runsc/boot/filter/extra_filters_race.go +++ b/runsc/boot/filter/extra_filters_race.go @@ -25,7 +25,7 @@ import ( // instrumentationFilters returns additional filters for syscalls used by TSAN. func instrumentationFilters() seccomp.SyscallRules { Report("TSAN is enabled: syscall filters less restrictive!") - return archInstrumentationFilters(seccomp.SyscallRules{ + return archInstrumentationFilters(seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_BRK: seccomp.MatchAll{}, unix.SYS_CLOCK_NANOSLEEP: seccomp.MatchAll{}, unix.SYS_CLONE: seccomp.MatchAll{}, @@ -38,5 +38,5 @@ func instrumentationFilters() seccomp.SyscallRules { unix.SYS_RSEQ: seccomp.MatchAll{}, unix.SYS_SET_ROBUST_LIST: seccomp.MatchAll{}, unix.SYS_SCHED_GETAFFINITY: seccomp.MatchAll{}, - }) + })) } diff --git a/runsc/boot/filter/extra_filters_race_amd64.go b/runsc/boot/filter/extra_filters_race_amd64.go index c5932d44a..1bd6899ec 100644 --- a/runsc/boot/filter/extra_filters_race_amd64.go +++ b/runsc/boot/filter/extra_filters_race_amd64.go @@ -23,8 +23,8 @@ import ( ) func archInstrumentationFilters(f seccomp.SyscallRules) seccomp.SyscallRules { - f[unix.SYS_OPEN] = seccomp.MatchAll{} + f.Set(unix.SYS_OPEN, seccomp.MatchAll{}) // Used within glibc's malloc. - f[unix.SYS_TIME] = seccomp.MatchAll{} + f.Set(unix.SYS_TIME, seccomp.MatchAll{}) return f } diff --git a/runsc/fsgofer/filter/config.go b/runsc/fsgofer/filter/config.go index 6940165a7..48bf50f12 100644 --- a/runsc/fsgofer/filter/config.go +++ b/runsc/fsgofer/filter/config.go @@ -23,7 +23,7 @@ import ( ) // allowedSyscalls is the set of syscalls executed by the gofer. -var allowedSyscalls = seccomp.SyscallRules{ +var allowedSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ACCEPT: seccomp.MatchAll{}, unix.SYS_CLOCK_GETTIME: seccomp.MatchAll{}, unix.SYS_CLOSE: seccomp.MatchAll{}, @@ -199,9 +199,9 @@ var allowedSyscalls = seccomp.SyscallRules{ unix.SYS_UNLINKAT: seccomp.MatchAll{}, unix.SYS_UTIMENSAT: seccomp.MatchAll{}, unix.SYS_WRITE: seccomp.MatchAll{}, -} +}) -var udsCommonSyscalls = seccomp.SyscallRules{ +var udsCommonSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_SOCKET: seccomp.Or{ seccomp.PerArg{ seccomp.EqualTo(unix.AF_UNIX), @@ -219,19 +219,19 @@ var udsCommonSyscalls = seccomp.SyscallRules{ seccomp.EqualTo(0), }, }, -} +}) -var udsOpenSyscalls = seccomp.SyscallRules{ +var udsOpenSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_CONNECT: seccomp.MatchAll{}, -} +}) -var udsCreateSyscalls = seccomp.SyscallRules{ +var udsCreateSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_ACCEPT4: seccomp.MatchAll{}, unix.SYS_BIND: seccomp.MatchAll{}, unix.SYS_LISTEN: seccomp.MatchAll{}, -} +}) -var xattrSyscalls = seccomp.SyscallRules{ +var xattrSyscalls = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_FGETXATTR: seccomp.MatchAll{}, unix.SYS_FSETXATTR: seccomp.MatchAll{}, -} +}) diff --git a/runsc/fsgofer/filter/config_amd64.go b/runsc/fsgofer/filter/config_amd64.go index 6ee286b03..c0e74475b 100644 --- a/runsc/fsgofer/filter/config_amd64.go +++ b/runsc/fsgofer/filter/config_amd64.go @@ -23,7 +23,7 @@ import ( ) func init() { - allowedSyscalls[unix.SYS_CLONE] = seccomp.PerArg{ + allowedSyscalls.Set(unix.SYS_CLONE, seccomp.PerArg{ // parent_tidptr and child_tidptr are always 0 because neither // CLONE_PARENT_SETTID nor CLONE_CHILD_SETTID are used. seccomp.EqualTo( @@ -38,7 +38,6 @@ func init() { seccomp.EqualTo(0), // parent_tidptr seccomp.EqualTo(0), // child_tidptr seccomp.AnyValue{}, // tls - } - - allowedSyscalls[unix.SYS_NEWFSTATAT] = seccomp.MatchAll{} + }) + allowedSyscalls.Set(unix.SYS_NEWFSTATAT, seccomp.MatchAll{}) } diff --git a/runsc/fsgofer/filter/config_arm64.go b/runsc/fsgofer/filter/config_arm64.go index 3e68801ab..fa8887ee8 100644 --- a/runsc/fsgofer/filter/config_arm64.go +++ b/runsc/fsgofer/filter/config_arm64.go @@ -23,7 +23,7 @@ import ( ) func init() { - allowedSyscalls[unix.SYS_CLONE] = seccomp.PerArg{ + allowedSyscalls.Set(unix.SYS_CLONE, seccomp.PerArg{ // parent_tidptr and child_tidptr are always 0 because neither // CLONE_PARENT_SETTID nor CLONE_CHILD_SETTID are used. seccomp.EqualTo( @@ -40,7 +40,6 @@ func init() { seccomp.AnyValue{}, // parent_tidptr seccomp.AnyValue{}, // tls seccomp.AnyValue{}, // child_tidptr - } - - allowedSyscalls[unix.SYS_FSTATAT] = seccomp.MatchAll{} + }) + allowedSyscalls.Set(unix.SYS_FSTATAT, seccomp.MatchAll{}) } diff --git a/runsc/fsgofer/filter/config_profile.go b/runsc/fsgofer/filter/config_profile.go index a729adcb2..b3297c832 100644 --- a/runsc/fsgofer/filter/config_profile.go +++ b/runsc/fsgofer/filter/config_profile.go @@ -19,7 +19,7 @@ import ( "gvisor.dev/gvisor/pkg/seccomp" ) -var profileFilters = seccomp.SyscallRules{ +var profileFilters = seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_OPENAT: seccomp.PerArg{ seccomp.AnyValue{}, seccomp.AnyValue{}, @@ -38,4 +38,4 @@ var profileFilters = seccomp.SyscallRules{ seccomp.AnyValue{}, /* new_value */ seccomp.EqualTo(0), /* old_value */ }, -} +}) diff --git a/runsc/fsgofer/filter/extra_filters.go b/runsc/fsgofer/filter/extra_filters.go index 5442add95..c429a89ec 100644 --- a/runsc/fsgofer/filter/extra_filters.go +++ b/runsc/fsgofer/filter/extra_filters.go @@ -25,5 +25,5 @@ import ( // Go instrumentation tools, e.g. -race, -msan. // Returns empty when disabled. func instrumentationFilters() seccomp.SyscallRules { - return nil + return seccomp.NewSyscallRules() } diff --git a/runsc/fsgofer/filter/extra_filters_msan.go b/runsc/fsgofer/filter/extra_filters_msan.go index 00ffd9f4b..a8a4245da 100644 --- a/runsc/fsgofer/filter/extra_filters_msan.go +++ b/runsc/fsgofer/filter/extra_filters_msan.go @@ -26,8 +26,8 @@ import ( // instrumentationFilters returns additional filters for syscalls used by MSAN. func instrumentationFilters() seccomp.SyscallRules { log.Warningf("*** SECCOMP WARNING: MSAN is enabled: syscall filters less restrictive!") - return seccomp.SyscallRules{ + return seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_SCHED_GETAFFINITY: seccomp.MatchAll{}, unix.SYS_SET_ROBUST_LIST: seccomp.MatchAll{}, - } + }) } diff --git a/runsc/fsgofer/filter/extra_filters_race.go b/runsc/fsgofer/filter/extra_filters_race.go index f68136dde..ac2187029 100644 --- a/runsc/fsgofer/filter/extra_filters_race.go +++ b/runsc/fsgofer/filter/extra_filters_race.go @@ -26,7 +26,7 @@ import ( // instrumentationFilters returns additional filters for syscalls used by TSAN. func instrumentationFilters() seccomp.SyscallRules { log.Warningf("*** SECCOMP WARNING: TSAN is enabled: syscall filters less restrictive!") - return archInstrumentationFilters(seccomp.SyscallRules{ + return archInstrumentationFilters(seccomp.MakeSyscallRules(map[uintptr]seccomp.SyscallRule{ unix.SYS_BRK: seccomp.MatchAll{}, unix.SYS_CLOCK_NANOSLEEP: seccomp.MatchAll{}, unix.SYS_CLONE: seccomp.MatchAll{}, @@ -40,5 +40,5 @@ func instrumentationFilters() seccomp.SyscallRules { unix.SYS_RSEQ: seccomp.MatchAll{}, unix.SYS_SET_ROBUST_LIST: seccomp.MatchAll{}, unix.SYS_SCHED_GETAFFINITY: seccomp.MatchAll{}, - }) + })) } diff --git a/runsc/fsgofer/filter/extra_filters_race_amd64.go b/runsc/fsgofer/filter/extra_filters_race_amd64.go index c5932d44a..1bd6899ec 100644 --- a/runsc/fsgofer/filter/extra_filters_race_amd64.go +++ b/runsc/fsgofer/filter/extra_filters_race_amd64.go @@ -23,8 +23,8 @@ import ( ) func archInstrumentationFilters(f seccomp.SyscallRules) seccomp.SyscallRules { - f[unix.SYS_OPEN] = seccomp.MatchAll{} + f.Set(unix.SYS_OPEN, seccomp.MatchAll{}) // Used within glibc's malloc. - f[unix.SYS_TIME] = seccomp.MatchAll{} + f.Set(unix.SYS_TIME, seccomp.MatchAll{}) return f } diff --git a/runsc/specutils/seccomp/seccomp.go b/runsc/specutils/seccomp/seccomp.go index 5e36eb3c0..f8c532a4e 100644 --- a/runsc/specutils/seccomp/seccomp.go +++ b/runsc/specutils/seccomp/seccomp.go @@ -136,7 +136,7 @@ func convertRules(s *specs.LinuxSeccomp) ([]seccomp.RuleSet, error) { continue } - sysRules.AddRule(uintptr(syscallNo), rule) + sysRules.Add(uintptr(syscallNo), rule) } ruleset = append(ruleset, seccomp.RuleSet{ diff --git a/test/secbench/secbench.go b/test/secbench/secbench.go index 9ff41bfd3..7e56e72bd 100644 --- a/test/secbench/secbench.go +++ b/test/secbench/secbench.go @@ -39,8 +39,9 @@ import ( func BenchFromSyscallRules(b *testing.B, name string, profile secbenchdef.Profile, rules seccomp.SyscallRules, denyRules seccomp.SyscallRules) secbenchdef.Bench { // If there is a rule allowing rt_sigreturn to be called, // also add a rule for the stand-in syscall number instead. - if sigreturnRule, found := rules[unix.SYS_RT_SIGRETURN]; found { - rules[uintptr(secbenchdef.RTSigreturn.Data(profile.Arch).Nr)] = sigreturnRule + if rules.Has(unix.SYS_RT_SIGRETURN) { + rules = rules.Copy() + rules.Set(uintptr(secbenchdef.RTSigreturn.Data(profile.Arch).Nr), rules.Get(unix.SYS_RT_SIGRETURN)) } insns, buildStats, err := seccomp.BuildProgram([]seccomp.RuleSet{ {