In order to support systems that can run applications from multiple
architectures we need to be able to support multiple filter DBs; were
calling this "filter collections".  This patch adds the basic
collection support such that it passes all of the existing tests;
further work may be necessary once we start using the multiple filter
capabilities.

Signed-off-by: Paul Moore <[email protected]>
---
 0 files changed

diff --git a/src/api.c b/src/api.c
index 3e7f8d7..f698f54 100644
--- a/src/api.c
+++ b/src/api.c
@@ -46,7 +46,7 @@
  */
 static int _ctx_valid(const scmp_filter_ctx *ctx)
 {
-       return db_valid((struct db_filter *)ctx);
+       return db_col_valid((struct db_filter_col *)ctx);
 }
 
 /**
@@ -67,20 +67,51 @@ static int _syscall_valid(int syscall)
 /* NOTE - function header comment in include/seccomp.h */
 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;
 
-       return db_init(&arch_def_native, def_action);
+       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;
 }
 
 /* NOTE - function header comment in include/seccomp.h */
 int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action)
 {
-       if (_ctx_valid(ctx) || db_action_valid(def_action) < 0)
+       int rc;
+       struct db_filter_col *col = (struct db_filter_col *)ctx;
+       struct db_filter *db;
+
+       if (db_col_valid(col) || db_action_valid(def_action) < 0)
                return -EINVAL;
 
-       db_reset((struct db_filter *)ctx, def_action);
-       return 0;
+       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;
 }
 
 /* NOTE - function header comment in include/seccomp.h */
@@ -89,25 +120,25 @@ void seccomp_release(scmp_filter_ctx ctx)
        if (_ctx_valid(ctx))
                return;
 
