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]>
---
 src/api.c     |  154 ++++++++++++++++++++++++++++-------------
 src/arch.h    |    3 +
 src/db.c      |  216 +++++++++++++++++++++++++++++++++++++++++----------------
 src/db.h      |   37 +++++++---
 src/gen_bpf.c |   14 +++-
 src/gen_bpf.h |    2 -
 src/gen_pfc.c |   16 +++-
 src/gen_pfc.h |    2 -
 8 files changed, 312 insertions(+), 132 deletions(-)

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


------------------------------------------------------------------------------
Got visibility?
Most devs has no idea what their production app looks like.
Find out how fast your code is with AppDynamics Lite.
http://ad.doubleclick.net/clk;262219671;13503038;y?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
libseccomp-discuss mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss

Reply via email to