Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions seccomp.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import (
int seccomp_precompute(scmp_filter_ctx ctx) {
return -EOPNOTSUPP;
}
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf, size_t *len) {
return -EOPNOTSUPP;
}
#endif
*/
import "C"
Expand Down Expand Up @@ -1242,6 +1245,30 @@ func (f *ScmpFilter) ExportBPF(file *os.File) error {
return nil
}

// ExportBPFMem is similar to [ExportBPF], except the data is written into
// a memory and returned as []byte.
func (f *ScmpFilter) ExportBPFMem() ([]byte, error) {
f.lock.Lock()
defer f.lock.Unlock()

if !f.valid {
return nil, errBadFilter
}

var len C.size_t
// Get the size required.
if retCode := C.seccomp_export_bpf_mem(f.filterCtx, unsafe.Pointer(nil), &len); retCode < 0 {
return nil, errRc(retCode)
}
// Get the data.
buf := make([]byte, int(len))
if retCode := C.seccomp_export_bpf_mem(f.filterCtx, unsafe.Pointer(&buf[0]), &len); retCode < 0 {
return nil, errRc(retCode)
}

return buf, nil
}

// Userspace Notification API

// GetNotifFd returns the userspace notification file descriptor associated with the given
Expand Down
60 changes: 60 additions & 0 deletions seccomp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
package seccomp

import (
"bytes"
"errors"
"fmt"
"io"
"os"
"os/exec"
"strings"
Expand Down Expand Up @@ -773,6 +775,64 @@ func subprocessCreateActKillProcessFilter(t *testing.T) {
}
}

func TestExportBPF(t *testing.T) {
execInSubprocess(t, subprocessExportBPF)
}

func subprocessExportBPF(t *testing.T) {
filter, err := NewFilter(ActAllow)
if err != nil {
t.Fatalf("Error creating filter: %s", err)
}
defer filter.Release()

call, err := GetSyscallFromName("getpid")
if err != nil {
t.Fatalf("Error getting syscall number of getpid: %s", err)
}

err = filter.AddRule(call, ActErrno.SetReturnCode(42))
if err != nil {
t.Fatalf("Error adding rule: %s", err)
}

file, err := os.Create(t.TempDir() + "/bpf")
if err != nil {
t.Fatal(err)
}
defer file.Close()

err = filter.ExportBPF(file)
if err != nil {
t.Fatalf("ExportBPF: %v", err)
}

if _, err := file.Seek(0, io.SeekStart); err != nil {
t.Fatal(err)
}
contents, err := io.ReadAll(file)
if err != nil {
t.Fatal(err)
}
t.Logf("ExportBPF: size %d", len(contents))

expErr := error(nil)
// ExportBPFMem needs seccomp 2.6.0.
if checkAPI(t.Name(), 0, 2, 6, 0) != nil {
expErr = syscall.EOPNOTSUPP
}
contentsMem, err := filter.ExportBPFMem()
if err != expErr {
t.Errorf("ExportBPFMem: want %v, got %v", expErr, err)
}
if err == nil {
t.Logf("ExportBPFMem: size %d", len(contents))
if !bytes.Equal(contents, contentsMem) {
t.Errorf("Got different data from ExportBPF and ExportBPFMem (%v != %v)", contents, contentsMem)
}
}
}

//
// Seccomp notification tests
//
Expand Down