Skip to content

Commit

Permalink
xxx: work in progress
Browse files Browse the repository at this point in the history
Signed-off-by: Paul Moore <[email protected]>
  • Loading branch information
pcmoore committed May 9, 2023
1 parent bbb9a81 commit 1fb3f2a
Show file tree
Hide file tree
Showing 11 changed files with 268 additions and 12 deletions.
15 changes: 15 additions & 0 deletions include/seccomp.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -849,6 +849,21 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd);
*/
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf, size_t *len);

/**
* XXX
*/
int seccomp_transaction_start(const scmp_filter_ctx ctx);

/**
* XXX
*/
void seccomp_transaction_reject(const scmp_filter_ctx ctx);

/**
* XXX
*/
int seccomp_transaction_commit(const scmp_filter_ctx ctx);

/**
* Precompute the seccomp filter for future use
* @param ctx the filter context
Expand Down
41 changes: 41 additions & 0 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -793,6 +793,47 @@ API int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
return rc;
}

/* NOTE - function header comment in include/seccomp.h */
API int seccomp_transaction_start(const scmp_filter_ctx ctx)
{
int rc;
struct db_filter_col *col;

if (_ctx_valid(ctx))
return _rc_filter(-EINVAL);
col = (struct db_filter_col *)ctx;

rc = db_col_transaction_start(col, true);

/* XXX - check return codes */
return _rc_filter(rc);
}

/* NOTE - function header comment in include/seccomp.h */
API void seccomp_transaction_reject(const scmp_filter_ctx ctx)
{
struct db_filter_col *col;

if (_ctx_valid(ctx))
return;
col = (struct db_filter_col *)ctx;

db_col_transaction_abort(col, true);
}

/* NOTE - function header comment in include/seccomp.h */
API int seccomp_transaction_commit(const scmp_filter_ctx ctx)
{
struct db_filter_col *col;

if (_ctx_valid(ctx))
return _rc_filter(-EINVAL);
col = (struct db_filter_col *)ctx;

db_col_transaction_commit(col, true);
return _rc_filter(0);
}

