[server] Add initial working Linux seccomp
filter for the server.
This commit is contained in:
parent
644be877f6
commit
b53992060e
7 changed files with 235 additions and 18 deletions
|
@ -18,6 +18,12 @@ func listenTcp (_endpoint string) (net.Listener, error) {
|
|||
|
||||
_useTcpListen := false
|
||||
|
||||
if ! _useTcpListen {
|
||||
if seccompApplied {
|
||||
_useTcpListen = true
|
||||
}
|
||||
}
|
||||
|
||||
if ! _useTcpListen {
|
||||
if (runtime.GOOS == "android") {
|
||||
_useTcpListen = true
|
||||
|
|
|
@ -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 () () {
|
||||
seccompApplied = true
|
||||
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)!")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func seccompApplyPhase2 () () {
|
||||
seccompApplied = true
|
||||
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)!")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func seccompApplyPhase3 () () {
|
||||
seccompApplied = true
|
||||
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)!")
|
||||
}
|
||||
}
|
||||
|
@ -37,5 +133,6 @@ func seccompApplyPhase3 () () {
|
|||
|
||||
|
||||
|
||||
var seccompApplied = false
|
||||
var seccompSupported = seccomp.Supported
|
||||
|
||||
|
|
|
@ -1035,7 +1035,7 @@ func main_0 () (error) {
|
|||
if _seccompEnabled && (_processes > 1) {
|
||||
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!")
|
||||
}
|
||||
|
||||
|
@ -1056,19 +1056,6 @@ func main_0 () (error) {
|
|||
|
||||
|
||||
|
||||
if _seccompEnabled {
|
||||
seccompApplyPhase1 ()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
runtime.GOMAXPROCS (int (_threads))
|
||||
|
||||
debug.SetGCPercent (50)
|
||||
|
@ -1097,6 +1084,19 @@ func main_0 () (error) {
|
|||
|
||||
|
||||
|
||||
if _seccompEnabled {
|
||||
seccompApplyPhase1 ()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
if _processes > 1 {
|
||||
|
||||
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 {
|
||||
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!")
|
||||
}
|
||||
if !_quiet {
|
||||
|
|
|
@ -32,6 +32,7 @@ require (
|
|||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // 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/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/zeebo/assert v1.3.1 // indirect
|
||||
|
|
|
@ -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/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/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/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=
|
||||
|
|
95
sources/lib/seccomp/supported.go
Normal file
95
sources/lib/seccomp/supported.go
Normal 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
|
||||
}
|
||||
|
16
sources/lib/seccomp/unsupported.go
Normal file
16
sources/lib/seccomp/unsupported.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
|
||||
//go:build !(linux && amd64 && seccomp)
|
||||
|
||||
|
||||
|
||||
|
||||
package seccomp
|
||||
|
||||
|
||||
|
||||
|
||||
func AllowOnlySyscalls (_syscalls []string) (error) {
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in a new issue