From b726d3762794744d94df18eeb8d7d9cbca83a317 Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Sun, 5 Jan 2020 11:46:32 +0100 Subject: pkg/host: detect unsupported LSMs --- pkg/host/syscalls_linux.go | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'pkg') diff --git a/pkg/host/syscalls_linux.go b/pkg/host/syscalls_linux.go index d9c247c88..99f413981 100644 --- a/pkg/host/syscalls_linux.go +++ b/pkg/host/syscalls_linux.go @@ -26,6 +26,9 @@ func isSupported(c *prog.Syscall, target *prog.Target, sandbox string) (bool, st if strings.HasPrefix(c.CallName, "syz_") { return isSupportedSyzkall(sandbox, c) } + if reason := isSupportedLSM(c); reason != "" { + return false, reason + } if strings.HasPrefix(c.Name, "socket$") || strings.HasPrefix(c.Name, "socketpair$") { return isSupportedSocket(c) @@ -151,6 +154,9 @@ var ( trialSupported = make(map[uint64]bool) filesystems []byte filesystemsOnce sync.Once + lsmOnce sync.Once + lsmError error + lsmDisabled map[string]bool ) // The function is lengthy as it handles all pseudo-syscalls, @@ -253,6 +259,31 @@ func isSupportedSyzkall(sandbox string, c *prog.Syscall) (bool, string) { panic("unknown syzkall: " + c.Name) } +func isSupportedLSM(c *prog.Syscall) string { + lsmOnce.Do(func() { + data, err := ioutil.ReadFile("/sys/kernel/security/lsm") + if err != nil { + lsmError = err + return + } + lsmDisabled = make(map[string]bool) + for _, lsm := range []string{"selinux", "apparmor", "smack"} { + if !strings.Contains(string(data), lsm) { + lsmDisabled[lsm] = true + } + } + }) + if lsmError != nil { + return lsmError.Error() + } + for lsm := range lsmDisabled { + if strings.Contains(strings.ToLower(c.Name), lsm) { + return fmt.Sprintf("LSM %v is not enabled", lsm) + } + } + return "" +} + func onlySandboxNone(sandbox string) (bool, string) { if syscall.Getuid() != 0 || sandbox != "none" { return false, "only supported under root with sandbox=none" -- cgit mrf-deployment