/* NOTE - function header comment in include/seccomp.h */
API scmp_filter_ctx seccomp_init(uint32_t def_action)
{
- if (db_action_valid(def_action) < 0)
+ if (db_col_action_valid(NULL, def_action) < 0)
return NULL;
return db_col_init(def_action);
{
struct db_filter_col *col = (struct db_filter_col *)ctx;
- if (ctx == NULL || db_action_valid(def_action) < 0)
+ /* use a NULL filter collection here since we are resetting it */
+ if (ctx == NULL || db_col_action_valid(NULL, def_action) < 0)
return -EINVAL;
return db_col_reset(col, def_action);
if (db_col_valid(col) || _syscall_valid(col, syscall))
return -EINVAL;
- rc = db_action_valid(action);
+ rc = db_col_action_valid(col, action);
if (rc < 0)
return rc;
if (action == col->attr.act_default)
if (db_col_valid(col) || _syscall_valid(col, syscall))
return -EINVAL;
- rc = db_action_valid(action);
+ rc = db_col_action_valid(col, action);
if (rc < 0)
return rc;
if (action == col->attr.act_default)
/* set the state */
col->state = _DB_STA_VALID;
+ if (def_action == SCMP_ACT_NOTIFY)
+ col->notify_used = true;
+ else
+ col->notify_used = false;
/* reset the initial db */
db = _db_init(arch_def_native);
}
/**
- * Validate the seccomp action
- * @param action the seccomp action
+ * Validate a filter collection
+ * @param col the seccomp filter collection
+ *
+ * This function validates a seccomp filter collection. Returns zero if the
+ * collection is valid, negative values on failure.
*
- * Verify that the given action is a valid seccomp action; return zero if
- * valid, -EINVAL if invalid.
*/
-int db_action_valid(uint32_t action)
+int db_col_valid(struct db_filter_col *col)
{
- if (sys_chk_seccomp_action(action) == 1)
+ if (col != NULL && col->state == _DB_STA_VALID && col->filter_cnt > 0)
return 0;
return -EINVAL;
}
/**
- * Validate a filter collection
+ * Validate the seccomp action
* @param col the seccomp filter collection
+ * @param action the seccomp action
*
- * This function validates a seccomp filter collection. Returns zero if the
- * collection is valid, negative values on failure.
- *
+ * Verify that the given action is a valid seccomp action; return zero if
+ * valid, -EINVAL if invalid.
*/
-int db_col_valid(struct db_filter_col *col)
+int db_col_action_valid(const struct db_filter_col *col, uint32_t action)
{
- if (col != NULL && col->state == _DB_STA_VALID && col->filter_cnt > 0)
+ if (col != NULL) {
+ /* NOTE: in some cases we don't have a filter collection yet,
+ * but when we do we need to do the following checks */
+
+ /* kernel disallows TSYNC and NOTIFY in one filter */
+ if (col->attr.tsync_enable && action == SCMP_ACT_NOTIFY)
+ return -EINVAL;
+ }
+
+ if (sys_chk_seccomp_action(action) == 1)
return 0;
return -EINVAL;
}
return -EACCES;
break;
case SCMP_FLTATR_ACT_BADARCH:
- if (db_action_valid(value) == 0)
+ if (db_col_action_valid(col, value) == 0)
col->attr.act_badarch = value;
else
return -EINVAL;
if (rc == 1) {
/* supported */
rc = 0;
+ /* kernel disallows TSYNC and NOTIFY in one filter */
+ if (value && col->notify_used)
+ return -EINVAL;
col->attr.tsync_enable = (value ? 1 : 0);
} else if (rc == 0)
/* unsupported */
db_col_transaction_abort(col);
add_return:
+ /* update the misc state */
+ if (rc == 0 && action == SCMP_ACT_NOTIFY)
+ col->notify_used = true;
if (chain != NULL)
free(chain);
return rc;
/* notification fd that was returned from seccomp() */
int notify_fd;
+ bool notify_used;
};
/**
#define db_list_foreach(iter,list) \
for (iter = (list); iter != NULL; iter = iter->next)
-int db_action_valid(uint32_t action);
-
struct db_api_rule_list *db_rule_dup(const struct db_api_rule_list *src);
struct db_filter_col *db_col_init(uint32_t def_action);
int db_col_valid(struct db_filter_col *col);
+int db_col_action_valid(const struct db_filter_col *col, uint32_t action);
+
int db_col_merge(struct db_filter_col *col_dst, struct db_filter_col *col_src);
int db_col_arch_exist(struct db_filter_col *col, uint32_t arch_token);