commit 783a170d62f30b3415f1746db6f264af85bd81f0 Author: Yawning Angel yawning@schwanenlied.me Date: Mon Dec 5 08:18:14 2016 +0000
More seccomp whitelist improvements.
* (General) Explicitly SIGKILL processes that try to use an unexpected ABI (eg: X32, x86_64 on x86 and vice versa). * (tor) Filter args to `fcntl[64]`, `accept4`. * (tor) `src/common/sandbox.c` things we need AF_NETLINK. Fuck that. --- src/cmd/gen-seccomp/seccomp.go | 3 ++ src/cmd/gen-seccomp/seccomp_tor.go | 97 ++++++++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 8 deletions(-)
diff --git a/src/cmd/gen-seccomp/seccomp.go b/src/cmd/gen-seccomp/seccomp.go index 6c7366f..62b286d 100644 --- a/src/cmd/gen-seccomp/seccomp.go +++ b/src/cmd/gen-seccomp/seccomp.go @@ -84,6 +84,9 @@ func newWhitelist(is386 bool) (*seccomp.ScmpFilter, error) { f.Release() return nil, err } + if err = f.SetBadArchAction(seccomp.ActKill); err != nil { + return nil, err + }
return f, nil } diff --git a/src/cmd/gen-seccomp/seccomp_tor.go b/src/cmd/gen-seccomp/seccomp_tor.go index 73ed3c0..2b01656 100644 --- a/src/cmd/gen-seccomp/seccomp_tor.go +++ b/src/cmd/gen-seccomp/seccomp_tor.go @@ -43,7 +43,6 @@ func compileTorSeccompProfile(fd *os.File, useBridges bool, is386 bool) error { "eventfd2", "pipe2", "pipe", - "fcntl", "fstat", "getdents", "getdents64", @@ -84,10 +83,6 @@ func compileTorSeccompProfile(fd *os.File, useBridges bool, is386 bool) error { "sendto", "unlink",
- // XXX: Calls that should be filtered by arg, but aren't yet. - "rt_sigaction", - "accept4", - // Calls that tor can filter, but I can't due to not being in // the tor daemon's process space. "chown", @@ -105,6 +100,7 @@ func compileTorSeccompProfile(fd *os.File, useBridges bool, is386 bool) error { "restart_syscall", "set_tid_address", "unshare", + "rt_sigaction", // Tor filters this but libc does more. } if is386 { allowedNoArgs386 := []string{ @@ -115,12 +111,11 @@ func compileTorSeccompProfile(fd *os.File, useBridges bool, is386 bool) error { "getuid32", "_llseek", "sigreturn", - "fcntl64", // XXX: Filter by arg.
"recv", "send", "stat64", - "socketcall", // Sigh... (see accept4 in the tor code) + "socketcall", // Sigh...
"ugetrlimit", "set_thread_area", @@ -161,6 +156,9 @@ func compileTorSeccompProfile(fd *os.File, useBridges bool, is386 bool) error { if err = allowCmpEq(f, "mremap", 3, mremapMaymove); err != nil { return err } + if err = torFilterAccept4(f, is386); err != nil { + return err + } if err = torFilterPoll(f); err != nil { return err } @@ -179,6 +177,9 @@ func compileTorSeccompProfile(fd *os.File, useBridges bool, is386 bool) error { if err = torFilterMmap(f, is386); err != nil { return err } + if err = torFilterFcntl(f, is386); err != nil { + return err + }
if useBridges { // XXX: One day, all the PTs will live in their own containers. @@ -246,6 +247,25 @@ func torFilterPrctl(f *seccomp.ScmpFilter) error { return f.AddRuleConditional(scall, seccomp.ActAllow, []seccomp.ScmpCondition{isPrSetDeathsig}) }
+func torFilterAccept4(f *seccomp.ScmpFilter, is386 bool) error { + scall, err := seccomp.GetSyscallFromName("accept4") + if err != nil { + return err + } + if is386 { + // XXX: The tor common/sandbox.c file, explcitly allows socketcall() + // by arg for this call, and only this call. ?????? + return f.AddRule(scall, seccomp.ActAllow) + } + + cond, err := seccomp.MakeCondition(3, seccomp.CompareMaskedEqual, 0, syscall.SOCK_CLOEXEC|syscall.SOCK_NONBLOCK) + if err != nil { + return nil + } + + return f.AddRuleConditional(scall, seccomp.ActAllow, []seccomp.ScmpCondition{cond}) +} + func torFilterPoll(f *seccomp.ScmpFilter) error { scall, err := seccomp.GetSyscallFromName("poll") if err != nil { @@ -273,7 +293,7 @@ func torFilterSocket(f *seccomp.ScmpFilter, is386 bool) error { }
// XXX: Tighten this some more. - return allowCmpEq(f, "socket", 0, syscall.AF_UNIX, syscall.AF_INET, syscall.AF_INET6, syscall.AF_NETLINK) + return allowCmpEq(f, "socket", 0, syscall.AF_UNIX, syscall.AF_INET, syscall.AF_INET6 /*, syscall.AF_NETLINK */) }
func torFilterSetsockopt(f *seccomp.ScmpFilter, is386 bool) error { @@ -447,6 +467,67 @@ func torFilterMmap(f *seccomp.ScmpFilter, is386 bool) error { return nil }
+func torFilterFcntl(f *seccomp.ScmpFilter, is386 bool) error { + scallFcntl, err := seccomp.GetSyscallFromName("fcntl") + if err != nil { + return err + } + scalls := []seccomp.ScmpSyscall{scallFcntl} + if is386 { + scallFcntl64, err := seccomp.GetSyscallFromName("fcntl64") + if err != nil { + return err + } + scalls = append(scalls, scallFcntl64) + } + + isFGetfl, err := seccomp.MakeCondition(1, seccomp.CompareEqual, syscall.F_GETFL) + if err != nil { + return err + } + isFGetfd, err := seccomp.MakeCondition(1, seccomp.CompareEqual, syscall.F_GETFD) + if err != nil { + return err + } + + isFSetfl, err := seccomp.MakeCondition(1, seccomp.CompareEqual, syscall.F_SETFL) + if err != nil { + return err + } + isFSetflFlags, err := seccomp.MakeCondition(2, seccomp.CompareEqual, syscall.O_RDWR|syscall.O_NONBLOCK) + if err != nil { + return err + } + + isFSetfd, err := seccomp.MakeCondition(1, seccomp.CompareEqual, syscall.F_SETFD) + if err != nil { + return err + } + isFdCloexec, err := seccomp.MakeCondition(2, seccomp.CompareEqual, syscall.FD_CLOEXEC) + if err != nil { + return err + } + + for _, scall := range scalls { + if err = f.AddRuleConditional(scall, seccomp.ActAllow, []seccomp.ScmpCondition{isFGetfl}); err != nil { + return err + } + if err = f.AddRuleConditional(scall, seccomp.ActAllow, []seccomp.ScmpCondition{isFGetfd}); err != nil { + return err + } + + if err = f.AddRuleConditional(scall, seccomp.ActAllow, []seccomp.ScmpCondition{isFSetfl, isFSetflFlags}); err != nil { + return err + } + + if err = f.AddRuleConditional(scall, seccomp.ActAllow, []seccomp.ScmpCondition{isFSetfd, isFdCloexec}); err != nil { + return err + } + } + + return nil +} + func obfsFilterSetsockopt(f *seccomp.ScmpFilter, is386 bool) error { // 386 already blindly allows all setsockopt() calls. if is386 {
tor-commits@lists.torproject.org