Skip to content

Commit 94aa2bf

Browse files
committed
Add ExportBPFMem
Also, add a test for ExportBPF and ExportBPFMem. Signed-off-by: Kir Kolyshkin <[email protected]>
1 parent e8d905a commit 94aa2bf

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

seccomp.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ import (
2727
int seccomp_precompute(scmp_filter_ctx ctx) {
2828
return -EOPNOTSUPP;
2929
}
30+
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf, size_t *len) {
31+
return -EOPNOTSUPP;
32+
}
3033
#endif
3134
*/
3235
import "C"
@@ -1242,6 +1245,30 @@ func (f *ScmpFilter) ExportBPF(file *os.File) error {
12421245
return nil
12431246
}
12441247

1248+
// ExportBPFMem is similar to [ExportBPF], except the data is written into
1249+
// a memory and returned as []byte.
1250+
func (f *ScmpFilter) ExportBPFMem() ([]byte, error) {
1251+
f.lock.Lock()
1252+
defer f.lock.Unlock()
1253+
1254+
if !f.valid {
1255+
return nil, errBadFilter
1256+
}
1257+
1258+
var len C.size_t
1259+
// Get the size required.
1260+
if retCode := C.seccomp_export_bpf_mem(f.filterCtx, unsafe.Pointer(nil), &len); retCode < 0 {
1261+
return nil, errRc(retCode)
1262+
}
1263+
// Get the data.
1264+
buf := make([]byte, int(len))
1265+
if retCode := C.seccomp_export_bpf_mem(f.filterCtx, unsafe.Pointer(&buf[0]), &len); retCode < 0 {
1266+
return nil, errRc(retCode)
1267+
}
1268+
1269+
return buf, nil
1270+
}
1271+
12451272
// Userspace Notification API
12461273

12471274
// GetNotifFd returns the userspace notification file descriptor associated with the given

seccomp_test.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
package seccomp
44

55
import (
6+
"bytes"
67
"errors"
78
"fmt"
9+
"io"
810
"os"
911
"os/exec"
1012
"strings"
@@ -773,6 +775,64 @@ func subprocessCreateActKillProcessFilter(t *testing.T) {
773775
}
774776
}
775777

778+
func TestExportBPF(t *testing.T) {
779+
execInSubprocess(t, subprocessExportBPF)
780+
}
781+
782+
func subprocessExportBPF(t *testing.T) {
783+
filter, err := NewFilter(ActAllow)
784+
if err != nil {
785+
t.Fatalf("Error creating filter: %s", err)
786+
}
787+
defer filter.Release()
788+
789+
call, err := GetSyscallFromName("getpid")
790+
if err != nil {
791+
t.Fatalf("Error getting syscall number of getpid: %s", err)
792+
}
793+
794+
err = filter.AddRule(call, ActErrno.SetReturnCode(42))
795+
if err != nil {
796+
t.Fatalf("Error adding rule: %s", err)
797+
}
798+
799+
file, err := os.Create(t.TempDir() + "/bpf")
800+
if err != nil {
801+
t.Fatal(err)
802+
}
803+
defer file.Close()
804+
805+
err = filter.ExportBPF(file)
806+
if err != nil {
807+
t.Fatalf("ExportBPF: %v", err)
808+
}
809+
810+
if _, err := file.Seek(0, io.SeekStart); err != nil {
811+
t.Fatal(err)
812+
}
813+
contents, err := io.ReadAll(file)
814+
if err != nil {
815+
t.Fatal(err)
816+
}
817+
t.Logf("ExportBPF: size %d", len(contents))
818+
819+
expErr := error(nil)
820+
// ExportBPFMem needs seccomp 2.6.0.
821+
if checkAPI(t.Name(), 0, 2, 6, 0) != nil {
822+
expErr = syscall.EOPNOTSUPP
823+
}
824+
contentsMem, err := filter.ExportBPFMem()
825+
if err != expErr {
826+
t.Errorf("ExportBPFMem: want %v, got %v", expErr, err)
827+
}
828+
if err == nil {
829+
t.Logf("ExportBPFMem: size %d", len(contents))
830+
if !bytes.Equal(contents, contentsMem) {
831+
t.Errorf("Got different data from ExportBPF and ExportBPFMem (%v != %v)", contents, contentsMem)
832+
}
833+
}
834+
}
835+
776836
//
777837
// Seccomp notification tests
778838
//

0 commit comments

Comments
 (0)