mirror of
https://github.com/criyle/go-sandbox.git
synced 2025-11-04 14:49:53 +08:00
74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
// Package secutil provides utility functions to manipulate seccomp filters
|
|
// provided by libseccomp
|
|
package secutil
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"syscall"
|
|
"unsafe"
|
|
|
|
libseccomp "github.com/seccomp/libseccomp-golang"
|
|
)
|
|
|
|
// FilterToBPF convert libseccomp filter to kernel readable BPF style
|
|
func FilterToBPF(filter *libseccomp.ScmpFilter) (*syscall.SockFprog, error) {
|
|
r, w, err := os.Pipe()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// export to pipe
|
|
go func() {
|
|
filter.ExportBPF(w)
|
|
w.Close()
|
|
}()
|
|
|
|
// get BPF binary
|
|
bin, err := ioutil.ReadAll(r)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// directly convert pointer
|
|
return &syscall.SockFprog{
|
|
Len: uint16(len(bin) / 8),
|
|
Filter: (*syscall.SockFilter)(unsafe.Pointer(&bin[0])),
|
|
}, nil
|
|
}
|
|
|
|
// BuildFilter builds libseccomp filter by defining the default action, trace action
|
|
// allow and trace syscall names
|
|
func BuildFilter(defaultAct, traceAct libseccomp.ScmpAction, allow, trace []string) (*libseccomp.ScmpFilter, error) {
|
|
filter, err := libseccomp.NewFilter(defaultAct)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
for _, s := range allow {
|
|
err := addFilterAction(filter, s, libseccomp.ActAllow)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
for _, s := range trace {
|
|
err := addFilterAction(filter, s, traceAct)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return filter, nil
|
|
}
|
|
|
|
func addFilterAction(filter *libseccomp.ScmpFilter, name string, action libseccomp.ScmpAction) error {
|
|
syscallID, err := libseccomp.GetSyscallFromName(name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = filter.AddRule(syscallID, action)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|