/* NOTE - function header comment in include/seccomp.h */
API int seccomp_precompute(const scmp_filter_ctx ctx)
{
Expand Down
22 changes: 16 additions & 6 deletions src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -2369,7 +2369,7 @@ int db_col_rule_add(struct db_filter_col *col,
}

/* create a checkpoint */
rc = db_col_transaction_start(col);
rc = db_col_transaction_start(col, false);
if (rc != 0)
goto add_return;

Expand All @@ -2396,9 +2396,9 @@ int db_col_rule_add(struct db_filter_col *col,

/* commit the transaction or abort */
if (rc == 0)
db_col_transaction_commit(col);
db_col_transaction_commit(col, false);
else
db_col_transaction_abort(col);
db_col_transaction_abort(col, false);

add_return:
/* update the misc state */
Expand All @@ -2415,12 +2415,13 @@ int db_col_rule_add(struct db_filter_col *col,
/**
* Start a new seccomp filter transaction
* @param col the filter collection
* @param user true if initiated by a user
*
* This function starts a new seccomp filter transaction for the given filter
* collection. Returns zero on success, negative values on failure.
*
*/
int db_col_transaction_start(struct db_filter_col *col)
int db_col_transaction_start(struct db_filter_col *col, bool user)
{
int rc;
unsigned int iter;
Expand All @@ -2439,6 +2440,7 @@ int db_col_transaction_start(struct db_filter_col *col)
* transaction is current/correct */

col->snapshots->shadow = false;
col->snapshots->user = user;
return 0;
}

Expand Down Expand Up @@ -2486,6 +2488,8 @@ int db_col_transaction_start(struct db_filter_col *col)
} while (rule_o != filter_o->rules);
}

snap->user = user;

/* add the snapshot to the list */
snap->next = col->snapshots;
col->snapshots = snap;
Expand All @@ -2502,11 +2506,12 @@ int db_col_transaction_start(struct db_filter_col *col)
/**
* Abort the top most seccomp filter transaction
* @param col the filter collection
* @param user true if initiated by a user
*
* This function aborts the most recent seccomp filter transaction.
*
*/
void db_col_transaction_abort(struct db_filter_col *col)
void db_col_transaction_abort(struct db_filter_col *col, bool user)
{
int iter;
unsigned int filter_cnt;
Expand All @@ -2516,6 +2521,8 @@ void db_col_transaction_abort(struct db_filter_col *col)
snap = col->snapshots;
if (snap == NULL)
return;
if (snap->user != user)
return;

/* replace the current filter with the last snapshot, skipping shadow
* snapshots are they are duplicates of the current snapshot */
Expand Down Expand Up @@ -2544,13 +2551,14 @@ void db_col_transaction_abort(struct db_filter_col *col)
/**
* Commit the top most seccomp filter transaction
* @param col the filter collection
* @param user true if initiated by a user
*
* This function commits the most recent seccomp filter transaction and
* attempts to create a shadow transaction that is a duplicate of the current
* filter to speed up future transactions.
*
*/
void db_col_transaction_commit(struct db_filter_col *col)
void db_col_transaction_commit(struct db_filter_col *col, bool user)
{
int rc;
unsigned int iter;
Expand All @@ -2561,6 +2569,8 @@ void db_col_transaction_commit(struct db_filter_col *col)
snap = col->snapshots;
if (snap == NULL)
return;
if (snap->user != user)
return;

/* check for a shadow set by a higher transaction commit */
if (snap->shadow) {
Expand Down
7 changes: 4 additions & 3 deletions src/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ struct db_filter_snap {
struct db_filter **filters;
unsigned int filter_cnt;
bool shadow;
bool user;

struct db_filter_snap *next;
};
Expand Down Expand Up @@ -215,9 +216,9 @@ int db_col_rule_add(struct db_filter_col *col,
int db_col_syscall_priority(struct db_filter_col *col,
int syscall, uint8_t priority);

int db_col_transaction_start(struct db_filter_col *col);
void db_col_transaction_abort(struct db_filter_col *col);
void db_col_transaction_commit(struct db_filter_col *col);
int db_col_transaction_start(struct db_filter_col *col, bool user);
void db_col_transaction_abort(struct db_filter_col *col, bool user);
void db_col_transaction_commit(struct db_filter_col *col, bool user);

int db_col_precompute(struct db_filter_col *col);
void db_col_precompute_reset(struct db_filter_col *col);
Expand Down
4 changes: 4 additions & 0 deletions src/python/libseccomp.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,10 @@ cdef extern from "seccomp.h":
int seccomp_export_bpf_mem(const scmp_filter_ctx ctx, void *buf,
size_t *len)

int seccomp_transaction_start(const scmp_filter_ctx ctx)
void seccomp_transaction_reject(const scmp_filter_ctx ctx)
int seccomp_transaction_commit(const scmp_filter_ctx ctx)

int seccomp_precompute(const scmp_filter_ctx ctx)

# kate: syntax python;
Expand Down
28 changes: 28 additions & 0 deletions src/python/seccomp.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,34 @@ cdef class SyscallFilter:
raise RuntimeError(str.format("Library error (errno = {0})", rc))
return program

def start_transaction(self):
""" Start a transaction.
Description:
XXX
"""
rc = libseccomp.seccomp_transaction_start(self._ctx)
if rc != 0:
raise RuntimeError(str.format("Library error (errno = {0})", rc))

def reject_transaction(self):
""" Reject a transaction.
Description:
XXX
"""
libseccomp.seccomp_transaction_reject(self._ctx)

def commit_transaction(self):
""" Commit a transaction.
Description:
XXX
"""
rc = libseccomp.seccomp_transaction_commit(self._ctx)
if rc != 0:
raise RuntimeError(str.format("Library error (errno = {0})", rc))

def precompute(self):
""" Precompute the seccomp filter.
Expand Down
1 change: 1 addition & 0 deletions tests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ util.pyc
58-live-tsync_notify
59-basic-empty_binary_tree
60-sim-precompute
61-sim-transactions
85 changes: 85 additions & 0 deletions tests/61-sim-transactions.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* Seccomp Library test program
*
* Copyright (c) 2023 Microsoft Corporation <[email protected]>
* Author: Paul Moore <[email protected]>
*/

/*
* This library is free software; you can redistribute it and/or modify it
* under the terms of version 2.1 of the GNU Lesser General Public License as
* published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, see <https://www.gnu.org/licenses>.
*/

#include <errno.h>
#include <unistd.h>

#include <seccomp.h>

#include "util.h"

int main(int argc, char *argv[])
{
int rc;
struct util_options opts;
scmp_filter_ctx ctx = NULL;

rc = util_getopt(argc, argv, &opts);
if (rc < 0)
goto out;

ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL)
return ENOMEM;

#if 1
rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1000, 0);
if (rc != 0)
goto out;
#endif

{
int i;
for (i = 0; i < 2; i++) {
rc = seccomp_transaction_start(ctx);
if (rc != 0)
goto out;
}
}
rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1001, 0);
if (rc != 0)
goto out;
{
int i;
for (i = 0; i < 1; i++) {
rc = seccomp_transaction_commit(ctx);
if (rc != 0)
goto out;
}
for (i = 0; i < 1; i++) {
seccomp_transaction_reject(ctx);
}
}

#if 1
rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, 1002, 0);
if (rc != 0)
goto out;
#endif

rc = util_filter_output(&opts, ctx);
if (rc)
goto out;

out:
seccomp_release(ctx);
return (rc < 0 ? -rc : rc);
}
45 changes: 45 additions & 0 deletions tests/61-sim-transactions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env python

#
# Seccomp Library test program
#
# Copyright (c) 2023 Microsoft Corporation <[email protected]>
# Author: Paul Moore <[email protected]>
#

#
# This library is free software; you can redistribute it and/or modify it
# under the terms of version 2.1 of the GNU Lesser General Public License as
# published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
# for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this library; if not, see <https://www.gnu.org/licenses>.
#

import argparse
import sys

import util

from seccomp import *

def test(args):
f = SyscallFilter(ALLOW)
f.precompute()
f.add_rule_exactly(KILL, 1000)
f.precompute()
f.add_rule_exactly(KILL, 1001)
f.precompute()
return f

args = util.get_opt()
ctx = test(args)
util.filter_output(args, ctx)

# kate: syntax python;
# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off;
23 changes: 23 additions & 0 deletions tests/61-sim-transactions.tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# libseccomp regression test automation data
#
# Copyright (c) 2023 Microsoft Corporation <[email protected]>
# Author: Paul Moore <[email protected]>
#

test type: bpf-sim

# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
61-sim-transactions all 1000 N N N N N N KILL
61-sim-transactions all 1001 N N N N N N ALLOW
61-sim-transactions all 1002 N N N N N N KILL

test type: bpf-sim-fuzz

# Testname StressCount
61-sim-transactions 5

test type: bpf-valgrind

# Testname
61-sim-transactions
Loading

0 comments on commit 1fb3f2a

Please sign in to comment.