Now that we are allowing users to specify a filter DB via the public API we should so some simple checking to ensure the passed DB is valid.
Signed-off-by: Paul Moore <[email protected]> --- src/api.c | 31 ++++++++++++++++++++++--------- src/db.c | 27 +++++++++++++++++++++++++++ src/db.h | 5 +++++ 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/api.c b/src/api.c index 6d6cd02..64ee4c6 100644 --- a/src/api.c +++ b/src/api.c @@ -36,6 +36,19 @@ #include "gen_bpf.h" #include "system.h" +/** + * Validate a filter context + * @param ctx the filter context + * + * Attempt to validate the provided filter context. Returns zero if the + * context is valid, negative values on failure. + * + */ +static int _ctx_valid(const scmp_filter_ctx *ctx) +{ + return db_valid((struct db_filter *)ctx); +} + /* NOTE - function header comment in include/seccomp.h */ scmp_filter_ctx seccomp_init(uint32_t def_action) { @@ -48,7 +61,7 @@ scmp_filter_ctx seccomp_init(uint32_t def_action) /* NOTE - function header comment in include/seccomp.h */ int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action) { - if (ctx == NULL || db_action_valid(def_action) < 0) + if (_ctx_valid(ctx) || db_action_valid(def_action) < 0) return -EINVAL; db_reset((struct db_filter *)ctx, def_action); @@ -58,7 +71,7 @@ int seccomp_reset(scmp_filter_ctx ctx, uint32_t def_action) /* NOTE - function header comment in include/seccomp.h */ void seccomp_release(scmp_filter_ctx ctx) { - if (ctx == NULL) + if (_ctx_valid(ctx)) return; db_release((struct db_filter *)ctx); @@ -71,7 +84,7 @@ int seccomp_load(const scmp_filter_ctx ctx) struct db_filter *filter; struct bpf_program *program; - if (ctx == NULL) + if (_ctx_valid(ctx)) return -EINVAL; filter = (struct db_filter *)ctx; @@ -97,7 +110,7 @@ int seccomp_load(const scmp_filter_ctx ctx) int seccomp_attr_get(const scmp_filter_ctx ctx, enum scmp_filter_attr attr, uint32_t *value) { - if (ctx == NULL) + if (_ctx_valid(ctx)) return -EINVAL; return db_attr_get((const struct db_filter *)ctx, attr, value); @@ -107,7 +120,7 @@ int seccomp_attr_get(const scmp_filter_ctx ctx, int seccomp_attr_set(scmp_filter_ctx ctx, enum scmp_filter_attr attr, uint32_t value) { - if (ctx == NULL) + if (_ctx_valid(ctx)) return -EINVAL; return db_attr_set((struct db_filter *)ctx, attr, value); @@ -119,7 +132,7 @@ int seccomp_syscall_priority(scmp_filter_ctx ctx, int syscall, uint8_t priority) int rc; struct db_filter *filter; - if (ctx == NULL) + if (_ctx_valid(ctx)) return -EINVAL; filter = (struct db_filter *)ctx; @@ -163,7 +176,7 @@ static int _seccomp_rule_add(struct db_filter *filter, struct db_api_arg *chain = NULL; struct scmp_arg_cmp arg_data; - if (filter == NULL) + if (db_valid(filter)) return -EINVAL; rc = db_action_valid(action); @@ -261,7 +274,7 @@ int seccomp_rule_add_exact(scmp_filter_ctx ctx, uint32_t action, /* NOTE - function header comment in include/seccomp.h */ int seccomp_export_pfc(const scmp_filter_ctx ctx, int fd) { - if (ctx == NULL) + if (_ctx_valid(ctx)) return -EINVAL; return gen_pfc_generate((struct db_filter *)ctx, fd); @@ -273,7 +286,7 @@ int seccomp_export_bpf(const scmp_filter_ctx ctx, int fd) int rc; struct bpf_program *program; - if (ctx == NULL) + if (_ctx_valid(ctx)) return -EINVAL; program = gen_bpf_generate((struct db_filter *)ctx); diff --git a/src/db.c b/src/db.c index a1ae3ed..b8686ac 100644 --- a/src/db.c +++ b/src/db.c @@ -31,6 +31,10 @@ #include "arch.h" #include "db.h" +/* state values */ +#define _DB_STA_VALID 0xA1B2C3D4 +#define _DB_STA_FREED 0x1A2B3C4D + /* the priority field is fairly simple - without any user hints, or in the case * of a hint "tie", we give higher priority to syscalls with less chain nodes * (filter is easier to evaluate) */ @@ -338,6 +342,9 @@ void db_reset(struct db_filter *db, uint32_t def_action) db->attr.act_default = def_action; db->attr.act_badarch = SCMP_ACT_KILL; db->attr.nnp_enable = 1; + + /* set the state */ + db->state = _DB_STA_VALID; } /** @@ -356,6 +363,8 @@ struct db_filter *db_init(const struct arch_def *arch, uint32_t def_action) 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; @@ -378,12 +387,30 @@ void db_release(struct db_filter *db) if (db == NULL) return; + /* set the state, just in case */ + db->state = _DB_STA_FREED; + /* free and reset the DB */ db_reset(db, 0); free(db); } /** + * Validate a filter DB + * @param db the seccomp filter DB + * + * This function validates a seccomp filter DB. Returns zero if the DB is + * valid, negative values on failure. + * + */ +int db_valid(struct db_filter *db) +{ + if (db != NULL && db->state == _DB_STA_VALID) + return 0; + return -EINVAL; +} + +/** * Get a filter attribute * @param db the seccomp filter DB * @param attr the filter attribute diff --git a/src/db.h b/src/db.h index 34734c4..b60470d 100644 --- a/src/db.h +++ b/src/db.h @@ -131,6 +131,9 @@ struct db_filter_attr { }; struct db_filter { + /* verification / state */ + int state; + /* target architecture */ const struct arch_def *arch; /* attributes */ @@ -158,6 +161,8 @@ 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); +int db_valid(struct db_filter *db); + 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, ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ libseccomp-discuss mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libseccomp-discuss
