forked from security/hakurei
This also does not require the libc tmpfile call. BPF programs emitted by libseccomp seems to be deterministic. The tests would catch regressions as it verifies the program against known good output backed by manual testing. Signed-off-by: Ophestra <cat@gensokyo.uk>
124 lines
4.0 KiB
Go
124 lines
4.0 KiB
Go
package seccomp_test
|
|
|
|
import (
|
|
"crypto/sha512"
|
|
"errors"
|
|
"io"
|
|
"slices"
|
|
"syscall"
|
|
"testing"
|
|
|
|
"git.gensokyo.uk/security/fortify/helper/seccomp"
|
|
"git.gensokyo.uk/security/fortify/internal/fmsg"
|
|
)
|
|
|
|
func TestExport(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
opts seccomp.SyscallOpts
|
|
want []byte
|
|
wantErr bool
|
|
}{
|
|
{"compat", 0, []byte{
|
|
0x95, 0xec, 0x69, 0xd0, 0x17, 0x73, 0x3e, 0x07,
|
|
0x21, 0x60, 0xe0, 0xda, 0x80, 0xfd, 0xeb, 0xec,
|
|
0xdf, 0x27, 0xae, 0x81, 0x66, 0xf5, 0xe2, 0xa7,
|
|
0x31, 0x27, 0x0c, 0x98, 0xea, 0x2d, 0x29, 0x46,
|
|
0xcb, 0x52, 0x31, 0x02, 0x90, 0x63, 0x66, 0x8a,
|
|
0xf2, 0x15, 0x87, 0x91, 0x55, 0xda, 0x21, 0xac,
|
|
0xa7, 0x9b, 0x07, 0x0e, 0x04, 0xc0, 0xee, 0x9a,
|
|
0xcd, 0xf5, 0x8f, 0x55, 0xcf, 0xa8, 0x15, 0xa5,
|
|
}, false},
|
|
{"base", seccomp.FlagExt, []byte{
|
|
0xdc, 0x7f, 0x2e, 0x1c, 0x5e, 0x82, 0x9b, 0x79,
|
|
0xeb, 0xb7, 0xef, 0xc7, 0x59, 0x15, 0x0f, 0x54,
|
|
0xa8, 0x3a, 0x75, 0xc8, 0xdf, 0x6f, 0xee, 0x4d,
|
|
0xce, 0x5d, 0xad, 0xc4, 0x73, 0x6c, 0x58, 0x5d,
|
|
0x4d, 0xee, 0xbf, 0xeb, 0x3c, 0x79, 0x69, 0xaf,
|
|
0x3a, 0x07, 0x7e, 0x90, 0xb7, 0x7b, 0xb4, 0x74,
|
|
0x1d, 0xb0, 0x5d, 0x90, 0x99, 0x7c, 0x86, 0x59,
|
|
0xb9, 0x58, 0x91, 0x20, 0x6a, 0xc9, 0x95, 0x2d,
|
|
}, false},
|
|
{"everything", seccomp.FlagExt |
|
|
seccomp.FlagDenyNS | seccomp.FlagDenyTTY | seccomp.FlagDenyDevel |
|
|
seccomp.FlagMultiarch | seccomp.FlagLinux32 | seccomp.FlagCan |
|
|
seccomp.FlagBluetooth, []byte{
|
|
0xe9, 0x9d, 0xd3, 0x45, 0xe1, 0x95, 0x41, 0x34,
|
|
0x73, 0xd3, 0xcb, 0xee, 0x07, 0xb4, 0xed, 0x57,
|
|
0xb9, 0x08, 0xbf, 0xa8, 0x9e, 0xa2, 0x07, 0x2f,
|
|
0xe9, 0x34, 0x82, 0x84, 0x7f, 0x50, 0xb5, 0xb7,
|
|
0x58, 0xda, 0x17, 0xe7, 0x4c, 0xa2, 0xbb, 0xc0,
|
|
0x08, 0x13, 0xde, 0x49, 0xa2, 0xb9, 0xbf, 0x83,
|
|
0x4c, 0x02, 0x4e, 0xd4, 0x88, 0x50, 0xbe, 0x69,
|
|
0xb6, 0x8a, 0x9a, 0x4c, 0x5f, 0x53, 0xa9, 0xdb,
|
|
}, false},
|
|
{"strict", seccomp.FlagExt |
|
|
seccomp.FlagDenyNS | seccomp.FlagDenyTTY | seccomp.FlagDenyDevel, []byte{
|
|
0xe8, 0x80, 0x29, 0x8d, 0xf2, 0xbd, 0x67, 0x51,
|
|
0xd0, 0x04, 0x0f, 0xc2, 0x1b, 0xc0, 0xed, 0x4c,
|
|
0x00, 0xf9, 0x5d, 0xc0, 0xd7, 0xba, 0x50, 0x6c,
|
|
0x24, 0x4d, 0x8b, 0x8c, 0xf6, 0x86, 0x6d, 0xba,
|
|
0x8e, 0xf4, 0xa3, 0x32, 0x96, 0xf2, 0x87, 0xb6,
|
|
0x6c, 0xcc, 0xc1, 0xd7, 0x8e, 0x97, 0x02, 0x65,
|
|
0x97, 0xf8, 0x4c, 0xc7, 0xde, 0xc1, 0x57, 0x3e,
|
|
0x14, 0x89, 0x60, 0xfb, 0xd3, 0x5c, 0xd7, 0x35,
|
|
}, false},
|
|
{"strict compat", 0 |
|
|
seccomp.FlagDenyNS | seccomp.FlagDenyTTY | seccomp.FlagDenyDevel, []byte{
|
|
0x39, 0x87, 0x1b, 0x93, 0xff, 0xaf, 0xc8, 0xb9,
|
|
0x79, 0xfc, 0xed, 0xc0, 0xb0, 0xc3, 0x7b, 0x9e,
|
|
0x03, 0x92, 0x2f, 0x5b, 0x02, 0x74, 0x8d, 0xc5,
|
|
0xc3, 0xc1, 0x7c, 0x92, 0x52, 0x7f, 0x6e, 0x02,
|
|
0x2e, 0xde, 0x1f, 0x48, 0xbf, 0xf5, 0x92, 0x46,
|
|
0xea, 0x45, 0x2c, 0x0d, 0x1d, 0xe5, 0x48, 0x27,
|
|
0x80, 0x8b, 0x1a, 0x6f, 0x84, 0xf3, 0x2b, 0xbd,
|
|
0xe1, 0xaa, 0x02, 0xae, 0x30, 0xee, 0xdc, 0xfa,
|
|
}, false},
|
|
}
|
|
|
|
buf := make([]byte, 8)
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
seccomp.CPrintln = fmsg.Println
|
|
t.Cleanup(func() { seccomp.CPrintln = nil })
|
|
|
|
e := seccomp.New(tc.opts)
|
|
digest := sha512.New()
|
|
|
|
if _, err := io.CopyBuffer(digest, e, buf); (err != nil) != tc.wantErr {
|
|
t.Errorf("Exporter: error = %v, wantErr %v", err, tc.wantErr)
|
|
return
|
|
}
|
|
if err := e.Close(); err != nil {
|
|
t.Errorf("Close: error = %v", err)
|
|
return
|
|
}
|
|
if got := digest.Sum(nil); slices.Compare(got, tc.want) != 0 {
|
|
t.Fatalf("Export() hash = %x, want %x",
|
|
got, tc.want)
|
|
return
|
|
}
|
|
})
|
|
}
|
|
|
|
t.Run("close without use", func(t *testing.T) {
|
|
e := seccomp.New(0)
|
|
if err := e.Close(); !errors.Is(err, syscall.EINVAL) {
|
|
t.Errorf("Close: error = %v", err)
|
|
return
|
|
}
|
|
})
|
|
|
|
t.Run("close partial read", func(t *testing.T) {
|
|
e := seccomp.New(0)
|
|
if _, err := e.Read(make([]byte, 0)); err != nil {
|
|
t.Errorf("Read: error = %v", err)
|
|
return
|
|
}
|
|
if err := e.Close(); err == nil || err.Error() != "seccomp_export_bpf failed: operation canceled" {
|
|
t.Errorf("Close: error = %v", err)
|
|
return
|
|
}
|
|
})
|
|
}
|