-       db_release((struct db_filter *)ctx);
+       db_col_release((struct db_filter_col *)ctx);
 }
 
 /* NOTE - function header comment in include/seccomp.h */
 int seccomp_load(const scmp_filter_ctx ctx)
 {
        int rc;
-       struct db_filter *filter;
+       struct db_filter_col *col;
        struct bpf_program *program;
 
        if (_ctx_valid(ctx))
                return -EINVAL;
-       filter = (struct db_filter *)ctx;
+       col = (struct db_filter_col *)ctx;
 
-       program = gen_bpf_generate(filter);
+       program = gen_bpf_generate((struct db_filter_col *)ctx);
        if (program == NULL)
                return -ENOMEM;
-       /* attempt to set NO_NEW_PRIVS but don't fail if it doesn't work */
-       if (filter->attr.nnp_enable) {
+       /* attempt to set NO_NEW_PRIVS */
+       if (col->attr.nnp_enable) {
                rc = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
                if (rc < 0)
                        return -errno;
@@ -128,7 +159,7 @@ int seccomp_attr_get(const scmp_filter_ctx ctx,
        if (_ctx_valid(ctx))
                return -EINVAL;
 
-       return db_attr_get((const struct db_filter *)ctx, attr, value);
+       return db_col_attr_get((const struct db_filter_col *)ctx, attr, value);
 }
 
 /* NOTE - function header comment in include/seccomp.h */
@@ -138,7 +169,7 @@ int seccomp_attr_set(scmp_filter_ctx ctx,
        if (_ctx_valid(ctx))
                return -EINVAL;
 
-       return db_attr_set((struct db_filter *)ctx, attr, value);
+       return db_col_attr_set((struct db_filter_col *)ctx, attr, value);
 }
 
 /* NOTE - function header comment in include/seccomp.h */
@@ -153,31 +184,46 @@ int seccomp_syscall_resolve_name(const char *name)
 /* NOTE - function header comment in include/seccomp.h */
 int seccomp_syscall_priority(scmp_filter_ctx ctx, int syscall, uint8_t 
priority)
 {
-       int rc;
+       int rc = 0, rc_tmp;
+       unsigned int iter;
+       int syscall_tmp;
+       struct db_filter_col *col;
        struct db_filter *filter;
 
        if (_ctx_valid(ctx) || _syscall_valid(syscall))
                return -EINVAL;
-       filter = (struct db_filter *)ctx;
+       col = (struct db_filter_col *)ctx;
+
+       for (iter = 0; iter < col->filter_cnt; iter++) {
+               filter = col->filters[iter];
+               syscall_tmp = syscall;
+
+               rc_tmp = arch_syscall_translate(filter->arch, &syscall_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 (syscall_tmp < 0) {
+                       rc_tmp = arch_syscall_rewrite(filter->arch,
+                                                     &syscall_tmp);
+                       if (rc_tmp < 0)
+                               goto syscall_priority_failure;
+               }
 
-       rc = arch_syscall_translate(filter->arch, &syscall);
-       if (rc < 0)
-               return rc;
+               rc_tmp = db_syscall_priority(filter, syscall_tmp, priority);
 
-       /* if this is a pseudo syscall (syscall < 0) then we need to rewrite
-        * the syscall for some arch specific reason */
-       if (syscall < 0) {
-               rc = arch_syscall_rewrite(filter->arch, &syscall);
-               if (rc < 0)
-                       return rc;
+syscall_priority_failure:
+               if (rc == 0 && rc_tmp < 0)
+                       rc = rc_tmp;
        }
 
-       return db_syscall_priority(filter, syscall, priority);
+       return rc;
 }
 
 /**
  * Add a new rule to the current filter
- * @param filter the DB filter
+ * @param col the filter collection
  * @param strict the strict flag
  * @param action the filter action
  * @param syscall the syscall number
@@ -193,32 +239,30 @@ int seccomp_syscall_priority(scmp_filter_ctx ctx, int 
syscall, uint8_t priority)
  * zero on success, negative values on failure.
  *
  */
-static int _seccomp_rule_add(struct db_filter *filter,
+static int _seccomp_rule_add(struct db_filter_col *col,
                             unsigned int strict, uint32_t action, int syscall,
                             unsigned int arg_cnt, va_list arg_list)
 {
-       int rc;
+       int rc = 0, rc_tmp;
+       int syscall_tmp;
        unsigned int iter;
        unsigned int chain_len_max;
        unsigned int arg_num;
+       struct db_filter *filter;
        struct db_api_arg *chain = NULL;
        struct scmp_arg_cmp arg_data;
 
-       if (db_valid(filter) || _syscall_valid(syscall))
+       if (db_col_valid(col) || _syscall_valid(syscall))
                return -EINVAL;
 
        rc = db_action_valid(action);
        if (rc < 0)
                return rc;
-       if (action == filter->attr.act_default)
+       if (action == col->attr.act_default)
                return -EPERM;
 
-       rc = arch_syscall_translate(filter->arch, &syscall);
-       if (rc < 0)
-               return rc;
-
        /* collect the arguments for the filter rule */
-       chain_len_max = arch_arg_count_max(filter->arch);
+       chain_len_max = ARG_COUNT_MAX;
        chain = malloc(sizeof(*chain) * chain_len_max);
        if (chain == NULL)
                return -ENOMEM;
@@ -256,16 +300,30 @@ static int _seccomp_rule_add(struct db_filter *filter,
                }
        }
 
-       /* if this is a pseudo syscall (syscall < 0) then we need to rewrite
-        * the rule for some arch specific reason */
-       if (syscall < 0) {
-               rc = arch_filter_rewrite(filter->arch, strict, &syscall, chain);
-               if (rc < 0)
-                       goto rule_add_return;
-       }
+       for (iter = 0; iter < col->filter_cnt; iter++) {
+               filter = col->filters[iter];
+               syscall_tmp = syscall;
+
+               rc_tmp = arch_syscall_translate(filter->arch, &syscall_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 (syscall_tmp < 0) {
+                       rc_tmp = arch_filter_rewrite(filter->arch, strict,
+                                                    &syscall_tmp, chain);
+                       if (rc_tmp < 0)
+                               goto rule_add_failure;
+               }
 
-       /* add the new rule to the existing filter */
-       rc = db_rule_add(filter, action, syscall, chain);
+               /* add the new rule to the existing filter */
+               rc_tmp = db_rule_add(filter, action, syscall_tmp, chain);
+
+rule_add_failure:
+               if (rc == 0 && rc_tmp < 0)
+                       rc = rc_tmp;
+       }
 
 rule_add_return:
        if (chain != NULL)
@@ -281,7 +339,7 @@ int seccomp_rule_add(scmp_filter_ctx ctx,
        va_list arg_list;
 
        va_start(arg_list, arg_cnt);
-       rc = _seccomp_rule_add((struct db_filter *)ctx,
+       rc = _seccomp_rule_add((struct db_filter_col *)ctx,
                               0, action, syscall, arg_cnt, arg_list);
        va_end(arg_list);
 
@@ -296,7 +354,7 @@ int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t 
action,
        va_list arg_list;
 
        va_start(arg_list, arg_cnt);
-       rc = _seccomp_rule_add((struct db_filter *)ctx,
+       rc = _seccomp_rule_add((struct db_filter_col *)ctx,
                               1, action, syscall, arg_cnt, arg_list);
        va_end(arg_list);
 
@@ -309,7 +367,7 @@ int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd)
        if (_ctx_valid(ctx))
                return -EINVAL;
 
-       return gen_pfc_generate((struct db_filter *)ctx, fd);
+       return gen_pfc_generate((struct db_filter_col *)ctx, fd);
 }
 
 /* NOTE - function header comment in include/seccomp.h */
@@ -321,7 +379,7 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd)
        if (_ctx_valid(ctx))
                return -EINVAL;
 
-       program = gen_bpf_generate((struct db_filter *)ctx);
+       program = gen_bpf_generate((struct db_filter_col *)ctx);
        if (program == NULL)
                return -ENOMEM;
        rc = write(fd, program->blks, BPF_PGM_SIZE(program));
diff --git a/src/arch.h b/src/arch.h
index 4e14ca6..43ef19f 100644
--- a/src/arch.h
+++ b/src/arch.h
@@ -71,8 +71,9 @@ struct arch_syscall_def {
 #define D64_LO(x)      ((uint32_t)((uint64_t)(x) & 0x00000000ffffffff))
 #define D64_HI(x)      ((uint32_t)((uint64_t)(x) >> 32))
 
-int arch_arg_count_max(const struct arch_def *arch);
+#define ARG_COUNT_MAX  6
 
+int arch_arg_count_max(const struct arch_def *arch);
 
 /**
  * Determine the argument offset
diff --git a/src/db.c b/src/db.c
index 1468cf9..174c95c 100644
--- a/src/db.c
+++ b/src/db.c
@@ -311,108 +311,101 @@ int db_action_valid(uint32_t action)
 }
 
 /**
- * Free and reset the seccomp filter DB
- * @param db the seccomp filter DB
+ * Free and reset the seccomp filter collection
+ * @param col the seccomp filter collection
  * @param def_action the default filter action
  *
- * This function frees any existing filters and resets the filter DB to a
- * default state; only the DB architecture is preserved.
+ * This function frees any existing filter DBs and resets the collection to a
+ * default state.
  *
  */
-void db_reset(struct db_filter *db, uint32_t def_action)
+void db_col_reset(struct db_filter_col *col, uint32_t def_action)
 {
-       struct db_sys_list *s_iter;
+       unsigned int iter;
 
-       if (db == NULL)
+       if (col == NULL)
                return;
 
        /* free any filters */
-       if (db->syscalls != NULL) {
-               s_iter = db->syscalls;
-               while (s_iter != NULL) {
-                       db->syscalls = s_iter->next;
-                       _db_tree_free(s_iter->chains);
-                       free(s_iter);
-                       s_iter = db->syscalls;
-               }
-               db->syscalls = NULL;
-       }
+       for (iter = 0; iter < col->filter_cnt; iter++)
+               db_release(col->filters[iter]);
+       col->filter_cnt = 0;
+       free(col->filters);
+       col->filters = NULL;
 
        /* set the default attribute values */
-       db->attr.act_default = def_action;
-       db->attr.act_badarch = SCMP_ACT_KILL;
-       db->attr.nnp_enable = 1;
+       col->attr.act_default = def_action;
+       col->attr.act_badarch = SCMP_ACT_KILL;
+       col->attr.nnp_enable = 1;
 
        /* set the state */
-       db->state = _DB_STA_VALID;
+       col->state = _DB_STA_VALID;
 }
 
 /**
- * Intitalize a seccomp filter DB
- * @param arch the architecture definition
+ * Intitalize a seccomp filter collection
  * @param def_action the default filter action
  *
- * This function initializes a seccomp filter DB and readies it for use.
- * Returns a pointer to the DB on success, NULL on failure.
+ * This function initializes a seccomp filter collection and readies it for
+ * use.  Returns a pointer to the collection on success, NULL on failure.
  *
  */
-struct db_filter *db_init(const struct arch_def *arch, uint32_t def_action)
+struct db_filter_col *db_col_init(uint32_t def_action)
 {
-       struct db_filter *db;
+       struct db_filter_col *col;
 
-       db = malloc(sizeof(*db));
-       if (db == NULL)
+       col = malloc(sizeof(*col));
+       if (col == NULL)
                return NULL;
 
-       /* clear the buffer for the first time and set the arch */
-       memset(db, 0, sizeof(*db));
-       db->arch = arch;
+       /* clear the buffer for the first time */
+       memset(col, 0, sizeof(*col));
 
        /* reset the DB to a known state */
-       db_reset(db, def_action);
+       db_col_reset(col, def_action);
 
-       return db;
+       return col;
 }
 
 /**
- * Destroy a seccomp filter DB
- * @param db the seccomp filter DB
+ * Destroy a seccomp filter collection
+ * @param col the seccomp filter collection
  *
- * This function destroys a seccomp filter DB.  After calling this function,
- * the filter should no longer be referenced.
+ * This function destroys a seccomp filter collection.  After calling this
+ * function, the filter should no longer be referenced.
  *
  */
-void db_release(struct db_filter *db)
+void db_col_release(struct db_filter_col *col)
 {
-       if (db == NULL)
+       if (col == NULL)
                return;
 
        /* set the state, just in case */
-       db->state = _DB_STA_FREED;
+       col->state = _DB_STA_FREED;
 
        /* free and reset the DB */
-       db_reset(db, 0);
-       free(db);
+       db_col_reset(col, 0);
+       free(col);
 }
 
 /**
- * Validate a filter DB
- * @param db the seccomp filter DB
+ * Validate a filter collection
+ * @param col the seccomp filter collection
  *
- * This function validates a seccomp filter DB.  Returns zero if the DB is
- * valid, negative values on failure.
+ * This function validates a seccomp filter collection.  Returns zero if the
+ * collection is valid, negative values on failure.
  *
  */
-int db_valid(struct db_filter *db)
+int db_col_valid(struct db_filter_col *col)
 {
-       if (db != NULL && db->state == _DB_STA_VALID)
+       if (col != NULL && col->state == _DB_STA_VALID)
                return 0;
        return -EINVAL;
 }
 
 /**
  * Get a filter attribute
- * @param db the seccomp filter DB
+ * @param col the seccomp filter collection
  * @param attr the filter attribute
  * @param value the filter attribute value
  *
@@ -420,18 +413,18 @@ int db_valid(struct db_filter *db)
  * on success, negative values on failure.
  *
  */
-int db_attr_get(const struct db_filter *db,
-               enum scmp_filter_attr attr, uint32_t *value)
+int db_col_attr_get(const struct db_filter_col *col,
+                   enum scmp_filter_attr attr, uint32_t *value)
 {
        switch (attr) {
        case SCMP_FLTATR_ACT_DEFAULT:
-               *value = db->attr.act_default;
+               *value = col->attr.act_default;
                break;
        case SCMP_FLTATR_ACT_BADARCH:
-               *value = db->attr.act_badarch;
+               *value = col->attr.act_badarch;
                break;
        case SCMP_FLTATR_CTL_NNP:
-               *value = db->attr.nnp_enable;
+               *value = col->attr.nnp_enable;
                break;
        default:
                return -EEXIST;
@@ -443,7 +436,7 @@ int db_attr_get(const struct db_filter *db,
 
 /**
  * Set a filter attribute
- * @param db the seccomp filter DB
+ * @param db the seccomp filter collection
  * @param attr the filter attribute
  * @param value the filter attribute value
  *
@@ -451,8 +444,8 @@ int db_attr_get(const struct db_filter *db,
  * success, negative values on failure.
  *
  */
-int db_attr_set(struct db_filter *db,
-               enum scmp_filter_attr attr, uint32_t value)
+int db_col_attr_set(struct db_filter_col *col,
+                   enum scmp_filter_attr attr, uint32_t value)
 {
        switch (attr) {
        case SCMP_FLTATR_ACT_DEFAULT:
@@ -461,12 +454,12 @@ int db_attr_set(struct db_filter *db,
                break;
        case SCMP_FLTATR_ACT_BADARCH:
                if (db_action_valid(value) == 0)
-                       db->attr.act_badarch = value;
+                       col->attr.act_badarch = value;
                else
                        return -EINVAL;
                break;
        case SCMP_FLTATR_CTL_NNP:
-               db->attr.nnp_enable = (value ? 1 : 0);
+               col->attr.nnp_enable = (value ? 1 : 0);
                break;
        default:
                return -EEXIST;
@@ -477,6 +470,109 @@ int db_attr_set(struct db_filter *db,
 }
 
 /**
+ * Add a new filter DB to a filter collection
+ * @param col the seccomp filter collection
+ * @param db the seccomp filter DB
+ *
+ * This function adds an existing seccomp filter DB to an existing seccomp
+ * filter collection assuming there isn't a filter DB already present with the
+ * same architecture.  Returns zero on success, negative values on failure.
+ *
+ */
+int db_col_db_add(struct db_filter_col *col, struct db_filter *db)
+{
+       unsigned int iter;
+       struct db_filter **dbs;
+
+       for (iter = 0; iter < col->filter_cnt; iter++)
+               if (col->filters[iter]->arch->token == db->arch->token)
+                       return -EEXIST;
+
+       dbs = realloc(col->filters,
+                     sizeof(struct db_filter *) * (col->filter_cnt + 1));
+       if (dbs == NULL)
+               return -ENOMEM;
+       col->filters = dbs;
+       col->filter_cnt++;
+       col->filters[col->filter_cnt - 1] = db;
+
+       return 0;
+}
+
+/**
+ * Free and reset the seccomp filter DB
+ * @param db the seccomp filter DB
+ * @param def_action the default filter action
+ *
+ * This function frees any existing filters and resets the filter DB to a
+ * default state; only the DB architecture is preserved.
+ *
+ */
+void db_reset(struct db_filter *db)
+{
+       struct db_sys_list *s_iter;
+
+       if (db == NULL)
+               return;
+
+       /* free any filters */
+       if (db->syscalls != NULL) {
+               s_iter = db->syscalls;
+               while (s_iter != NULL) {
+                       db->syscalls = s_iter->next;
+                       _db_tree_free(s_iter->chains);
+                       free(s_iter);
+                       s_iter = db->syscalls;
+               }
+               db->syscalls = NULL;
+       }
+}
+
+/**
+ * Intitalize a seccomp filter DB
+ * @param arch the architecture definition
+ *
+ * This function initializes a seccomp filter DB and readies it for use.
+ * Returns a pointer to the DB on success, NULL on failure.
+ *
+ */
+struct db_filter *db_init(const struct arch_def *arch)
+{
+       struct db_filter *db;
+
+       db = malloc(sizeof(*db));
+       if (db == NULL)
+               return NULL;
+
+       /* clear the buffer for the first time and set the arch */
+       memset(db, 0, sizeof(*db));
+       db->arch = arch;
+
+       /* reset the DB to a known state */
+       db_reset(db);
+
+       return db;
+}
+
+/**
+ * Destroy a seccomp filter DB
+ * @param db the seccomp filter DB
+ *
+ * This function destroys a seccomp filter DB.  After calling this function,
+ * the filter should no longer be referenced.
+ *
+ */
+void db_release(struct db_filter *db)
+{
+       if (db == NULL)
+               return;
+
+       /* free and reset the DB */
+       db_reset(db);
+       free(db);
+}
+
+/**
  * Update the user specified portion of the syscall priority
  * @param db the seccomp filter db
  * @param syscall the syscall number
diff --git a/src/db.h b/src/db.h
index b60470d..a9ebbc9 100644
--- a/src/db.h
+++ b/src/db.h
@@ -131,16 +131,23 @@ struct db_filter_attr {
 };
 
 struct db_filter {
+       /* target architecture */
+       const struct arch_def *arch;
+
+       /* syscall filters, kept as a sorted single-linked list */
+       struct db_sys_list *syscalls;
+};
+
+struct db_filter_col {
        /* verification / state */
        int state;
 
-       /* target architecture */
-       const struct arch_def *arch;
        /* attributes */
        struct db_filter_attr attr;
 
-       /* syscall filters, kept as a sorted single-linked list */
-       struct db_sys_list *syscalls;
+       /* individual filters */
+       struct db_filter **filters;
+       unsigned int filter_cnt;
 };
 
 /**
@@ -157,16 +164,22 @@ struct db_filter {
 
 int db_action_valid(uint32_t action);
 
-void db_reset(struct db_filter *db, uint32_t def_action);
-struct db_filter *db_init(const struct arch_def *arch, uint32_t def_action);
-void db_release(struct db_filter *db);
+struct db_filter_col *db_col_init(uint32_t def_action);
+void db_col_reset(struct db_filter_col *col, uint32_t def_action);
+void db_col_release(struct db_filter_col *col);
 
-int db_valid(struct db_filter *db);
+int db_col_valid(struct db_filter_col *col);
 
-int db_attr_get(const struct db_filter *db,
-               enum scmp_filter_attr attr, uint32_t *value);
-int db_attr_set(struct db_filter *db,
-               enum scmp_filter_attr attr, uint32_t value);
+int db_col_attr_get(const struct db_filter_col *col,
+                   enum scmp_filter_attr attr, uint32_t *value);
+int db_col_attr_set(struct db_filter_col *col,
+                   enum scmp_filter_attr attr, uint32_t value);
+
+int db_col_db_add(struct db_filter_col *col, struct db_filter *db);
+
+struct db_filter *db_init(const struct arch_def *arch);
+void db_reset(struct db_filter *db);
+void db_release(struct db_filter *db);
 
 int db_syscall_priority(struct db_filter *db,
                        unsigned int syscall, uint8_t priority);
diff --git a/src/gen_bpf.c b/src/gen_bpf.c
index 9e2f809..2e8407e 100644
--- a/src/gen_bpf.c
+++ b/src/gen_bpf.c
@@ -1459,20 +1459,26 @@ build_bpf_free_blks:
 
 /**
  * Generate a BPF representation of the filter DB
- * @param db the seccomp filter DB
+ * @param col the seccomp filter collection
  *
- * This function generates a BPF representation of the given filter DB.
+ * This function generates a BPF representation of the given filter collection.
  * Returns a pointer to a valid bpf_program on success, NULL on failure.
  *
  */
-struct bpf_program *gen_bpf_generate(const struct db_filter *db)
+struct bpf_program *gen_bpf_generate(const struct db_filter_col *col)
 {
        int rc;
+       struct db_filter *db;
        struct bpf_state state;
 
+       /* NOTE: temporary until we fully support filter collections */
+       if (col->filter_cnt != 1 || col->filters[0]->arch != &arch_def_native)
+               return NULL;
+       db = col->filters[0];
+
        memset(&state, 0, sizeof(state));
        state.arch = db->arch;
-       state.attr = &db->attr;
+       state.attr = &col->attr;
 
        state.bpf = malloc(sizeof(*(state.bpf)));
        if (state.bpf == NULL)
diff --git a/src/gen_bpf.h b/src/gen_bpf.h
index 92828ee..43f337e 100644
--- a/src/gen_bpf.h
+++ b/src/gen_bpf.h
@@ -35,7 +35,7 @@ struct bpf_program {
 #define BPF_PGM_SIZE(x) \
        ((x)->blk_cnt * sizeof(*((x)->blks)))
 
-struct bpf_program *gen_bpf_generate(const struct db_filter *db);
+struct bpf_program *gen_bpf_generate(const struct db_filter_col *col);
 void gen_bpf_release(struct bpf_program *program);
 
 #endif
diff --git a/src/gen_pfc.c b/src/gen_pfc.c
index 4334c14..3f36f11 100644
--- a/src/gen_pfc.c
+++ b/src/gen_pfc.c
@@ -198,22 +198,28 @@ static void _gen_pfc_syscall(const struct arch_def *arch,
 
 /**
  * Generate a pseudo filter code string representation
- * @param db the seccomp filter DB
+ * @param col the seccomp filter collection
  * @param fd the fd to send the output
  *
  * This function generates a pseudo filter code representation of the given
- * filter DB and writes it to the given fd.  Returns zero on success, negative
- * values on failure.
+ * filter collection and writes it to the given fd.  Returns zero on success,
+ * negative values on failure.
  *
  */
-int gen_pfc_generate(const struct db_filter *db, int fd)
+int gen_pfc_generate(const struct db_filter_col *col, int fd)
 {
        int rc = 0;
        int newfd;
        FILE *fds;
+       struct db_filter *db;
        struct db_sys_list *s_iter;
        struct pfc_sys_list *p_iter = NULL, *p_new, *p_head = NULL, *p_prev;
 
+       /* NOTE: temporary until we fully support filter collections */
+       if (col->filter_cnt != 1 || col->filters[0]->arch != &arch_def_native)
+               return -EFAULT;
+       db = col->filters[0];
+
        newfd = dup(fd);
        if (newfd < 0)
                return errno;
@@ -263,7 +269,7 @@ int gen_pfc_generate(const struct db_filter *db, int fd)
                p_iter = p_iter->next;
        }
        fprintf(fds, "# default action\n");
-       _pfc_action(fds, db->attr.act_default);
+       _pfc_action(fds, col->attr.act_default);
        fprintf(fds, "#\n");
        fprintf(fds, "# pseudo filter code end\n");
        fprintf(fds, "#\n");
diff --git a/src/gen_pfc.h b/src/gen_pfc.h
index b0b2195..80f680f 100644
--- a/src/gen_pfc.h
+++ b/src/gen_pfc.h
@@ -24,6 +24,6 @@
 
 #include "db.h"
 
-int gen_pfc_generate(const struct db_filter *db, int fd);
+int gen_pfc_generate(const struct db_filter_col *col, int fd);
 
 #endif


------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
libseccomp-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss

Reply via email to