Skip to content

Commit

Permalink
Add ExportBPFMem
Browse files Browse the repository at this point in the history
Also, add a test for ExportBPF and ExportBPFMem.

Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
  • Loading branch information
kolyshkin committed Feb 8, 2025
1 parent e8d905a commit 94aa2bf
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
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

0 comments on commit 94aa2bf

Please sign in to comment.