fortify/helper/seccomp/export.go
Ophestra 5b7b3fa9a4
All checks were successful
Test / Create distribution (push) Successful in 1m6s
Test / Run NixOS test (push) Successful in 2m44s
helper/seccomp: implement reader interface via pipe
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>
2025-02-03 19:43:03 +09:00

57 lines
999 B
Go

package seccomp
import (
"io/fs"
"os"
"runtime"
"sync"
"sync/atomic"
)
type exporter struct {
opts SyscallOpts
r, w *os.File
prepareOnce sync.Once
prepareErr error
closeErr atomic.Pointer[error]
exportErr <-chan error
}
func (e *exporter) prepare() error {
e.prepareOnce.Do(func() {
if r, w, err := os.Pipe(); err != nil {
e.prepareErr = err
return
} else {
e.r, e.w = r, w
}
ec := make(chan error, 1)
go func() { ec <- exportFilter(e.w.Fd(), e.opts); close(ec); _ = e.closeWrite() }()
e.exportErr = ec
runtime.SetFinalizer(e, (*exporter).closeWrite)
})
return e.prepareErr
}
func (e *exporter) closeWrite() error {
if !e.closeErr.CompareAndSwap(nil, &fs.ErrInvalid) {
return *e.closeErr.Load()
}
if e.w == nil {
return fs.ErrInvalid
}
err := e.w.Close()
e.closeErr.Store(&err)
// no need for a finalizer anymore
runtime.SetFinalizer(e, nil)
return err
}
func newExporter(opts SyscallOpts) *exporter {
return &exporter{opts: opts}
}