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
57 changes: 57 additions & 0 deletions seccomp.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ int seccomp_precompute(scmp_filter_ctx ctx) {
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf, size_t *len) {
return -EOPNOTSUPP;
}
int seccomp_transaction_start(const scmp_filter_ctx ctx) {
return -EOPNOTSUPP;
}
int seccomp_transaction_commit(const scmp_filter_ctx ctx) {
return -EOPNOTSUPP;
}
void seccomp_transaction_reject(const scmp_filter_ctx ctx) {}
#endif
*/
import "C"
Expand Down Expand Up @@ -1301,3 +1308,53 @@ func NotifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error {
func NotifIDValid(fd ScmpFd, id uint64) error {
return notifIDValid(fd, id)
}

// TransactionStart starts a new seccomp filter transaction that the caller can
// use to perform any number of filter modifications which can then be
// committed to the filter using [TransactionCommit] or rejected using
// [TransactionReject]. It is important to note that transactions only affect
// the seccomp filter state while it is being managed by libseccomp; seccomp
// filters which have been loaded into the kernel can not be modified, only new
// seccomp filters can be added on top of the existing loaded filter stack.
func (f *ScmpFilter) TransactionStart() error {
f.lock.Lock()
defer f.lock.Unlock()

if !f.valid {
return errBadFilter
}

if retCode := C.seccomp_transaction_start(f.filterCtx); retCode < 0 {
return errRc(retCode)
}

return nil
}

// TransactionReject rejects a transaction started by [TransactionStart].
func (f *ScmpFilter) TransactionReject() {
f.lock.Lock()
defer f.lock.Unlock()

if !f.valid {
return
}

C.seccomp_transaction_reject(f.filterCtx)
}

// TransactionReject commits a transaction started by [TransactionStart].
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, a copy-paste blooper. Being fixed in #120

func (f *ScmpFilter) TransactionCommit() error {
f.lock.Lock()
defer f.lock.Unlock()

if !f.valid {
return errBadFilter
}

if retCode := C.seccomp_transaction_commit(f.filterCtx); retCode < 0 {
return errRc(retCode)
}

return nil
}
58 changes: 58 additions & 0 deletions seccomp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1072,3 +1072,61 @@ func subprocessNotifUnsupported(t *testing.T) {
t.Error("GetNotifFd: got nil, want error")
}
}

func TestTransaction(t *testing.T) {
execInSubprocess(t, testTransaction)
}

func testTransaction(t *testing.T) {
if err := checkAPI("seccomp transaction support", 0, 2, 6, 0); err != nil {
t.Skip(err)
}

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

if err := filter.TransactionStart(); err != nil {
t.Fatalf("Error starting transaction: %v", err)
}
if err := filter.AddRuleExact(ScmpSyscall(0x1), ActKill); err != nil {
t.Fatalf("Error adding rule: %v", err)
}
if err := filter.TransactionCommit(); err != nil {
t.Fatalf("Error committing transaction: %v", err)
}

if err := filter.TransactionStart(); err != nil {
t.Fatalf("Error starting transaction: %v", err)
}
if err := filter.AddRuleExact(ScmpSyscall(0x1), ActKill); err != nil {
t.Fatalf("Error adding rule: %v", err)
}
filter.TransactionReject()
}

func TestTransactionUnsupported(t *testing.T) {
execInSubprocess(t, testTransactionUnsupported)
}

func testTransactionUnsupported(t *testing.T) {
if checkAPI("seccomp transaction support", 0, 2, 6, 0) == nil {
t.Skip("seccomp transaction is supported")
}

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

if filter.TransactionStart() == nil {
t.Error("TransactionStart: want error, got nil")
}
if filter.TransactionCommit() == nil {
t.Fatalf("TransactionCommit: want error, got nil")
}
filter.TransactionReject()
}