summaryrefslogtreecommitdiff
path: root/src/api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/api.c')
-rw-r--r--src/api.c251
1 files changed, 34 insertions, 217 deletions
diff --git a/src/api.c b/src/api.c
index 0cfa407..a4f9deb 100644
--- a/src/api.c
+++ b/src/api.c
@@ -69,51 +69,21 @@ static int _syscall_valid(int syscall)
/* NOTE - function header comment in include/seccomp.h */
API scmp_filter_ctx seccomp_init(uint32_t def_action)
{
- struct db_filter_col *col;
- struct db_filter *db;
-
if (db_action_valid(def_action) < 0)
return NULL;
- col = db_col_init(def_action);
- if (col == NULL)
- return NULL;
- db = db_init(arch_def_native);
- if (db == NULL)
- goto init_failure_col;
-
- if (db_col_db_add(col, db) < 0)
- goto init_failure_db;
-
- return col;
-
-init_failure_db:
- db_release(db);
-init_failure_col:
- db_col_release(col);
- return NULL;
+ return db_col_init(def_action);
}
/* NOTE - function header comment in include/seccomp.h */
API int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action)
{
- int rc;
struct db_filter_col *col = (struct db_filter_col *)ctx;
- struct db_filter *db;
if (ctx == NULL || db_action_valid(def_action) < 0)
return -EINVAL;
- db_col_reset(col, def_action);
-
- db = db_init(arch_def_native);
- if (db == NULL)
- return -ENOMEM;
- rc = db_col_db_add(col, db);
- if (rc < 0)
- db_release(db);
-
- return rc;
+ return db_col_reset(col, def_action);
}
/* NOTE - function header comment in include/seccomp.h */
@@ -180,9 +150,7 @@ API int seccomp_arch_exist(const scmp_filter_ctx ctx,
/* NOTE - function header comment in include/seccomp.h */
API int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token)
{
- int rc;
const struct arch_def *arch;
- struct db_filter *db;
struct db_filter_col *col = (struct db_filter_col *)ctx;
if (arch_token == 0)
@@ -196,14 +164,7 @@ API int seccomp_arch_add(scmp_filter_ctx ctx, uint32_t arch_token)
arch = arch_def_lookup(arch_token);
if (arch == NULL)
return -EFAULT;
- db = db_init(arch);
- if (db == NULL)
- return -ENOMEM;
- rc = db_col_db_add(col, db);
- if (rc < 0)
- db_release(db);
-
- return rc;
+ return db_col_db_new(col, arch);
}
/* NOTE - function header comment in include/seccomp.h */
@@ -336,81 +297,25 @@ API int seccomp_syscall_resolve_name(const char *name)
API int seccomp_syscall_priority(scmp_filter_ctx ctx,
int syscall, uint8_t priority)
{
- int rc = 0, rc_tmp;
- unsigned int iter;
- int sc_tmp;
- struct db_filter_col *col;
- struct db_filter *filter;
+ struct db_filter_col *col = (struct db_filter_col *)ctx;
- if (_ctx_valid(ctx) || _syscall_valid(syscall))
+ if (db_col_valid(col) || _syscall_valid(syscall))
return -EINVAL;
- col = (struct db_filter_col *)ctx;
- for (iter = 0; iter < col->filter_cnt; iter++) {
- filter = col->filters[iter];
- sc_tmp = syscall;
-
- rc_tmp = arch_syscall_translate(filter->arch, &sc_tmp);
- if (rc_tmp < 0)
- goto syscall_priority_failure;
-
- /* if this is a pseudo syscall (syscall < 0) then we need to
- * rewrite the syscall for some arch specific reason */
- if (sc_tmp < 0) {
- /* we set this as a strict op - we don't really care
- * since priorities are a "best effort" thing - as we
- * want to catch the -EDOM error and bail on this
- * architecture */
- rc_tmp = arch_syscall_rewrite(filter->arch, &sc_tmp);
- if (rc_tmp == -EDOM)
- continue;
- if (rc_tmp < 0)
- goto syscall_priority_failure;
- }
-
- rc_tmp = db_syscall_priority(filter, sc_tmp, priority);
-
-syscall_priority_failure:
- if (rc == 0 && rc_tmp < 0)
- rc = rc_tmp;
- }
-
- return rc;
+ return db_col_syscall_priority(col, syscall, priority);
}
-/**
- * Add a new rule to the current filter
- * @param col the filter collection
- * @param strict the strict flag
- * @param action the filter action
- * @param syscall the syscall number
- * @param arg_cnt the number of argument filters in the argument filter chain
- * @param arg_array the argument filter chain, (uint, enum scmp_compare, ulong)
- *
- * This function adds a new argument/comparison/value to the seccomp filter for
- * a syscall; multiple arguments can be specified and they will be chained
- * together (essentially AND'd together) in the filter. When the strict flag
- * is true the function will fail if the exact rule can not be added to the
- * filter, if the strict flag is false the function will not fail if the
- * function needs to adjust the rule due to architecture specifics. Returns
- * zero on success, negative values on failure.
- *
- */
-static int _seccomp_rule_add(struct db_filter_col *col,
- bool strict, uint32_t action, int syscall,
- unsigned int arg_cnt,
- const struct scmp_arg_cmp *arg_array)
+/* NOTE - function header comment in include/seccomp.h */
+API int seccomp_rule_add_array(scmp_filter_ctx ctx,
+ uint32_t action, int syscall,
+ unsigned int arg_cnt,
+ const struct scmp_arg_cmp *arg_array)
{
- int rc = 0, rc_tmp;
- int sc_tmp;
- unsigned int iter;
- unsigned int chain_len;
- unsigned int arg_num;
- size_t chain_size;
- struct db_filter *filter;
- struct db_api_arg *chain = NULL, *chain_tmp;
- struct scmp_arg_cmp arg_data;
+ int rc;
+ struct db_filter_col *col = (struct db_filter_col *)ctx;
+ if (arg_cnt > ARG_COUNT_MAX)
+ return -EINVAL;
if (arg_cnt > 0 && arg_array == NULL)
return -EINVAL;
@@ -423,110 +328,7 @@ static int _seccomp_rule_add(struct db_filter_col *col,
if (action == col->attr.act_default)
return -EPERM;
- if (strict && col->filter_cnt > 1)
- return -EOPNOTSUPP;
-
- /* collect the arguments for the filter rule */
- chain_len = ARG_COUNT_MAX;
- chain_size = sizeof(*chain) * chain_len;
- chain = malloc(chain_size);
- if (chain == NULL)
- return -ENOMEM;
- memset(chain, 0, chain_size);
- for (iter = 0; iter < arg_cnt; iter++) {
- arg_data = arg_array[iter];
- arg_num = arg_data.arg;
- if (arg_num < chain_len && chain[arg_num].valid == 0) {
- chain[arg_num].valid = 1;
- chain[arg_num].arg = arg_num;
- chain[arg_num].op = arg_data.op;
- /* XXX - we should check datum/mask size against the
- * arch definition, e.g. 64 bit datum on x86 */
- switch (chain[arg_num].op) {
- case SCMP_CMP_NE:
- case SCMP_CMP_LT:
- case SCMP_CMP_LE:
- case SCMP_CMP_EQ:
- case SCMP_CMP_GE:
- case SCMP_CMP_GT:
- chain[arg_num].mask = DATUM_MAX;
- chain[arg_num].datum = arg_data.datum_a;
- break;
- case SCMP_CMP_MASKED_EQ:
- chain[arg_num].mask = arg_data.datum_a;
- chain[arg_num].datum = arg_data.datum_b;
- break;
- default:
- rc = -EINVAL;
- goto rule_add_return;
- }
- } else {
- rc = -EINVAL;
- goto rule_add_return;
- }
- }
-
- for (iter = 0; iter < col->filter_cnt; iter++) {
- filter = col->filters[iter];
- sc_tmp = syscall;
-
- rc_tmp = arch_syscall_translate(filter->arch, &sc_tmp);
- if (rc_tmp < 0)
- goto rule_add_failure;
-
- /* if this is a pseudo syscall (syscall < 0) then we need to
- * rewrite the rule for some arch specific reason */
- if (sc_tmp < 0) {
- /* make a private copy of the chain */
- chain_tmp = malloc(chain_size);
- if (chain_tmp == NULL) {
- rc = -ENOMEM;
- goto rule_add_failure;
- }
- memcpy(chain_tmp, chain, chain_size);
-
- /* mangle the private chain copy */
- rc_tmp = arch_filter_rewrite(filter->arch, strict,
- &sc_tmp, chain_tmp);
- if ((rc_tmp == -EDOM) && (!strict)) {
- free(chain_tmp);
- continue;
- }
- if (rc_tmp < 0) {
- free(chain_tmp);
- goto rule_add_failure;
- }
-
- /* add the new rule to the existing filter */
- rc_tmp = db_rule_add(filter, action, sc_tmp, chain_tmp);
- free(chain_tmp);
- } else
- /* add the new rule to the existing filter */
- rc_tmp = db_rule_add(filter, action, sc_tmp, chain);
-
-rule_add_failure:
- if (rc == 0 && rc_tmp < 0)
- rc = rc_tmp;
- }
-
-rule_add_return:
- if (chain != NULL)
- free(chain);
- return rc;
-}
-
-/* NOTE - function header comment in include/seccomp.h */
-API int seccomp_rule_add_array(scmp_filter_ctx ctx,
- uint32_t action, int syscall,
- unsigned int arg_cnt,
- const struct scmp_arg_cmp *arg_array)
-{
- /* arg_cnt is unsigned, so no need to check the lower bound */
- if (arg_cnt > ARG_COUNT_MAX)
- return -EINVAL;
-
- return _seccomp_rule_add((struct db_filter_col *)ctx,
- 0, action, syscall, arg_cnt, arg_array);
+ return db_col_rule_add(col, 0, action, syscall, arg_cnt, arg_array);
}
/* NOTE - function header comment in include/seccomp.h */
@@ -558,12 +360,27 @@ API int seccomp_rule_add_exact_array(scmp_filter_ctx ctx,
unsigned int arg_cnt,
const struct scmp_arg_cmp *arg_array)
{
- /* arg_cnt is unsigned, so no need to check the lower bound */
+ int rc;
+ struct db_filter_col *col = (struct db_filter_col *)ctx;
+
if (arg_cnt > ARG_COUNT_MAX)
return -EINVAL;
+ if (arg_cnt > 0 && arg_array == NULL)
+ return -EINVAL;
+
+ if (db_col_valid(col) || _syscall_valid(syscall))
+ return -EINVAL;
+
+ rc = db_action_valid(action);
+ if (rc < 0)
+ return rc;
+ if (action == col->attr.act_default)
+ return -EPERM;
+
+ if (col->filter_cnt > 1)
+ return -EOPNOTSUPP;
- return _seccomp_rule_add((struct db_filter_col *)ctx,
- 1, action, syscall, arg_cnt, arg_array);
+ return db_col_rule_add(col, 1, action, syscall, arg_cnt, arg_array);
}
/* NOTE - function header comment in include/seccomp.h */