From 237e45d23aabd8e3f7679cbd87abbea757702ae9 Mon Sep 17 00:00:00 2001 From: Andrei Vagin Date: Thu, 3 Feb 2022 14:51:32 -0800 Subject: [PATCH] filters: don't allow to create new executable mappings PiperOrigin-RevId: 426244201 --- pkg/seccomp/seccomp.go | 9 ++++++++- pkg/seccomp/seccomp_rules.go | 25 ++++++++++++++++++++++++- pkg/seccomp/seccomp_test_victim.go | 2 +- pkg/sentry/platform/kvm/machine.go | 2 +- runsc/boot/filter/filter.go | 2 +- runsc/fsgofer/filter/filter.go | 2 +- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/pkg/seccomp/seccomp.go b/pkg/seccomp/seccomp.go index 062250d69..da5a861a2 100644 --- a/pkg/seccomp/seccomp.go +++ b/pkg/seccomp/seccomp.go @@ -41,11 +41,14 @@ const ( // used because it only kills the offending thread and often keeps the sentry // hanging. // +// denyRules describes forbidden syscalls. rules describes allowed syscalls. +// denyRules is executed before rules. +// // Be aware that RET_TRAP sends SIGSYS to the process and it may be ignored, // making it possible for the process to continue running after a violation. // However, it will leave a SECCOMP audit event trail behind. In any case, the // syscall is still blocked from executing. -func Install(rules SyscallRules) error { +func Install(rules SyscallRules, denyRules SyscallRules) error { defaultAction, err := defaultAction() if err != nil { return err @@ -57,6 +60,10 @@ func Install(rules SyscallRules) error { log.Infof("Installing seccomp filters for %d syscalls (action=%v)", len(rules), defaultAction) instrs, err := BuildProgram([]RuleSet{ + { + Rules: denyRules, + Action: defaultAction, + }, { Rules: rules, Action: linux.SECCOMP_RET_ALLOW, diff --git a/pkg/seccomp/seccomp_rules.go b/pkg/seccomp/seccomp_rules.go index daf165bbf..8967c51c9 100644 --- a/pkg/seccomp/seccomp_rules.go +++ b/pkg/seccomp/seccomp_rules.go @@ -14,7 +14,11 @@ package seccomp -import "fmt" +import ( + "fmt" + + "golang.org/x/sys/unix" +) // The offsets are based on the following struct in include/linux/seccomp.h. // struct seccomp_data { @@ -188,3 +192,22 @@ func (sr SyscallRules) Merge(rules SyscallRules) { } } } + +// DenyNewExecMappings is a set of rules that denies creating new executable +// mappings and converting existing ones. +var DenyNewExecMappings = SyscallRules{ + unix.SYS_MMAP: []Rule{ + { + MatchAny{}, + MatchAny{}, + MaskedEqual(unix.PROT_EXEC, unix.PROT_EXEC), + }, + }, + unix.SYS_MPROTECT: []Rule{ + { + MatchAny{}, + MatchAny{}, + MaskedEqual(unix.PROT_EXEC, unix.PROT_EXEC), + }, + }, +} diff --git a/pkg/seccomp/seccomp_test_victim.go b/pkg/seccomp/seccomp_test_victim.go index a96b1e327..10ff0df7e 100644 --- a/pkg/seccomp/seccomp_test_victim.go +++ b/pkg/seccomp/seccomp_test_victim.go @@ -105,7 +105,7 @@ func main() { } } - if err := seccomp.Install(syscalls); err != nil { + if err := seccomp.Install(syscalls, nil); err != nil { fmt.Printf("Failed to install seccomp: %v", err) os.Exit(1) } diff --git a/pkg/sentry/platform/kvm/machine.go b/pkg/sentry/platform/kvm/machine.go index 5f7a044b1..ecfbb8794 100644 --- a/pkg/sentry/platform/kvm/machine.go +++ b/pkg/sentry/platform/kvm/machine.go @@ -744,7 +744,7 @@ func seccompMmapRules(m *machine) { { seccomp.MatchAny{}, seccomp.MatchAny{}, - seccomp.MatchAny{}, + seccomp.MaskedEqual(unix.PROT_EXEC, 0), /* MAP_DENYWRITE is ignored and used only for filtering. */ seccomp.MaskedEqual(unix.MAP_DENYWRITE, 0), }, diff --git a/runsc/boot/filter/filter.go b/runsc/boot/filter/filter.go index e80c171b3..73803f9ab 100644 --- a/runsc/boot/filter/filter.go +++ b/runsc/boot/filter/filter.go @@ -51,7 +51,7 @@ func Install(opt Options) error { s.Merge(opt.Platform.SyscallFilters()) - return seccomp.Install(s) + return seccomp.Install(s, seccomp.DenyNewExecMappings) } // Report writes a warning message to the log. diff --git a/runsc/fsgofer/filter/filter.go b/runsc/fsgofer/filter/filter.go index 6c67ee288..66d28febc 100644 --- a/runsc/fsgofer/filter/filter.go +++ b/runsc/fsgofer/filter/filter.go @@ -27,7 +27,7 @@ func Install() error { // when not enabled. allowedSyscalls.Merge(instrumentationFilters()) - return seccomp.Install(allowedSyscalls) + return seccomp.Install(allowedSyscalls, seccomp.DenyNewExecMappings) } // InstallUDSFilters extends the allowed syscalls to include those necessary for