[server] Add initial working Linux seccomp filter for the server.

This commit is contained in:
Ciprian Dorin Craciun 2022-09-11 20:19:56 +03:00
parent 644be877f6
commit b53992060e
7 changed files with 235 additions and 18 deletions

View file

@ -18,6 +18,12 @@ func listenTcp (_endpoint string) (net.Listener, error) {
_useTcpListen := false _useTcpListen := false
if ! _useTcpListen {
if seccompApplied {
_useTcpListen = true
}
}
if ! _useTcpListen { if ! _useTcpListen {
if (runtime.GOOS == "android") { if (runtime.GOOS == "android") {
_useTcpListen = true _useTcpListen = true

View file

@ -11,25 +11,121 @@ import . "github.com/volution/kawipiko/lib/common"
var _seccompBaseSyscalls = []string {
"brk",
"mmap",
"munmap",
"madvise",
"mprotect",
"clone3",
"getpid",
"gettid",
"tgkill",
"exit_group",
"sched_yield",
"nanosleep",
"sigaltstack",
"rt_sigaction",
"rt_sigprocmask",
"rt_sigreturn",
"restart_syscall",
"futex",
"set_robust_list",
"rseq",
}
// NOTE: While serving.
var _seccompPhase3Syscalls = append ([]string {
"accept4",
"close",
"getsockname",
"getpeername",
"getsockopt",
"setsockopt",
"read",
"write",
"pread64",
"pwrite64",
"recvmmsg",
"sendmsg",
"epoll_ctl",
"epoll_pwait",
"getrandom",
"getrusage",
}, _seccompBaseSyscalls ...)
// NOTE: While listening.
var _seccompPhase2Syscalls = append ([]string {
"socket",
"bind",
"listen",
"pipe2",
"fcntl",
"epoll_create1",
"seccomp",
"prctl",
}, _seccompPhase3Syscalls ...)
// NOTE: While loading.
var _seccompPhase1Syscalls = append ([]string {
"openat",
"fstat",
"newfstatat",
"mmap",
"seccomp",
"prctl",
}, _seccompPhase2Syscalls ...)
func seccompApplyPhase1 () () { func seccompApplyPhase1 () () {
seccompApplied = true
log.Printf ("[ii] [d53cf86e] [seccomp.] applying Linux seccomp filter (phase 1)...\n") log.Printf ("[ii] [d53cf86e] [seccomp.] applying Linux seccomp filter (phase 1)...\n")
if _error := seccomp.ApplyServer (); _error != nil { if _error := seccomp.AllowOnlySyscalls (_seccompPhase1Syscalls); _error != nil {
AbortError (_error, "[58d1492b] failed to apply Linux seccomp filter (phase 1)!") AbortError (_error, "[58d1492b] failed to apply Linux seccomp filter (phase 1)!")
} }
} }
func seccompApplyPhase2 () () { func seccompApplyPhase2 () () {
seccompApplied = true
log.Printf ("[ii] [a338ddaf] [seccomp.] applying Linux seccomp filter (phase 2)...\n") log.Printf ("[ii] [a338ddaf] [seccomp.] applying Linux seccomp filter (phase 2)...\n")
if _error := seccomp.ApplyServer (); _error != nil { if _error := seccomp.AllowOnlySyscalls (_seccompPhase2Syscalls); _error != nil {
AbortError (_error, "[68283e68] failed to apply Linux seccomp filter (phase 2)!") AbortError (_error, "[68283e68] failed to apply Linux seccomp filter (phase 2)!")
} }
} }
func seccompApplyPhase3 () () { func seccompApplyPhase3 () () {
seccompApplied = true
log.Printf ("[ii] [a319ff21] [seccomp.] applying Linux seccomp filter (phase 3)...\n") log.Printf ("[ii] [a319ff21] [seccomp.] applying Linux seccomp filter (phase 3)...\n")
if _error := seccomp.ApplyServer (); _error != nil { if _error := seccomp.AllowOnlySyscalls (_seccompPhase3Syscalls); _error != nil {
AbortError (_error, "[7c5a0f44] failed to apply Linux seccomp filter (phase 3)!") AbortError (_error, "[7c5a0f44] failed to apply Linux seccomp filter (phase 3)!")
} }
} }
@ -37,5 +133,6 @@ func seccompApplyPhase3 () () {
var seccompApplied = false
var seccompSupported = seccomp.Supported var seccompSupported = seccomp.Supported

View file

@ -1035,7 +1035,7 @@ func main_0 () (error) {
if _seccompEnabled && (_processes > 1) { if _seccompEnabled && (_processes > 1) {
AbortError (nil, "[69c06e0c] Linux seccomp is not supported with multiple processes!") AbortError (nil, "[69c06e0c] Linux seccomp is not supported with multiple processes!")
} }
if _seccompEnabled && ((_profilingCpu != "") || (_profilingMem != "")) { if _seccompEnabled && ((_profileCpu != "") || (_profileMem != "")) {
AbortError (nil, "[1fb06ca1] Linux seccomp is not supported with profiling!") AbortError (nil, "[1fb06ca1] Linux seccomp is not supported with profiling!")
} }
@ -1056,19 +1056,6 @@ func main_0 () (error) {
if _seccompEnabled {
seccompApplyPhase1 ()
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
runtime.GOMAXPROCS (int (_threads)) runtime.GOMAXPROCS (int (_threads))
debug.SetGCPercent (50) debug.SetGCPercent (50)
@ -1097,6 +1084,19 @@ func main_0 () (error) {
if _seccompEnabled {
seccompApplyPhase1 ()
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
if _processes > 1 { if _processes > 1 {
log.Printf ("[ii] [06f8c944] [master..] sub-processes starting (`%d` processes with `%d` threads each)...\n", _processes, _threads) log.Printf ("[ii] [06f8c944] [master..] sub-processes starting (`%d` processes with `%d` threads each)...\n", _processes, _threads)
@ -2185,7 +2185,7 @@ func main_0 () (error) {
if !_quiet { if !_quiet {
log.Printf ("[ii] [4cf834b0] [quic-h3.] starting QUIC server...\n") log.Printf ("[ii] [4cf834b0] [quic-h3.] starting QUIC server...\n")
} }
if _error := _server.httpQuicServer.Serve (_httpQuicListener); (_error != nil) && (_error.Error () != "server closed") { if _error := _server.httpQuicServer.Serve (_httpQuicListener); (_error != nil) && (_error.Error () != "quic: Server closed") {
AbortError (_error, "[73e700c5] [quic-h3.] failed executing server!") AbortError (_error, "[73e700c5] [quic-h3.] failed executing server!")
} }
if !_quiet { if !_quiet {

View file

@ -32,6 +32,7 @@ require (
github.com/nxadm/tail v1.4.8 // indirect github.com/nxadm/tail v1.4.8 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect
github.com/onsi/gomega v1.19.0 // indirect github.com/onsi/gomega v1.19.0 // indirect
github.com/seccomp/libseccomp-golang v0.10.0 // indirect
github.com/stretchr/testify v1.8.0 // indirect github.com/stretchr/testify v1.8.0 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/zeebo/assert v1.3.1 // indirect github.com/zeebo/assert v1.3.1 // indirect

View file

@ -144,6 +144,8 @@ github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/seccomp/libseccomp-golang v0.10.0 h1:aA4bp+/Zzi0BnWZ2F1wgNBs5gTpm+na2rWM6M9YjLpY=
github.com/seccomp/libseccomp-golang v0.10.0/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=

View file

@ -0,0 +1,95 @@
//go:build linux && amd64 && seccomp
package seccomp
import "fmt"
import "syscall"
import "github.com/seccomp/libseccomp-golang"
func init () {
Supported = true
if false {
_filter, _error := seccomp.NewFilter (seccomp.ActLog)
if _error != nil {
panic (_error)
}
if _error = _filter.Load (); _error != nil {
panic (_error)
}
}
}
func AllowOnlySyscalls (_syscalls []string) (error) {
_architectures := []seccomp.ScmpArch {
seccomp.ArchNative,
seccomp.ArchX86,
seccomp.ArchX32,
seccomp.ArchAMD64,
}
_fallbackAction := seccomp.ActKill
switch 0 {
case 1 :
_fallbackAction = seccomp.ActErrno.SetReturnCode (int16 (syscall.EPERM))
case 2 :
_fallbackAction = seccomp.ActLog
}
_filter, _error := seccomp.NewFilter (_fallbackAction)
if _error != nil {
return _error
}
for _, _architecture := range _architectures {
if _error := _filter.AddArch (_architecture); _error != nil {
return _error
}
}
for _, _syscall := range _syscalls {
var _sc_syscall seccomp.ScmpSyscall
switch {
case _syscall[0] == '!' :
continue
default :
if _sc_syscall_0, _error := seccomp.GetSyscallFromNameByArch (_syscall, seccomp.ArchNative); _error == nil {
_sc_syscall = _sc_syscall_0
} else {
return fmt.Errorf ("[5cf9cd60] failed resolving syscall `%s`: %w", _syscall, _error)
}
}
if _error := _filter.AddRule (_sc_syscall, seccomp.ActAllow); _error != nil {
return _error
}
}
if _error = _filter.Load (); _error != nil {
return _error
}
return nil
}

View file

@ -0,0 +1,16 @@
//go:build !(linux && amd64 && seccomp)
package seccomp
func AllowOnlySyscalls (_syscalls []string) (error) {
return nil
}