Skip to content

Commit 5143533

Browse files
authored
Merge pull request #119 from kolyshkin/trans
Add transaction support Signed-off-by: Kir Kolyshkin <[email protected]> Acked-by: Tom Hromatka <[email protected]>
2 parents ebd76af + 80346ad commit 5143533

File tree

2 files changed

+115
-0
lines changed

2 files changed

+115
-0
lines changed

seccomp.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ int seccomp_precompute(scmp_filter_ctx ctx) {
3030
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf, size_t *len) {
3131
return -EOPNOTSUPP;
3232
}
33+
int seccomp_transaction_start(const scmp_filter_ctx ctx) {
34+
return -EOPNOTSUPP;
35+
}
36+
int seccomp_transaction_commit(const scmp_filter_ctx ctx) {
37+
return -EOPNOTSUPP;
38+
}
39+
void seccomp_transaction_reject(const scmp_filter_ctx ctx) {}
3340
#endif
3441
*/
3542
import "C"
@@ -1301,3 +1308,53 @@ func NotifRespond(fd ScmpFd, scmpResp *ScmpNotifResp) error {
13011308
func NotifIDValid(fd ScmpFd, id uint64) error {
13021309
return notifIDValid(fd, id)
13031310
}
1311+
1312+
// TransactionStart starts a new seccomp filter transaction that the caller can
1313+
// use to perform any number of filter modifications which can then be
1314+
// committed to the filter using [TransactionCommit] or rejected using
1315+
// [TransactionReject]. It is important to note that transactions only affect
1316+
// the seccomp filter state while it is being managed by libseccomp; seccomp
1317+
// filters which have been loaded into the kernel can not be modified, only new
1318+
// seccomp filters can be added on top of the existing loaded filter stack.
1319+
func (f *ScmpFilter) TransactionStart() error {
1320+
f.lock.Lock()
1321+
defer f.lock.Unlock()
1322+
1323+
if !f.valid {
1324+
return errBadFilter
1325+
}
1326+
1327+
if retCode := C.seccomp_transaction_start(f.filterCtx); retCode < 0 {
1328+
return errRc(retCode)
1329+
}
1330+
1331+
return nil
1332+
}
1333+
1334+
// TransactionReject rejects a transaction started by [TransactionStart].
1335+
func (f *ScmpFilter) TransactionReject() {
1336+
f.lock.Lock()
1337+
defer f.lock.Unlock()
1338+
1339+
if !f.valid {
1340+
return
1341+
}
1342+
1343+
C.seccomp_transaction_reject(f.filterCtx)
1344+
}
1345+
1346+
// TransactionReject commits a transaction started by [TransactionStart].
1347+
func (f *ScmpFilter) TransactionCommit() error {
1348+
f.lock.Lock()
1349+
defer f.lock.Unlock()
1350+
1351+
if !f.valid {
1352+
return errBadFilter
1353+
}
1354+
1355+
if retCode := C.seccomp_transaction_commit(f.filterCtx); retCode < 0 {
1356+
return errRc(retCode)
1357+
}
1358+
1359+
return nil
1360+
}

seccomp_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,3 +1072,61 @@ func subprocessNotifUnsupported(t *testing.T) {
10721072
t.Error("GetNotifFd: got nil, want error")
10731073
}
10741074
}
1075+
1076+
func TestTransaction(t *testing.T) {
1077+
execInSubprocess(t, testTransaction)
1078+
}
1079+
1080+
func testTransaction(t *testing.T) {
1081+
if err := checkAPI("seccomp transaction support", 0, 2, 6, 0); err != nil {
1082+
t.Skip(err)
1083+
}
1084+
1085+
filter, err := NewFilter(ActAllow)
1086+
if err != nil {
1087+
t.Fatalf("Error creating filter: %s", err)
1088+
}
1089+
defer filter.Release()
1090+
1091+
if err := filter.TransactionStart(); err != nil {
1092+
t.Fatalf("Error starting transaction: %v", err)
1093+
}
1094+
if err := filter.AddRuleExact(ScmpSyscall(0x1), ActKill); err != nil {
1095+
t.Fatalf("Error adding rule: %v", err)
1096+
}
1097+
if err := filter.TransactionCommit(); err != nil {
1098+
t.Fatalf("Error committing transaction: %v", err)
1099+
}
1100+
1101+
if err := filter.TransactionStart(); err != nil {
1102+
t.Fatalf("Error starting transaction: %v", err)
1103+
}
1104+
if err := filter.AddRuleExact(ScmpSyscall(0x1), ActKill); err != nil {
1105+
t.Fatalf("Error adding rule: %v", err)
1106+
}
1107+
filter.TransactionReject()
1108+
}
1109+
1110+
func TestTransactionUnsupported(t *testing.T) {
1111+
execInSubprocess(t, testTransactionUnsupported)
1112+
}
1113+
1114+
func testTransactionUnsupported(t *testing.T) {
1115+
if checkAPI("seccomp transaction support", 0, 2, 6, 0) == nil {
1116+
t.Skip("seccomp transaction is supported")
1117+
}
1118+
1119+
filter, err := NewFilter(ActAllow)
1120+
if err != nil {
1121+
t.Fatalf("Error creating filter: %s", err)
1122+
}
1123+
defer filter.Release()
1124+
1125+
if filter.TransactionStart() == nil {
1126+
t.Error("TransactionStart: want error, got nil")
1127+
}
1128+
if filter.TransactionCommit() == nil {
1129+
t.Fatalf("TransactionCommit: want error, got nil")
1130+
}
1131+
filter.TransactionReject()
1132+
}

0 commit comments

Comments
 (0)