From f41f8bfd30738eb398780e1e1a87830699f856a7 Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Fri, 15 Nov 2019 07:38:28 -0700 Subject: [PATCH 1/5] bpf: Refactor duplicate sorting code In _gen_bpf_arch(), there was an identical block of code to sort the primary database syscalls and the secondary database syscalls. This commit refactors those duplicated, inline loops into a single function. Signed-off-by: Tom Hromatka --- src/gen_bpf.c | 113 +++++++++++++++++++++----------------------------- 1 file changed, 48 insertions(+), 65 deletions(-) diff --git a/src/gen_bpf.c b/src/gen_bpf.c index 1b559b0f..10855c5f 100644 --- a/src/gen_bpf.c +++ b/src/gen_bpf.c @@ -1143,6 +1143,50 @@ static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state, return NULL; } +/** + * Sort the syscalls by priority + * @param syscalls the linked list of syscalls to be sorted + * @param s_head the head of the linked list to be returned to the caller + * @param s_tail the tail of the linked list to be returned to the caller + */ +static void _sys_priority_sort(struct db_sys_list *syscalls, + struct db_sys_list **s_head, + struct db_sys_list **s_tail) +{ + struct db_sys_list *s_iter, *s_iter_b; + + db_list_foreach(s_iter, syscalls) { + if (*s_head != NULL) { + s_iter_b = *s_head; + while ((s_iter_b->pri_nxt != NULL) && + (s_iter->priority <= s_iter_b->priority)) + s_iter_b = s_iter_b->pri_nxt; + + if (s_iter->priority > s_iter_b->priority) { + s_iter->pri_prv = s_iter_b->pri_prv; + s_iter->pri_nxt = s_iter_b; + if (s_iter_b == *s_head) { + (*s_head)->pri_prv = s_iter; + *s_head = s_iter; + } else { + s_iter->pri_prv->pri_nxt = s_iter; + s_iter->pri_nxt->pri_prv = s_iter; + } + } else { + s_iter->pri_prv = *s_tail; + s_iter->pri_nxt = NULL; + s_iter->pri_prv->pri_nxt = s_iter; + *s_tail = s_iter; + } + } else { + *s_head = s_iter; + *s_tail = s_iter; + (*s_head)->pri_prv = NULL; + (*s_head)->pri_nxt = NULL; + } + } +} + /** * Generate the BPF instruction blocks for a given syscall * @param state the BPF state @@ -1241,76 +1285,15 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, unsigned int blk_cnt = 0; bool acc_reset; struct bpf_instr instr; - struct db_sys_list *s_head = NULL, *s_tail = NULL, *s_iter, *s_iter_b; + struct db_sys_list *s_head = NULL, *s_tail = NULL, *s_iter; struct bpf_blk *b_head = NULL, *b_tail = NULL, *b_iter, *b_new; state->arch = db->arch; /* sort the syscall list */ - db_list_foreach(s_iter, db->syscalls) { - if (s_head != NULL) { - s_iter_b = s_head; - while ((s_iter_b->pri_nxt != NULL) && - (s_iter->priority <= s_iter_b->priority)) - s_iter_b = s_iter_b->pri_nxt; - - if (s_iter->priority > s_iter_b->priority) { - s_iter->pri_prv = s_iter_b->pri_prv; - s_iter->pri_nxt = s_iter_b; - if (s_iter_b == s_head) { - s_head->pri_prv = s_iter; - s_head = s_iter; - } else { - s_iter->pri_prv->pri_nxt = s_iter; - s_iter->pri_nxt->pri_prv = s_iter; - } - } else { - s_iter->pri_prv = s_tail; - s_iter->pri_nxt = NULL; - s_iter->pri_prv->pri_nxt = s_iter; - s_tail = s_iter; - } - } else { - s_head = s_iter; - s_tail = s_iter; - s_head->pri_prv = NULL; - s_head->pri_nxt = NULL; - } - } - if (db_secondary != NULL) { - db_list_foreach(s_iter, db_secondary->syscalls) { - if (s_head != NULL) { - s_iter_b = s_head; - while ((s_iter_b->pri_nxt != NULL) && - (s_iter->priority <= s_iter_b->priority)) - s_iter_b = s_iter_b->pri_nxt; - - if (s_iter->priority > s_iter_b->priority) { - s_iter->pri_prv = s_iter_b->pri_prv; - s_iter->pri_nxt = s_iter_b; - if (s_iter_b == s_head) { - s_head->pri_prv = s_iter; - s_head = s_iter; - } else { - s_iter->pri_prv->pri_nxt = - s_iter; - s_iter->pri_nxt->pri_prv = - s_iter; - } - } else { - s_iter->pri_prv = s_tail; - s_iter->pri_nxt = NULL; - s_iter->pri_prv->pri_nxt = s_iter; - s_tail = s_iter; - } - } else { - s_head = s_iter; - s_tail = s_iter; - s_head->pri_prv = NULL; - s_head->pri_nxt = NULL; - } - } - } + _sys_priority_sort(db->syscalls, &s_head, &s_tail); + if (db_secondary != NULL) + _sys_priority_sort(db_secondary->syscalls, &s_head, &s_tail); if ((state->arch->token == SCMP_ARCH_X86_64 || state->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) From 963868d77f4c086a382eb5f513023afe7debc164 Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Fri, 15 Nov 2019 07:56:23 -0700 Subject: [PATCH 2/5] bpf: Refactor syscall loop in _gen_bpf_arch() This commit splits out some init code and a lengthy for-loop in _gen_bpf_arch() into its own function - _gen_bpf_syscalls(). Signed-off-by: Tom Hromatka --- src/gen_bpf.c | 162 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 64 deletions(-) diff --git a/src/gen_bpf.c b/src/gen_bpf.c index 10855c5f..40fe2758 100644 --- a/src/gen_bpf.c +++ b/src/gen_bpf.c @@ -159,11 +159,14 @@ struct bpf_state { /* default action */ uint64_t def_hsh; - /* target arch - NOTE: be careful, temporary use only! */ - const struct arch_def *arch; - /* bpf program */ struct bpf_program *bpf; + + /* WARNING - the following variables are temporary use only */ + const struct arch_def *arch; + struct bpf_blk *b_head; + struct bpf_blk *b_tail; + struct bpf_blk *b_new; }; /** @@ -1266,29 +1269,27 @@ static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state, } /** - * Generate the BPF instruction blocks for a given filter/architecture + * Loop through the syscalls in the db_filter and generate their bpf * @param state the BPF state * @param db the filter DB * @param db_secondary the secondary DB - * - * Generate the BPF instruction block for the given filter DB(s)/architecture(s) - * and return a pointer to the block on succes, NULL on failure. The resulting - * block assumes that the architecture token has already been loaded into the - * BPF accumulator. - * + * @param Number of blocks added by this function */ -static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, - const struct db_filter *db, - const struct db_filter *db_secondary) +static int _gen_bpf_syscalls(struct bpf_state *state, + const struct db_filter *db, + const struct db_filter *db_secondary, + unsigned int *blks_added) { - int rc; - unsigned int blk_cnt = 0; - bool acc_reset; - struct bpf_instr instr; struct db_sys_list *s_head = NULL, *s_tail = NULL, *s_iter; - struct bpf_blk *b_head = NULL, *b_tail = NULL, *b_iter, *b_new; + bool acc_reset; + int rc = 0; state->arch = db->arch; + state->b_head = NULL; + state->b_tail = NULL; + state->b_new = NULL; + + *blks_added = 0; /* sort the syscall list */ _sys_priority_sort(db->syscalls, &s_head, &s_tail); @@ -1307,39 +1308,72 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, continue; /* build the syscall filter */ - b_new = _gen_bpf_syscall(state, s_iter, - (b_head == NULL ? - state->def_hsh : b_head->hash), + state->b_new = _gen_bpf_syscall(state, s_iter, + (state->b_head == NULL ? + state->def_hsh : state->b_head->hash), (s_iter == s_head ? acc_reset : false)); - if (b_new == NULL) - goto arch_failure; + if (state->b_new == NULL) + goto out; /* add the filter to the list head */ - b_new->prev = NULL; - b_new->next = b_head; - if (b_tail != NULL) { - b_head->prev = b_new; - b_head = b_new; + state->b_new->prev = NULL; + state->b_new->next = state->b_head; + if (state->b_tail != NULL) { + state->b_head->prev = state->b_new; + state->b_head = state->b_new; } else { - b_head = b_new; - b_tail = b_head; + state->b_head = state->b_new; + state->b_tail = state->b_head; } - if (b_tail->next != NULL) - b_tail = b_tail->next; - blk_cnt++; + if (state->b_tail->next != NULL) + state->b_tail = state->b_tail->next; + (*blks_added)++; } +out: + return rc; +} + +/** + * Generate the BPF instruction blocks for a given filter/architecture + * @param state the BPF state + * @param db the filter DB + * @param db_secondary the secondary DB + * + * Generate the BPF instruction block for the given filter DB(s)/architecture(s) + * and return a pointer to the block on succes, NULL on failure. The resulting + * block assumes that the architecture token has already been loaded into the + * BPF accumulator. + * + */ +static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, + const struct db_filter *db, + const struct db_filter *db_secondary) +{ + int rc; + unsigned int blk_cnt = 0, blks_added = 0; + struct bpf_instr instr; + struct bpf_blk *b_iter; + + state->arch = db->arch; + + /* create the syscall filters and add them to block list group */ + rc = _gen_bpf_syscalls(state, db, db_secondary, &blks_added); + if (rc < 0) + goto arch_failure; + blk_cnt += blks_added; + /* additional ABI filtering */ if ((state->arch->token == SCMP_ARCH_X86_64 || state->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) { _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), _BPF_JMP_NO, _BPF_JMP_NO, _BPF_SYSCALL(state->arch)); - b_new = _blk_append(state, NULL, &instr); - if (b_new == NULL) + state->b_new = _blk_append(state, NULL, &instr); + if (state->b_new == NULL) goto arch_failure; - b_new->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + state->b_new->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); if (state->arch->token == SCMP_ARCH_X86_64) { /* filter out x32 */ _BPF_INSTR(instr, @@ -1347,12 +1381,12 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, _BPF_JMP_NO, _BPF_JMP_NO, _BPF_K(state->arch, X32_SYSCALL_BIT)); - if (b_head != NULL) - instr.jf = _BPF_JMP_HSH(b_head->hash); + if (state->b_head != NULL) + instr.jf = _BPF_JMP_HSH(state->b_head->hash); else instr.jf = _BPF_JMP_HSH(state->def_hsh); - b_new = _blk_append(state, b_new, &instr); - if (b_new == NULL) + state->b_new = _blk_append(state, state->b_new, &instr); + if (state->b_new == NULL) goto arch_failure; /* NOTE: starting with Linux v4.8 the seccomp filters * are processed both when the syscall is @@ -1366,8 +1400,8 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, _BPF_JMP_NO, _BPF_JMP_HSH(state->bad_arch_hsh), _BPF_K(state->arch, -1)); - if (b_head != NULL) - instr.jt = _BPF_JMP_HSH(b_head->hash); + if (state->b_head != NULL) + instr.jt = _BPF_JMP_HSH(state->b_head->hash); else instr.jt = _BPF_JMP_HSH(state->def_hsh); blk_cnt++; @@ -1378,22 +1412,22 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, _BPF_JMP_NO, _BPF_JMP_HSH(state->bad_arch_hsh), _BPF_K(state->arch, X32_SYSCALL_BIT)); - if (b_head != NULL) - instr.jt = _BPF_JMP_HSH(b_head->hash); + if (state->b_head != NULL) + instr.jt = _BPF_JMP_HSH(state->b_head->hash); else instr.jt = _BPF_JMP_HSH(state->def_hsh); blk_cnt++; } else /* we should never get here */ goto arch_failure; - b_new = _blk_append(state, b_new, &instr); - if (b_new == NULL) + state->b_new = _blk_append(state, state->b_new, &instr); + if (state->b_new == NULL) goto arch_failure; - b_new->next = b_head; - if (b_head != NULL) - b_head->prev = b_new; - b_head = b_new; - rc = _hsh_add(state, &b_head, 1); + state->b_new->next = state->b_head; + if (state->b_head != NULL) + state->b_head->prev = state->b_new; + state->b_head = state->b_new; + rc = _hsh_add(state, &state->b_head, 1); if (rc < 0) goto arch_failure; } @@ -1402,34 +1436,34 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_JMP + BPF_JEQ), _BPF_JMP_NO, _BPF_JMP_NXT(blk_cnt++), _BPF_K(state->arch, state->arch->token_bpf)); - if (b_head != NULL) - instr.jt = _BPF_JMP_HSH(b_head->hash); + if (state->b_head != NULL) + instr.jt = _BPF_JMP_HSH(state->b_head->hash); else instr.jt = _BPF_JMP_HSH(state->def_hsh); - b_new = _blk_append(state, NULL, &instr); - if (b_new == NULL) + state->b_new = _blk_append(state, NULL, &instr); + if (state->b_new == NULL) goto arch_failure; - b_new->next = b_head; - if (b_head != NULL) - b_head->prev = b_new; - b_head = b_new; - rc = _hsh_add(state, &b_head, 1); + state->b_new->next = state->b_head; + if (state->b_head != NULL) + state->b_head->prev = state->b_new; + state->b_head = state->b_new; + rc = _hsh_add(state, &state->b_head, 1); if (rc < 0) goto arch_failure; state->arch = NULL; - return b_head; + return state->b_head; arch_failure: /* NOTE: we do the cleanup here and not just return an error as all of * the instruction blocks may not be added to the hash table when we * hit an error */ state->arch = NULL; - b_iter = b_head; + b_iter = state->b_head; while (b_iter != NULL) { - b_new = b_iter->next; + state->b_new = b_iter->next; _blk_free(state, b_iter); - b_iter = b_new; + b_iter = state->b_new; } return NULL; } From fc8a69c0ea03d94262983442eb25afcf9753d1bc Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Fri, 15 Nov 2019 08:12:28 -0700 Subject: [PATCH 3/5] bpf: Refactor code that inserts instructions into BPF state This commit adds a function - _gen_bpf_insert() - that inserts an instruction block into the BPF state and creates the linked list connections for that newly-inserted block. Signed-off-by: Tom Hromatka --- src/gen_bpf.c | 52 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 16 deletions(-) diff --git a/src/gen_bpf.c b/src/gen_bpf.c index 40fe2758..db58e7bf 100644 --- a/src/gen_bpf.c +++ b/src/gen_bpf.c @@ -1190,6 +1190,36 @@ static void _sys_priority_sort(struct db_sys_list *syscalls, } } +/** + * Insert an instruction into the BPF state and connect the linked list + * @param state the BPF state + * @param instr the instruction to insert + * @param insert the BPF blk that represents the instruction + * @param next the next BPF instruction in the linked list + * @param existing_blk insert will be added to the end of this blk if non-NULL + * + * Insert a set of instructions into the BPF state and associate those + * instructions with the bpf_blk called insert. The "next" field in the + * newly inserted block will be linked with the "next" bpf_blk parameter. + */ +static int _gen_bpf_insert(struct bpf_state *state, struct bpf_instr *instr, + struct bpf_blk **insert, struct bpf_blk **next, + struct bpf_blk *existing_blk) +{ + int rc; + + *insert = _blk_append(state, existing_blk, instr); + if (*insert == NULL) + return -EINVAL; + (*insert)->next = (*next); + if (*next != NULL) + (*next)->prev = (*insert); + *next = *insert; + + rc = _hsh_add(state, insert, 1); + return rc; +} + /** * Generate the BPF instruction blocks for a given syscall * @param state the BPF state @@ -1420,14 +1450,9 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, } else /* we should never get here */ goto arch_failure; - state->b_new = _blk_append(state, state->b_new, &instr); - if (state->b_new == NULL) - goto arch_failure; - state->b_new->next = state->b_head; - if (state->b_head != NULL) - state->b_head->prev = state->b_new; - state->b_head = state->b_new; - rc = _hsh_add(state, &state->b_head, 1); + + rc = _gen_bpf_insert(state, &instr, &state->b_new, + &state->b_head, state->b_new); if (rc < 0) goto arch_failure; } @@ -1440,14 +1465,9 @@ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, instr.jt = _BPF_JMP_HSH(state->b_head->hash); else instr.jt = _BPF_JMP_HSH(state->def_hsh); - state->b_new = _blk_append(state, NULL, &instr); - if (state->b_new == NULL) - goto arch_failure; - state->b_new->next = state->b_head; - if (state->b_head != NULL) - state->b_head->prev = state->b_new; - state->b_head = state->b_new; - rc = _hsh_add(state, &state->b_head, 1); + + rc = _gen_bpf_insert(state, &instr, &state->b_new, &state->b_head, + NULL); if (rc < 0) goto arch_failure; From c9df08870b87bf81f037d1df30eab83050261ff6 Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Fri, 15 Nov 2019 12:28:47 -0700 Subject: [PATCH 4/5] bpf:pfc: Add optimization option to use a binary tree This patch adds a filter attribute, SCMP_FLTATR_CTL_OPTIMIZE, to specify the optimization level of the seccomp filter: 0 - currently unused 1 - rules weighted by priority and complexity (default) 2 - binary tree sorted by syscall number Several in-house customers have identified that their large seccomp filters are slowing down their applications. Their filters largely consist of simple allow/deny logic for many syscalls (306 in one case) and for the most part don't utilize argument filtering. I modified gen_bpf.c and gen_pfc.c to utilize a cBPF binary tree if the user has requested optimize level 2. I then timed calling getppid() in a loop using one of my customer's seccomp filters. I ran this loop one million times and recorded the min, max, and mean times (in TSC ticks) to call getppid(). (I didn't disable interrupts, so the max time was often large.) I chose to report the minimum time because I feel it best represents the actual time to traverse the syscall. Test Case minimum TSC ticks to make syscall ---------------------------------------------------------------- seccomp disabled 138 getppid() at the front of 306-syscall seccomp filter 256 getppid() in middle of 306-syscall seccomp filter 516 getppid() at the end of the 306-syscall filter 1942 getppid() in a binary tree 312 As shown in the table above, a binary tree can signficantly improve syscall performance in the average and worst case scenario for these customers. Signed-off-by: Tom Hromatka --- include/seccomp.h.in | 5 + src/db.c | 17 +++ src/db.h | 3 + src/gen_bpf.c | 286 ++++++++++++++++++++++++++++++++++++-- src/gen_pfc.c | 191 ++++++++++++++++++++----- src/python/libseccomp.pxd | 1 + src/python/seccomp.pyx | 1 + 7 files changed, 459 insertions(+), 45 deletions(-) diff --git a/include/seccomp.h.in b/include/seccomp.h.in index 208b3663..8115b500 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -69,6 +69,11 @@ enum scmp_filter_attr { SCMP_FLTATR_API_TSKIP = 5, /**< allow rules with a -1 syscall */ SCMP_FLTATR_CTL_LOG = 6, /**< log not-allowed actions */ SCMP_FLTATR_CTL_SSB = 7, /**< disable SSB mitigation */ + SCMP_FLTATR_CTL_OPTIMIZE = 8, /**< filter optimization level: (DEFAULT = 1) + * 0 - currently unused + * 1 - rules weighted by priority and complexity + * 2 - binary tree sorted by syscall number + */ _SCMP_FLTATR_MAX, }; diff --git a/src/db.c b/src/db.c index a40cb2b1..bd362a6f 100644 --- a/src/db.c +++ b/src/db.c @@ -841,6 +841,7 @@ static void _db_reset(struct db_filter *db) } db->syscalls = NULL; } + db->syscall_cnt = 0; /* free any rules */ if (db->rules != NULL) { @@ -1069,6 +1070,7 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action) col->attr.api_tskip = 0; col->attr.log_enable = 0; col->attr.spec_allow = 0; + col->attr.optimize = 1; /* set the state */ col->state = _DB_STA_VALID; @@ -1311,6 +1313,9 @@ int db_col_attr_get(const struct db_filter_col *col, case SCMP_FLTATR_CTL_SSB: *value = col->attr.spec_allow; break; + case SCMP_FLTATR_CTL_OPTIMIZE: + *value = col->attr.optimize; + break; default: rc = -EEXIST; break; @@ -1386,6 +1391,17 @@ int db_col_attr_set(struct db_filter_col *col, rc = -EOPNOTSUPP; } break; + case SCMP_FLTATR_CTL_OPTIMIZE: + switch (value) { + case 1: + case 2: + col->attr.optimize = value; + break; + default: + rc = -EOPNOTSUPP; + break; + } + break; default: rc = -EEXIST; break; @@ -2052,6 +2068,7 @@ int db_rule_add(struct db_filter *db, const struct db_api_rule_list *rule) s_new->next = db->syscalls; db->syscalls = s_new; } + db->syscall_cnt++; return 0; } else if (s_iter->chains == NULL) { if (rm_flag || !s_iter->valid) { diff --git a/src/db.h b/src/db.h index 9dce65a9..ae485eef 100644 --- a/src/db.h +++ b/src/db.h @@ -118,6 +118,8 @@ struct db_filter_attr { uint32_t log_enable; /* SPEC_ALLOW related attributes */ uint32_t spec_allow; + /* SCMP_FLTATR_CTL_OPTIMIZE related attributes */ + uint32_t optimize; }; struct db_filter { @@ -126,6 +128,7 @@ struct db_filter { /* syscall filters, kept as a sorted single-linked list */ struct db_sys_list *syscalls; + unsigned int syscall_cnt; /* list of rules used to build the filters, kept in order */ struct db_api_rule_list *rules; diff --git a/src/gen_bpf.c b/src/gen_bpf.c index db58e7bf..55a7958e 100644 --- a/src/gen_bpf.c +++ b/src/gen_bpf.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,11 @@ #define AINC_BLK 2 #define AINC_PROG 64 +/* binary tree definitions */ +#define SYSCALLS_PER_NODE (4) +#define BTREE_HSH_INVALID (UINT64_MAX) +#define BTREE_SYSCALL_INVALID (UINT_MAX) + struct acc_state { int32_t offset; uint32_t mask; @@ -1146,6 +1152,50 @@ static struct bpf_blk *_gen_bpf_chain(struct bpf_state *state, return NULL; } +/** + * Sort the syscalls by syscall number + * @param syscalls the linked list of syscalls to be sorted + * @param s_head the head of the linked list to be returned to the caller + * @param s_tail the tail of the linked list to be returned to the caller + */ +static void _sys_num_sort(struct db_sys_list *syscalls, + struct db_sys_list **s_head, + struct db_sys_list **s_tail) +{ + struct db_sys_list *s_iter, *s_iter_b; + + db_list_foreach(s_iter, syscalls) { + if (*s_head != NULL) { + s_iter_b = *s_head; + while ((s_iter_b->pri_nxt != NULL) && + (s_iter->num <= s_iter_b->num)) + s_iter_b = s_iter_b->pri_nxt; + + if (s_iter->num > s_iter_b->num) { + s_iter->pri_prv = s_iter_b->pri_prv; + s_iter->pri_nxt = s_iter_b; + if (s_iter_b == *s_head) { + (*s_head)->pri_prv = s_iter; + *s_head = s_iter; + } else { + s_iter->pri_prv->pri_nxt = s_iter; + s_iter->pri_nxt->pri_prv = s_iter; + } + } else { + s_iter->pri_prv = *s_tail; + s_iter->pri_nxt = NULL; + s_iter->pri_prv->pri_nxt = s_iter; + *s_tail = s_iter; + } + } else { + *s_head = s_iter; + *s_tail = s_iter; + (*s_head)->pri_prv = NULL; + (*s_head)->pri_nxt = NULL; + } + } +} + /** * Sort the syscalls by priority * @param syscalls the linked list of syscalls to be sorted @@ -1190,6 +1240,27 @@ static void _sys_priority_sort(struct db_sys_list *syscalls, } } +/** + * Sort the syscalls + * @param syscalls the linked list of syscalls to be sorted + * @param s_head the head of the linked list to be returned to the caller + * @param s_tail the tail of the linked list to be returned to the caller + * + * Wrapper function for sorting syscalls + * + */ +static void _sys_sort(struct db_sys_list *syscalls, + struct db_sys_list **s_head, + struct db_sys_list **s_tail, + uint32_t optimize) +{ + if (optimize != 2) + _sys_priority_sort(syscalls, s_head, s_tail); + else + /* sort by number for the binary tree */ + _sys_num_sort(syscalls, s_head, s_tail); +} + /** * Insert an instruction into the BPF state and connect the linked list * @param state the BPF state @@ -1220,6 +1291,136 @@ static int _gen_bpf_insert(struct bpf_state *state, struct bpf_instr *instr, return rc; } +/** + * Calculate the number of levels in the binary tree + * @param syscall_cnt the number of syscalls in this seccomp filter + */ +static int _get_bintree_levels(unsigned int syscall_cnt) +{ + unsigned int i = 2, max_level = SYSCALLS_PER_NODE * 2; + + while (max_level < syscall_cnt) { + max_level <<= 1; + i++; + } + + return i; +} + +/** + * Initialize the binary tree + * @param bintree_hashes Array of hashes that store binary tree jump dests + * @param bintree_syscalls Array of syscalls for the binary tree "if > " logic + * @param bintree_levels Number of levels in the binary tree + * @param syscall_cnt Number of syscalls in this filter + * @param empty_cnt Number of empty slots needed to balance the tree + * + */ +static int _gen_bpf_init_bintree(uint64_t **bintree_hashes, + unsigned int **bintree_syscalls, + unsigned int *bintree_levels, + unsigned int syscall_cnt, + unsigned int *empty_cnt) +{ + int i; + + *bintree_levels = _get_bintree_levels(syscall_cnt); + + if (*bintree_levels > 0) { + *empty_cnt = ((unsigned int)(SYSCALLS_PER_NODE * 2) << + ((*bintree_levels) - 1)) - syscall_cnt; + *bintree_hashes = zmalloc(sizeof(uint64_t) * + (*bintree_levels)); + if (bintree_hashes == NULL) + return -ENOMEM; + + *bintree_syscalls = zmalloc(sizeof(unsigned int) * + (*bintree_levels)); + if (bintree_syscalls == NULL) + return -ENOMEM; + + for (i = 0; i < *bintree_levels; i++) { + (*bintree_syscalls)[i] = BTREE_SYSCALL_INVALID; + (*bintree_hashes)[i] = BTREE_HSH_INVALID; + } + } + + return 0; +} + +/** + * Generate the binary tree + * @param state the BPF state + * @param bintree_hashes Array of hashes that store binary tree jump dests + * @param bintree_syscalls Array of syscalls for the binary tree "if > " logic + * @param bintree_levels Number of levels in the binary tree + * @param total_cnt Total number of syscalls and empty slots in the bintree + * @param cur_syscall Current syscall being processed + * @param blks_added Number of BPF blocks added by this function + * + * Generate the BPF instruction blocks for the binary tree for cur_syscall. + * If this syscall is at the end of the node, then this function will + * create the requisite ifs and elses for the tree. + */ +static int _gen_bpf_bintree(struct bpf_state *state, uint64_t *bintree_hashes, + unsigned int *bintree_syscalls, + unsigned int bintree_levels, + unsigned int total_cnt, unsigned int cur_syscall, + unsigned int *blks_added) +{ + struct bpf_blk *b_bintree = NULL; + struct bpf_instr instr; + unsigned int level; + int rc = 0, i, j; + + for (i = bintree_levels - 1; i >= 0; i--) { + level = SYSCALLS_PER_NODE << i; + + if ((total_cnt % level) == 0) { + /* save the "if greater than" syscall num */ + bintree_syscalls[i] = cur_syscall; + /* save the hash for the jf case */ + bintree_hashes[i] = state->b_new->hash; + + for (j = 0; j < i; j++) { + if (bintree_syscalls[j] == BTREE_SYSCALL_INVALID || + bintree_hashes[j] == BTREE_HSH_INVALID) + /* we are near the end of the binary + * tree and the jump-to location is + * not valid. skip this if-else + */ + continue; + + _BPF_INSTR(instr, + _BPF_OP(state->arch, BPF_JMP + BPF_JGT), + _BPF_JMP_NO, + _BPF_JMP_NO, + _BPF_K(state->arch, bintree_syscalls[j])); + instr.jt = _BPF_JMP_HSH(b_bintree == NULL ? + state->b_new->hash : b_bintree->hash); + instr.jf = _BPF_JMP_HSH(bintree_hashes[j]); + (*blks_added)++; + + rc = _gen_bpf_insert(state, &instr, + &b_bintree, &state->b_head, NULL); + if (rc < 0) + goto out; + } + + if (b_bintree != NULL) + /* this is the last if in this "block". + * save it off so the next binary tree + * if can "else" to it. + */ + bintree_hashes[j] = b_bintree->hash; + break; + } + } + +out: + return rc; +} + /** * Generate the BPF instruction blocks for a given syscall * @param state the BPF state @@ -1308,9 +1509,13 @@ static struct bpf_blk *_gen_bpf_syscall(struct bpf_state *state, static int _gen_bpf_syscalls(struct bpf_state *state, const struct db_filter *db, const struct db_filter *db_secondary, - unsigned int *blks_added) + unsigned int *blks_added, uint32_t optimize, + unsigned int *bintree_levels) { struct db_sys_list *s_head = NULL, *s_tail = NULL, *s_iter; + unsigned int syscall_cnt = 0, empty_cnt = 0; + uint64_t *bintree_hashes = NULL, nxt_hsh; + unsigned int *bintree_syscalls = NULL; bool acc_reset; int rc = 0; @@ -1322,9 +1527,17 @@ static int _gen_bpf_syscalls(struct bpf_state *state, *blks_added = 0; /* sort the syscall list */ - _sys_priority_sort(db->syscalls, &s_head, &s_tail); + _sys_sort(db->syscalls, &s_head, &s_tail, optimize); if (db_secondary != NULL) - _sys_priority_sort(db_secondary->syscalls, &s_head, &s_tail); + _sys_sort(db_secondary->syscalls, &s_head, &s_tail, optimize); + + if (optimize == 2) { + rc = _gen_bpf_init_bintree(&bintree_hashes, &bintree_syscalls, + bintree_levels, db->syscall_cnt, + &empty_cnt); + if (rc < 0) + goto out; + } if ((state->arch->token == SCMP_ARCH_X86_64 || state->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) @@ -1332,17 +1545,30 @@ static int _gen_bpf_syscalls(struct bpf_state *state, else acc_reset = true; + if (*bintree_levels > 0) + /* The accumulator is reset when the first bintree "if" is + * generated. + */ + acc_reset = false; + /* create the syscall filters and add them to block list group */ for (s_iter = s_tail; s_iter != NULL; s_iter = s_iter->pri_prv) { if (!s_iter->valid) continue; + if (*bintree_levels > 0 && + ((syscall_cnt + empty_cnt) % SYSCALLS_PER_NODE) == 0) + /* This is the last syscall in the node. go to the + * default hash */ + nxt_hsh = state->def_hsh; + else + nxt_hsh = state->b_head == NULL ? + state->def_hsh : state->b_head->hash; + /* build the syscall filter */ - state->b_new = _gen_bpf_syscall(state, s_iter, - (state->b_head == NULL ? - state->def_hsh : state->b_head->hash), - (s_iter == s_head ? - acc_reset : false)); + state->b_new = _gen_bpf_syscall(state, s_iter, nxt_hsh, + (s_iter == s_head ? + acc_reset : false)); if (state->b_new == NULL) goto out; @@ -1360,9 +1586,26 @@ static int _gen_bpf_syscalls(struct bpf_state *state, if (state->b_tail->next != NULL) state->b_tail = state->b_tail->next; (*blks_added)++; + syscall_cnt++; + + /* build the binary tree if and else logic */ + if (*bintree_levels > 0) { + rc = _gen_bpf_bintree(state, bintree_hashes, + bintree_syscalls, + *bintree_levels, + syscall_cnt + empty_cnt, + s_iter->num, blks_added); + if (rc < 0) + goto out; + } } out: + if (bintree_hashes != NULL) + free(bintree_hashes); + if (bintree_syscalls != NULL) + free(bintree_syscalls); + return rc; } @@ -1380,21 +1623,37 @@ static int _gen_bpf_syscalls(struct bpf_state *state, */ static struct bpf_blk *_gen_bpf_arch(struct bpf_state *state, const struct db_filter *db, - const struct db_filter *db_secondary) + const struct db_filter *db_secondary, + uint32_t optimize) { int rc; - unsigned int blk_cnt = 0, blks_added = 0; + unsigned int blk_cnt = 0, blks_added = 0, bintree_levels = 0; struct bpf_instr instr; - struct bpf_blk *b_iter; + struct bpf_blk *b_iter, *b_bintree; state->arch = db->arch; /* create the syscall filters and add them to block list group */ - rc = _gen_bpf_syscalls(state, db, db_secondary, &blks_added); + rc = _gen_bpf_syscalls(state, db, db_secondary, &blks_added, optimize, + &bintree_levels); if (rc < 0) goto arch_failure; blk_cnt += blks_added; + if (bintree_levels > 0) { + _BPF_INSTR(instr, _BPF_OP(state->arch, BPF_LD + BPF_ABS), + _BPF_JMP_NO, _BPF_JMP_NO, + _BPF_SYSCALL(state->arch)); + blk_cnt++; + + rc = _gen_bpf_insert(state, &instr, &b_bintree, + &state->b_head, NULL); + if (rc < 0) + goto arch_failure; + b_bintree->acc_start = _ACC_STATE_UNDEF; + b_bintree->acc_end = _ACC_STATE_OFFSET(_BPF_OFFSET_SYSCALL); + } + /* additional ABI filtering */ if ((state->arch->token == SCMP_ARCH_X86_64 || state->arch->token == SCMP_ARCH_X32) && (db_secondary == NULL)) { @@ -1751,7 +2010,8 @@ static int _gen_bpf_build_bpf(struct bpf_state *state, db_secondary = NULL; /* create the filter for the architecture(s) */ - b_new = _gen_bpf_arch(state, col->filters[iter], db_secondary); + b_new = _gen_bpf_arch(state, col->filters[iter], db_secondary, + col->attr.optimize); if (b_new == NULL) return -ENOMEM; b_new->prev = b_tail; diff --git a/src/gen_pfc.c b/src/gen_pfc.c index 8186f0d0..767845f4 100644 --- a/src/gen_pfc.c +++ b/src/gen_pfc.c @@ -243,68 +243,163 @@ static void _gen_pfc_chain(const struct arch_def *arch, * */ static void _gen_pfc_syscall(const struct arch_def *arch, - const struct db_sys_list *sys, FILE *fds) + const struct db_sys_list *sys, FILE *fds, + int lvl) { unsigned int sys_num = sys->num; const char *sys_name = arch_syscall_resolve_num(arch, sys_num); - _indent(fds, 1); + _indent(fds, lvl); fprintf(fds, "# filter for syscall \"%s\" (%u) [priority: %d]\n", (sys_name ? sys_name : "UNKNOWN"), sys_num, sys->priority); - _indent(fds, 1); + _indent(fds, lvl); fprintf(fds, "if ($syscall == %u)\n", sys_num); if (sys->chains == NULL) { - _indent(fds, 2); + _indent(fds, lvl + 1); _pfc_action(fds, sys->action); } else - _gen_pfc_chain(arch, sys->chains, 2, fds); + _gen_pfc_chain(arch, sys->chains, lvl + 1, fds); } -/** - * Generate pseudo filter code for an architecture - * @param col the seccomp filter collection - * @param db the single seccomp filter - * @param fds the file stream to send the output - * - * This function generates a pseudo filter code representation of the given - * filter DB and writes it to the given output stream. Returns zero on - * success, negative values on failure. - * - */ -static int _gen_pfc_arch(const struct db_filter_col *col, - const struct db_filter *db, FILE *fds) +#define SYSCALLS_PER_NODE (4) +static int _get_bintree_levels(unsigned int syscall_cnt, + uint32_t optimize) { - int rc = 0; + unsigned int i = 0, max_level; + + if (optimize != 2) + /* Only use a binary tree if requested */ + return 0; + + do { + max_level = SYSCALLS_PER_NODE << i; + i++; + } while(max_level < syscall_cnt); + + return i; +} + +static int _get_bintree_syscall_num(const struct pfc_sys_list *cur, + int lookahead_cnt, + int *const num) +{ + while (lookahead_cnt > 0 && cur != NULL) { + cur = cur->next; + lookahead_cnt--; + } + + if (cur == NULL) + return -EINVAL; + + *num = cur->sys->num; + return 0; +} + +static int _sys_num_sort(struct db_sys_list *syscalls, + struct pfc_sys_list **p_head) +{ + struct pfc_sys_list *p_iter = NULL, *p_new, *p_prev; struct db_sys_list *s_iter; - struct pfc_sys_list *p_iter = NULL, *p_new, *p_head = NULL, *p_prev; - /* sort the syscall list */ - db_list_foreach(s_iter, db->syscalls) { + db_list_foreach(s_iter, syscalls) { p_new = zmalloc(sizeof(*p_new)); if (p_new == NULL) { - rc = -ENOMEM; - goto arch_return; + return -ENOMEM; } p_new->sys = s_iter; p_prev = NULL; - p_iter = p_head; + p_iter = *p_head; + while (p_iter != NULL && + s_iter->num < p_iter->sys->num) { + p_prev = p_iter; + p_iter = p_iter->next; + } + if (*p_head == NULL) + *p_head = p_new; + else if (p_prev == NULL) { + p_new->next = *p_head; + *p_head = p_new; + } else { + p_new->next = p_iter; + p_prev->next = p_new; + } + } + + return 0; +} + +static int _sys_priority_sort(struct db_sys_list *syscalls, + struct pfc_sys_list **p_head) +{ + struct pfc_sys_list *p_iter = NULL, *p_new, *p_prev; + struct db_sys_list *s_iter; + + db_list_foreach(s_iter, syscalls) { + p_new = zmalloc(sizeof(*p_new)); + if (p_new == NULL) { + return -ENOMEM; + } + p_new->sys = s_iter; + + p_prev = NULL; + p_iter = *p_head; while (p_iter != NULL && s_iter->priority < p_iter->sys->priority) { p_prev = p_iter; p_iter = p_iter->next; } - if (p_head == NULL) - p_head = p_new; + if (*p_head == NULL) + *p_head = p_new; else if (p_prev == NULL) { - p_new->next = p_head; - p_head = p_new; + p_new->next = *p_head; + *p_head = p_new; } else { p_new->next = p_iter; p_prev->next = p_new; } } + return 0; +} + +static int _sys_sort(struct db_sys_list *syscalls, + struct pfc_sys_list **p_head, + uint32_t optimize) +{ + if (optimize != 2) + return _sys_priority_sort(syscalls, p_head); + else + /* sort by number for the binary tree */ + return _sys_num_sort(syscalls, p_head); +} + +/** + * Generate pseudo filter code for an architecture + * @param col the seccomp filter collection + * @param db the single seccomp filter + * @param fds the file stream to send the output + * + * This function generates a pseudo filter code representation of the given + * filter DB and writes it to the given output stream. Returns zero on + * success, negative values on failure. + * + */ +static int _gen_pfc_arch(const struct db_filter_col *col, + const struct db_filter *db, FILE *fds, + uint32_t optimize) +{ + int rc = 0, i = 0, lookahead_num; + unsigned int syscall_cnt = 0, bintree_levels, level, indent = 1; + struct pfc_sys_list *p_iter = NULL, *p_head = NULL; + + /* sort the syscall list */ + rc = _sys_sort(db->syscalls, &p_head, optimize); + if (rc < 0) + goto arch_return; + + bintree_levels = _get_bintree_levels(db->syscall_cnt, optimize); + fprintf(fds, "# filter for arch %s (%u)\n", _pfc_arch(db->arch), db->arch->token_bpf); fprintf(fds, "if ($arch == %u)\n", db->arch->token_bpf); @@ -314,8 +409,40 @@ static int _gen_pfc_arch(const struct db_filter_col *col, p_iter = p_iter->next; continue; } - _gen_pfc_syscall(db->arch, p_iter->sys, fds); + + for (i = bintree_levels - 1; i > 0; i--) { + level = SYSCALLS_PER_NODE << i; + + if (syscall_cnt == 0 || (syscall_cnt % level) == 0) { + rc = _get_bintree_syscall_num(p_iter, level / 2, + &lookahead_num); + if (rc < 0) + /* We have reached the end of the bintree. + * There aren't enough syscalls to construct + * any more if-elses. + */ + continue; + _indent(fds, indent); + fprintf(fds, "if ($syscall > %u)\n", lookahead_num); + indent++; + } else if ((syscall_cnt % (level / 2)) == 0) { + lookahead_num = p_iter->sys->num; + _indent(fds, indent - 1); + fprintf(fds, "else # ($syscall <= %u)\n", + p_iter->sys->num); + } + + } + + _gen_pfc_syscall(db->arch, p_iter->sys, fds, indent); + syscall_cnt++; p_iter = p_iter->next; + + /* undo the indentations as the else statements complete */ + for (i = 0; i < bintree_levels; i++) { + if (syscall_cnt % ((SYSCALLS_PER_NODE * 2) << i) == 0) + indent--; + } } _indent(fds, 1); fprintf(fds, "# default action\n"); @@ -330,7 +457,6 @@ static int _gen_pfc_arch(const struct db_filter_col *col, } return rc; } - /** * Generate a pseudo filter code string representation * @param col the seccomp filter collection @@ -363,7 +489,8 @@ int gen_pfc_generate(const struct db_filter_col *col, int fd) fprintf(fds, "#\n"); for (iter = 0; iter < col->filter_cnt; iter++) - _gen_pfc_arch(col, col->filters[iter], fds); + _gen_pfc_arch(col, col->filters[iter], fds, + col->attr.optimize); fprintf(fds, "# invalid architecture action\n"); _pfc_action(fds, col->attr.act_badarch); diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd index f1194b67..b9703180 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -61,6 +61,7 @@ cdef extern from "seccomp.h": SCMP_FLTATR_API_TSKIP SCMP_FLTATR_CTL_LOG SCMP_FLTATR_CTL_SSB + SCMP_FLTATR_CTL_OPTIMIZE cdef enum scmp_compare: SCMP_CMP_NE diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx index 113fbf4e..d7c1bb12 100644 --- a/src/python/seccomp.pyx +++ b/src/python/seccomp.pyx @@ -326,6 +326,7 @@ cdef class Attr: API_TSKIP = libseccomp.SCMP_FLTATR_API_TSKIP CTL_LOG = libseccomp.SCMP_FLTATR_CTL_LOG CTL_SSB = libseccomp.SCMP_FLTATR_CTL_SSB + CTL_OPTIMIZE = libseccomp.SCMP_FLTATR_CTL_OPTIMIZE cdef class Arg: """ Python object representing a SyscallFilter syscall argument. From b5d97f2b77899063e4c8f987dfe54785707ecba1 Mon Sep 17 00:00:00 2001 From: Tom Hromatka Date: Fri, 15 Nov 2019 12:55:33 -0700 Subject: [PATCH 5/5] tests: add tests for the binary tree This commit adds tests to ensure the validity of the binary tree and the resultant pfc and bpf output. Signed-off-by: Tom Hromatka --- tests/.gitignore | 3 + tests/13-basic-attrs.py | 3 + tests/53-sim-binary_tree.c | 95 +++ tests/53-sim-binary_tree.py | 52 ++ tests/53-sim-binary_tree.tests | 345 ++++++++ tests/54-live-binary_tree.c | 128 +++ tests/54-live-binary_tree.py | 95 +++ tests/54-live-binary_tree.tests | 11 + tests/55-basic-pfc_binary_tree.c | 91 ++ tests/55-basic-pfc_binary_tree.pfc | 1174 ++++++++++++++++++++++++++ tests/55-basic-pfc_binary_tree.sh | 46 + tests/55-basic-pfc_binary_tree.tests | 11 + tests/Makefile.am | 17 +- 13 files changed, 2067 insertions(+), 4 deletions(-) create mode 100644 tests/53-sim-binary_tree.c create mode 100755 tests/53-sim-binary_tree.py create mode 100644 tests/53-sim-binary_tree.tests create mode 100644 tests/54-live-binary_tree.c create mode 100755 tests/54-live-binary_tree.py create mode 100644 tests/54-live-binary_tree.tests create mode 100644 tests/55-basic-pfc_binary_tree.c create mode 100644 tests/55-basic-pfc_binary_tree.pfc create mode 100755 tests/55-basic-pfc_binary_tree.sh create mode 100644 tests/55-basic-pfc_binary_tree.tests diff --git a/tests/.gitignore b/tests/.gitignore index 5b17af9b..bd00e140 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -58,3 +58,6 @@ util.pyc 50-sim-hash_collision 51-live-user_notification 52-basic-load +53-sim-binary_tree +54-live-binary_tree +55-basic-pfc_binary_tree diff --git a/tests/13-basic-attrs.py b/tests/13-basic-attrs.py index 38971c09..0435ded9 100755 --- a/tests/13-basic-attrs.py +++ b/tests/13-basic-attrs.py @@ -55,6 +55,9 @@ def test(): f.set_attr(Attr.CTL_SSB, 1) if f.get_attr(Attr.CTL_SSB) != 1: raise RuntimeError("Failed getting Attr.CTL_SSB") + f.set_attr(Attr.CTL_OPTIMIZE, 2) + if f.get_attr(Attr.CTL_OPTIMIZE) != 2: + raise RuntimeError("Failed getting Attr.CTL_OPTIMIZE") test() diff --git a/tests/53-sim-binary_tree.c b/tests/53-sim-binary_tree.c new file mode 100644 index 00000000..2c7890e5 --- /dev/null +++ b/tests/53-sim-binary_tree.c @@ -0,0 +1,95 @@ +/** + * Seccomp Library test program + * + * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Author: Tom Hromatka + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include +#include +#include +#include + +#include + +#include "util.h" + +#define MAX_SYSCALL (330) + +#include + +int main(int argc, char *argv[]) +{ + int rc, i; + struct util_options opts; + scmp_filter_ctx ctx = NULL; + + rc = util_getopt(argc, argv, &opts); + if (rc < 0) + goto out; + + ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) { + rc = ENOMEM; + goto out; + } + + rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); + if (rc < 0) + goto out; + rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); + if (rc < 0) + goto out; + rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); + if (rc < 0) + goto out; + rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_OPTIMIZE, 2); + if (rc < 0) + goto out; + + /* NOTE: this test is entirely fabricated and should not be + * replicated in the real world. + * + * The MAX_SYSCALL number (330) was chosen to force seccomp to + * build an unbalanced binary tree - and it happens to be less + * than the current syscall max. The syscall numbers are + * hardcoded to simplify the test. A few syscalls have + * argument chains to further complicate the filter. + */ + + for (i = 0; i < MAX_SYSCALL; i++) { + /* arbitrarily make the filter more complex by filtering + * on arguments for a few syscalls + */ + if (i == 10 || i == 53 || i == 61 || i == 255) + rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 1, + SCMP_A0(SCMP_CMP_EQ, i)); + else + rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 0); + if (rc < 0) + goto out; + } + + rc = util_filter_output(&opts, ctx); + if (rc) + goto out; + +out: + seccomp_release(ctx); + return (rc < 0 ? -rc : rc); +} diff --git a/tests/53-sim-binary_tree.py b/tests/53-sim-binary_tree.py new file mode 100755 index 00000000..8a17918b --- /dev/null +++ b/tests/53-sim-binary_tree.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +# +# Seccomp Library test program +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of version 2.1 of the GNU Lesser General Public License as +# published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see . +# + +import argparse +import sys + +import util + +from seccomp import * + +def test(args): + f = SyscallFilter(ALLOW) + + f.remove_arch(Arch()) + f.add_arch(Arch("x86_64")) + f.add_arch(Arch("x86")) + f.set_attr(Attr.CTL_OPTIMIZE, 2) + + for i in range(330): + if (i == 10 or i == 53 or i == 61 or i == 255): + f.add_rule(ERRNO(i), i, Arg(0, EQ, i)) + else: + f.add_rule(ERRNO(i), i) + + return f + +args = util.get_opt() +ctx = test(args) +util.filter_output(args, ctx) + +# kate: syntax python; +# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/tests/53-sim-binary_tree.tests b/tests/53-sim-binary_tree.tests new file mode 100644 index 00000000..8c896ac3 --- /dev/null +++ b/tests/53-sim-binary_tree.tests @@ -0,0 +1,345 @@ +# +# libseccomp regression test automation data +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +test type: bpf-sim + +# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result +53-sim-binary_tree all 0 N N N N N N ERRNO(0) +53-sim-binary_tree all 1 N N N N N N ERRNO(1) +53-sim-binary_tree all 2 N N N N N N ERRNO(2) +53-sim-binary_tree all 3 N N N N N N ERRNO(3) +53-sim-binary_tree all 4 N N N N N N ERRNO(4) +53-sim-binary_tree all 5 N N N N N N ERRNO(5) +53-sim-binary_tree all 6 N N N N N N ERRNO(6) +53-sim-binary_tree all 7 N N N N N N ERRNO(7) +53-sim-binary_tree all 8 N N N N N N ERRNO(8) +53-sim-binary_tree all 9 N N N N N N ERRNO(9) +53-sim-binary_tree all 10 10 N N N N N ERRNO(10) +53-sim-binary_tree all 11 N N N N N N ERRNO(11) +53-sim-binary_tree all 12 N N N N N N ERRNO(12) +53-sim-binary_tree all 13 N N N N N N ERRNO(13) +53-sim-binary_tree all 14 N N N N N N ERRNO(14) +53-sim-binary_tree all 15 N N N N N N ERRNO(15) +53-sim-binary_tree all 16 N N N N N N ERRNO(16) +53-sim-binary_tree all 17 N N N N N N ERRNO(17) +53-sim-binary_tree all 18 N N N N N N ERRNO(18) +53-sim-binary_tree all 19 N N N N N N ERRNO(19) +53-sim-binary_tree all 20 N N N N N N ERRNO(20) +53-sim-binary_tree all 21 N N N N N N ERRNO(21) +53-sim-binary_tree all 22 N N N N N N ERRNO(22) +53-sim-binary_tree all 23 N N N N N N ERRNO(23) +53-sim-binary_tree all 24 N N N N N N ERRNO(24) +53-sim-binary_tree all 25 N N N N N N ERRNO(25) +53-sim-binary_tree all 26 N N N N N N ERRNO(26) +53-sim-binary_tree all 27 N N N N N N ERRNO(27) +53-sim-binary_tree all 28 N N N N N N ERRNO(28) +53-sim-binary_tree all 29 N N N N N N ERRNO(29) +53-sim-binary_tree all 30 N N N N N N ERRNO(30) +53-sim-binary_tree all 31 N N N N N N ERRNO(31) +53-sim-binary_tree all 32 N N N N N N ERRNO(32) +53-sim-binary_tree all 33 N N N N N N ERRNO(33) +53-sim-binary_tree all 34 N N N N N N ERRNO(34) +53-sim-binary_tree all 35 N N N N N N ERRNO(35) +53-sim-binary_tree all 36 N N N N N N ERRNO(36) +53-sim-binary_tree all 37 N N N N N N ERRNO(37) +53-sim-binary_tree all 38 N N N N N N ERRNO(38) +53-sim-binary_tree all 39 N N N N N N ERRNO(39) +53-sim-binary_tree all 40 N N N N N N ERRNO(40) +53-sim-binary_tree all 41 N N N N N N ERRNO(41) +53-sim-binary_tree all 42 N N N N N N ERRNO(42) +53-sim-binary_tree all 43 N N N N N N ERRNO(43) +53-sim-binary_tree all 44 N N N N N N ERRNO(44) +53-sim-binary_tree all 45 N N N N N N ERRNO(45) +53-sim-binary_tree all 46 N N N N N N ERRNO(46) +53-sim-binary_tree all 47 N N N N N N ERRNO(47) +53-sim-binary_tree all 48 N N N N N N ERRNO(48) +53-sim-binary_tree all 49 N N N N N N ERRNO(49) +53-sim-binary_tree all 50 N N N N N N ERRNO(50) +53-sim-binary_tree all 51 N N N N N N ERRNO(51) +53-sim-binary_tree all 52 N N N N N N ERRNO(52) +53-sim-binary_tree all 53 53 N N N N N ERRNO(53) +53-sim-binary_tree all 54 N N N N N N ERRNO(54) +53-sim-binary_tree all 55 N N N N N N ERRNO(55) +53-sim-binary_tree all 56 N N N N N N ERRNO(56) +53-sim-binary_tree all 57 N N N N N N ERRNO(57) +53-sim-binary_tree all 58 N N N N N N ERRNO(58) +53-sim-binary_tree all 59 N N N N N N ERRNO(59) +53-sim-binary_tree all 60 N N N N N N ERRNO(60) +53-sim-binary_tree all 61 61 N N N N N ERRNO(61) +53-sim-binary_tree all 62 N N N N N N ERRNO(62) +53-sim-binary_tree all 63 N N N N N N ERRNO(63) +53-sim-binary_tree all 64 N N N N N N ERRNO(64) +53-sim-binary_tree all 65 N N N N N N ERRNO(65) +53-sim-binary_tree all 66 N N N N N N ERRNO(66) +53-sim-binary_tree all 67 N N N N N N ERRNO(67) +53-sim-binary_tree all 68 N N N N N N ERRNO(68) +53-sim-binary_tree all 69 N N N N N N ERRNO(69) +53-sim-binary_tree all 70 N N N N N N ERRNO(70) +53-sim-binary_tree all 71 N N N N N N ERRNO(71) +53-sim-binary_tree all 72 N N N N N N ERRNO(72) +53-sim-binary_tree all 73 N N N N N N ERRNO(73) +53-sim-binary_tree all 74 N N N N N N ERRNO(74) +53-sim-binary_tree all 75 N N N N N N ERRNO(75) +53-sim-binary_tree all 76 N N N N N N ERRNO(76) +53-sim-binary_tree all 77 N N N N N N ERRNO(77) +53-sim-binary_tree all 78 N N N N N N ERRNO(78) +53-sim-binary_tree all 79 N N N N N N ERRNO(79) +53-sim-binary_tree all 80 N N N N N N ERRNO(80) +53-sim-binary_tree all 81 N N N N N N ERRNO(81) +53-sim-binary_tree all 82 N N N N N N ERRNO(82) +53-sim-binary_tree all 83 N N N N N N ERRNO(83) +53-sim-binary_tree all 84 N N N N N N ERRNO(84) +53-sim-binary_tree all 85 N N N N N N ERRNO(85) +53-sim-binary_tree all 86 N N N N N N ERRNO(86) +53-sim-binary_tree all 87 N N N N N N ERRNO(87) +53-sim-binary_tree all 88 N N N N N N ERRNO(88) +53-sim-binary_tree all 89 N N N N N N ERRNO(89) +53-sim-binary_tree all 90 N N N N N N ERRNO(90) +53-sim-binary_tree all 91 N N N N N N ERRNO(91) +53-sim-binary_tree all 92 N N N N N N ERRNO(92) +53-sim-binary_tree all 93 N N N N N N ERRNO(93) +53-sim-binary_tree all 94 N N N N N N ERRNO(94) +53-sim-binary_tree all 95 N N N N N N ERRNO(95) +53-sim-binary_tree all 96 N N N N N N ERRNO(96) +53-sim-binary_tree all 97 N N N N N N ERRNO(97) +53-sim-binary_tree all 98 N N N N N N ERRNO(98) +53-sim-binary_tree all 99 N N N N N N ERRNO(99) +53-sim-binary_tree all 100 N N N N N N ERRNO(100) +53-sim-binary_tree all 101 N N N N N N ERRNO(101) +53-sim-binary_tree all 102 N N N N N N ERRNO(102) +53-sim-binary_tree all 103 N N N N N N ERRNO(103) +53-sim-binary_tree all 104 N N N N N N ERRNO(104) +53-sim-binary_tree all 105 N N N N N N ERRNO(105) +53-sim-binary_tree all 106 N N N N N N ERRNO(106) +53-sim-binary_tree all 107 N N N N N N ERRNO(107) +53-sim-binary_tree all 108 N N N N N N ERRNO(108) +53-sim-binary_tree all 109 N N N N N N ERRNO(109) +53-sim-binary_tree all 110 N N N N N N ERRNO(110) +53-sim-binary_tree all 111 N N N N N N ERRNO(111) +53-sim-binary_tree all 112 N N N N N N ERRNO(112) +53-sim-binary_tree all 113 N N N N N N ERRNO(113) +53-sim-binary_tree all 114 N N N N N N ERRNO(114) +53-sim-binary_tree all 115 N N N N N N ERRNO(115) +53-sim-binary_tree all 116 N N N N N N ERRNO(116) +53-sim-binary_tree all 117 N N N N N N ERRNO(117) +53-sim-binary_tree all 118 N N N N N N ERRNO(118) +53-sim-binary_tree all 119 N N N N N N ERRNO(119) +53-sim-binary_tree all 120 N N N N N N ERRNO(120) +53-sim-binary_tree all 121 N N N N N N ERRNO(121) +53-sim-binary_tree all 122 N N N N N N ERRNO(122) +53-sim-binary_tree all 123 N N N N N N ERRNO(123) +53-sim-binary_tree all 124 N N N N N N ERRNO(124) +53-sim-binary_tree all 125 N N N N N N ERRNO(125) +53-sim-binary_tree all 126 N N N N N N ERRNO(126) +53-sim-binary_tree all 127 N N N N N N ERRNO(127) +53-sim-binary_tree all 128 N N N N N N ERRNO(128) +53-sim-binary_tree all 129 N N N N N N ERRNO(129) +53-sim-binary_tree all 130 N N N N N N ERRNO(130) +53-sim-binary_tree all 131 N N N N N N ERRNO(131) +53-sim-binary_tree all 132 N N N N N N ERRNO(132) +53-sim-binary_tree all 133 N N N N N N ERRNO(133) +53-sim-binary_tree all 134 N N N N N N ERRNO(134) +53-sim-binary_tree all 135 N N N N N N ERRNO(135) +53-sim-binary_tree all 136 N N N N N N ERRNO(136) +53-sim-binary_tree all 137 N N N N N N ERRNO(137) +53-sim-binary_tree all 138 N N N N N N ERRNO(138) +53-sim-binary_tree all 139 N N N N N N ERRNO(139) +53-sim-binary_tree all 140 N N N N N N ERRNO(140) +53-sim-binary_tree all 141 N N N N N N ERRNO(141) +53-sim-binary_tree all 142 N N N N N N ERRNO(142) +53-sim-binary_tree all 143 N N N N N N ERRNO(143) +53-sim-binary_tree all 144 N N N N N N ERRNO(144) +53-sim-binary_tree all 145 N N N N N N ERRNO(145) +53-sim-binary_tree all 146 N N N N N N ERRNO(146) +53-sim-binary_tree all 147 N N N N N N ERRNO(147) +53-sim-binary_tree all 148 N N N N N N ERRNO(148) +53-sim-binary_tree all 149 N N N N N N ERRNO(149) +53-sim-binary_tree all 150 N N N N N N ERRNO(150) +53-sim-binary_tree all 151 N N N N N N ERRNO(151) +53-sim-binary_tree all 152 N N N N N N ERRNO(152) +53-sim-binary_tree all 153 N N N N N N ERRNO(153) +53-sim-binary_tree all 154 N N N N N N ERRNO(154) +53-sim-binary_tree all 155 N N N N N N ERRNO(155) +53-sim-binary_tree all 156 N N N N N N ERRNO(156) +53-sim-binary_tree all 157 N N N N N N ERRNO(157) +53-sim-binary_tree all 158 N N N N N N ERRNO(158) +53-sim-binary_tree all 159 N N N N N N ERRNO(159) +53-sim-binary_tree all 160 N N N N N N ERRNO(160) +53-sim-binary_tree all 161 N N N N N N ERRNO(161) +53-sim-binary_tree all 162 N N N N N N ERRNO(162) +53-sim-binary_tree all 163 N N N N N N ERRNO(163) +53-sim-binary_tree all 164 N N N N N N ERRNO(164) +53-sim-binary_tree all 165 N N N N N N ERRNO(165) +53-sim-binary_tree all 166 N N N N N N ERRNO(166) +53-sim-binary_tree all 167 N N N N N N ERRNO(167) +53-sim-binary_tree all 168 N N N N N N ERRNO(168) +53-sim-binary_tree all 169 N N N N N N ERRNO(169) +53-sim-binary_tree all 170 N N N N N N ERRNO(170) +53-sim-binary_tree all 171 N N N N N N ERRNO(171) +53-sim-binary_tree all 172 N N N N N N ERRNO(172) +53-sim-binary_tree all 173 N N N N N N ERRNO(173) +53-sim-binary_tree all 174 N N N N N N ERRNO(174) +53-sim-binary_tree all 175 N N N N N N ERRNO(175) +53-sim-binary_tree all 176 N N N N N N ERRNO(176) +53-sim-binary_tree all 177 N N N N N N ERRNO(177) +53-sim-binary_tree all 178 N N N N N N ERRNO(178) +53-sim-binary_tree all 179 N N N N N N ERRNO(179) +53-sim-binary_tree all 180 N N N N N N ERRNO(180) +53-sim-binary_tree all 181 N N N N N N ERRNO(181) +53-sim-binary_tree all 182 N N N N N N ERRNO(182) +53-sim-binary_tree all 183 N N N N N N ERRNO(183) +53-sim-binary_tree all 184 N N N N N N ERRNO(184) +53-sim-binary_tree all 185 N N N N N N ERRNO(185) +53-sim-binary_tree all 186 N N N N N N ERRNO(186) +53-sim-binary_tree all 187 N N N N N N ERRNO(187) +53-sim-binary_tree all 188 N N N N N N ERRNO(188) +53-sim-binary_tree all 189 N N N N N N ERRNO(189) +53-sim-binary_tree all 190 N N N N N N ERRNO(190) +53-sim-binary_tree all 191 N N N N N N ERRNO(191) +53-sim-binary_tree all 192 N N N N N N ERRNO(192) +53-sim-binary_tree all 193 N N N N N N ERRNO(193) +53-sim-binary_tree all 194 N N N N N N ERRNO(194) +53-sim-binary_tree all 195 N N N N N N ERRNO(195) +53-sim-binary_tree all 196 N N N N N N ERRNO(196) +53-sim-binary_tree all 197 N N N N N N ERRNO(197) +53-sim-binary_tree all 198 N N N N N N ERRNO(198) +53-sim-binary_tree all 199 N N N N N N ERRNO(199) +53-sim-binary_tree all 200 N N N N N N ERRNO(200) +53-sim-binary_tree all 201 N N N N N N ERRNO(201) +53-sim-binary_tree all 202 N N N N N N ERRNO(202) +53-sim-binary_tree all 203 N N N N N N ERRNO(203) +53-sim-binary_tree all 204 N N N N N N ERRNO(204) +53-sim-binary_tree all 205 N N N N N N ERRNO(205) +53-sim-binary_tree all 206 N N N N N N ERRNO(206) +53-sim-binary_tree all 207 N N N N N N ERRNO(207) +53-sim-binary_tree all 208 N N N N N N ERRNO(208) +53-sim-binary_tree all 209 N N N N N N ERRNO(209) +53-sim-binary_tree all 210 N N N N N N ERRNO(210) +53-sim-binary_tree all 211 N N N N N N ERRNO(211) +53-sim-binary_tree all 212 N N N N N N ERRNO(212) +53-sim-binary_tree all 213 N N N N N N ERRNO(213) +53-sim-binary_tree all 214 N N N N N N ERRNO(214) +53-sim-binary_tree all 215 N N N N N N ERRNO(215) +53-sim-binary_tree all 216 N N N N N N ERRNO(216) +53-sim-binary_tree all 217 N N N N N N ERRNO(217) +53-sim-binary_tree all 218 N N N N N N ERRNO(218) +53-sim-binary_tree all 219 N N N N N N ERRNO(219) +53-sim-binary_tree all 220 N N N N N N ERRNO(220) +53-sim-binary_tree all 221 N N N N N N ERRNO(221) +53-sim-binary_tree all 222 N N N N N N ERRNO(222) +53-sim-binary_tree all 223 N N N N N N ERRNO(223) +53-sim-binary_tree all 224 N N N N N N ERRNO(224) +53-sim-binary_tree all 225 N N N N N N ERRNO(225) +53-sim-binary_tree all 226 N N N N N N ERRNO(226) +53-sim-binary_tree all 227 N N N N N N ERRNO(227) +53-sim-binary_tree all 228 N N N N N N ERRNO(228) +53-sim-binary_tree all 229 N N N N N N ERRNO(229) +53-sim-binary_tree all 230 N N N N N N ERRNO(230) +53-sim-binary_tree all 231 N N N N N N ERRNO(231) +53-sim-binary_tree all 232 N N N N N N ERRNO(232) +53-sim-binary_tree all 233 N N N N N N ERRNO(233) +53-sim-binary_tree all 234 N N N N N N ERRNO(234) +53-sim-binary_tree all 235 N N N N N N ERRNO(235) +53-sim-binary_tree all 236 N N N N N N ERRNO(236) +53-sim-binary_tree all 237 N N N N N N ERRNO(237) +53-sim-binary_tree all 238 N N N N N N ERRNO(238) +53-sim-binary_tree all 239 N N N N N N ERRNO(239) +53-sim-binary_tree all 240 N N N N N N ERRNO(240) +53-sim-binary_tree all 241 N N N N N N ERRNO(241) +53-sim-binary_tree all 242 N N N N N N ERRNO(242) +53-sim-binary_tree all 243 N N N N N N ERRNO(243) +53-sim-binary_tree all 244 N N N N N N ERRNO(244) +53-sim-binary_tree all 245 N N N N N N ERRNO(245) +53-sim-binary_tree all 246 N N N N N N ERRNO(246) +53-sim-binary_tree all 247 N N N N N N ERRNO(247) +53-sim-binary_tree all 248 N N N N N N ERRNO(248) +53-sim-binary_tree all 249 N N N N N N ERRNO(249) +53-sim-binary_tree all 250 N N N N N N ERRNO(250) +53-sim-binary_tree all 251 N N N N N N ERRNO(251) +53-sim-binary_tree all 252 N N N N N N ERRNO(252) +53-sim-binary_tree all 253 N N N N N N ERRNO(253) +53-sim-binary_tree all 254 N N N N N N ERRNO(254) +53-sim-binary_tree all 255 255 N N N N N ERRNO(255) +53-sim-binary_tree all 256 N N N N N N ERRNO(256) +53-sim-binary_tree all 257 N N N N N N ERRNO(257) +53-sim-binary_tree all 258 N N N N N N ERRNO(258) +53-sim-binary_tree all 259 N N N N N N ERRNO(259) +53-sim-binary_tree all 260 N N N N N N ERRNO(260) +53-sim-binary_tree all 261 N N N N N N ERRNO(261) +53-sim-binary_tree all 262 N N N N N N ERRNO(262) +53-sim-binary_tree all 263 N N N N N N ERRNO(263) +53-sim-binary_tree all 264 N N N N N N ERRNO(264) +53-sim-binary_tree all 265 N N N N N N ERRNO(265) +53-sim-binary_tree all 266 N N N N N N ERRNO(266) +53-sim-binary_tree all 267 N N N N N N ERRNO(267) +53-sim-binary_tree all 268 N N N N N N ERRNO(268) +53-sim-binary_tree all 269 N N N N N N ERRNO(269) +53-sim-binary_tree all 270 N N N N N N ERRNO(270) +53-sim-binary_tree all 271 N N N N N N ERRNO(271) +53-sim-binary_tree all 272 N N N N N N ERRNO(272) +53-sim-binary_tree all 273 N N N N N N ERRNO(273) +53-sim-binary_tree all 274 N N N N N N ERRNO(274) +53-sim-binary_tree all 275 N N N N N N ERRNO(275) +53-sim-binary_tree all 276 N N N N N N ERRNO(276) +53-sim-binary_tree all 277 N N N N N N ERRNO(277) +53-sim-binary_tree all 278 N N N N N N ERRNO(278) +53-sim-binary_tree all 279 N N N N N N ERRNO(279) +53-sim-binary_tree all 280 N N N N N N ERRNO(280) +53-sim-binary_tree all 281 N N N N N N ERRNO(281) +53-sim-binary_tree all 282 N N N N N N ERRNO(282) +53-sim-binary_tree all 283 N N N N N N ERRNO(283) +53-sim-binary_tree all 284 N N N N N N ERRNO(284) +53-sim-binary_tree all 285 N N N N N N ERRNO(285) +53-sim-binary_tree all 286 N N N N N N ERRNO(286) +53-sim-binary_tree all 287 N N N N N N ERRNO(287) +53-sim-binary_tree all 288 N N N N N N ERRNO(288) +53-sim-binary_tree all 289 N N N N N N ERRNO(289) +53-sim-binary_tree all 290 N N N N N N ERRNO(290) +53-sim-binary_tree all 291 N N N N N N ERRNO(291) +53-sim-binary_tree all 292 N N N N N N ERRNO(292) +53-sim-binary_tree all 293 N N N N N N ERRNO(293) +53-sim-binary_tree all 294 N N N N N N ERRNO(294) +53-sim-binary_tree all 295 N N N N N N ERRNO(295) +53-sim-binary_tree all 296 N N N N N N ERRNO(296) +53-sim-binary_tree all 297 N N N N N N ERRNO(297) +53-sim-binary_tree all 298 N N N N N N ERRNO(298) +53-sim-binary_tree all 299 N N N N N N ERRNO(299) +53-sim-binary_tree all 300 N N N N N N ERRNO(300) +53-sim-binary_tree all 301 N N N N N N ERRNO(301) +53-sim-binary_tree all 302 N N N N N N ERRNO(302) +53-sim-binary_tree all 303 N N N N N N ERRNO(303) +53-sim-binary_tree all 304 N N N N N N ERRNO(304) +53-sim-binary_tree all 305 N N N N N N ERRNO(305) +53-sim-binary_tree all 306 N N N N N N ERRNO(306) +53-sim-binary_tree all 307 N N N N N N ERRNO(307) +53-sim-binary_tree all 308 N N N N N N ERRNO(308) +53-sim-binary_tree all 309 N N N N N N ERRNO(309) +53-sim-binary_tree all 310 N N N N N N ERRNO(310) +53-sim-binary_tree all 311 N N N N N N ERRNO(311) +53-sim-binary_tree all 312 N N N N N N ERRNO(312) +53-sim-binary_tree all 313 N N N N N N ERRNO(313) +53-sim-binary_tree all 314 N N N N N N ERRNO(314) +53-sim-binary_tree all 315 N N N N N N ERRNO(315) +53-sim-binary_tree all 316 N N N N N N ERRNO(316) +53-sim-binary_tree all 317 N N N N N N ERRNO(317) +53-sim-binary_tree all 318 N N N N N N ERRNO(318) +53-sim-binary_tree all 319 N N N N N N ERRNO(319) +53-sim-binary_tree all 320 N N N N N N ERRNO(320) +53-sim-binary_tree all 321 N N N N N N ERRNO(321) +53-sim-binary_tree all 322 N N N N N N ERRNO(322) +53-sim-binary_tree all 323 N N N N N N ERRNO(323) +53-sim-binary_tree all 324 N N N N N N ERRNO(324) +53-sim-binary_tree all 325 N N N N N N ERRNO(325) +53-sim-binary_tree all 326 N N N N N N ERRNO(326) +53-sim-binary_tree all 327 N N N N N N ERRNO(327) +53-sim-binary_tree all 328 N N N N N N ERRNO(328) +53-sim-binary_tree all 329 N N N N N N ERRNO(329) + +test type: bpf-valgrind + +# Testname +53-sim-binary_tree diff --git a/tests/54-live-binary_tree.c b/tests/54-live-binary_tree.c new file mode 100644 index 00000000..6c8eb155 --- /dev/null +++ b/tests/54-live-binary_tree.c @@ -0,0 +1,128 @@ +/** + * Seccomp Library test program + * + * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Author: Tom Hromatka + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "util.h" + +/* arbitrary list of syscalls to force seccomp to generate a binary tree */ +static const int blacklist[] = { + SCMP_SYS(times), + SCMP_SYS(ptrace), + SCMP_SYS(getuid), + SCMP_SYS(syslog), + SCMP_SYS(getgid), + SCMP_SYS(setuid), + SCMP_SYS(setgid), + SCMP_SYS(geteuid), + SCMP_SYS(getegid), + SCMP_SYS(setpgid), + SCMP_SYS(getppid), + SCMP_SYS(getpgrp), + SCMP_SYS(setsid), + SCMP_SYS(setreuid), + SCMP_SYS(setregid), + SCMP_SYS(getgroups), + SCMP_SYS(setgroups), + SCMP_SYS(setresuid), + SCMP_SYS(getresuid), + SCMP_SYS(setresgid), + SCMP_SYS(getresgid), + SCMP_SYS(getpgid), + SCMP_SYS(setfsuid), + SCMP_SYS(setfsgid), +}; + +int main(int argc, char *argv[]) +{ + int rc; + int fd; + int i; + scmp_filter_ctx ctx = NULL; + const char buf[] = "testing"; + ssize_t buf_len = strlen(buf); + + rc = util_action_parse(argv[1]); + if (rc != SCMP_ACT_ALLOW) { + rc = 1; + goto out; + } + + rc = util_trap_install(); + if (rc != 0) + goto out; + + fd = open("/dev/null", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + if (fd < 0) { + rc = errno; + goto out; + } + + ctx = seccomp_init(SCMP_ACT_TRAP); + if (ctx == NULL) + return ENOMEM; + + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, + SCMP_A0(SCMP_CMP_EQ, fd)); + if (rc != 0) + goto out; + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); + if (rc != 0) + goto out; + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); + if (rc != 0) + goto out; + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); + if (rc != 0) + goto out; + + for (i = 0; i < (sizeof(blacklist) / sizeof(blacklist[0])); i++) { + rc = seccomp_rule_add(ctx, SCMP_ACT_KILL, blacklist[i], 0); + if (rc != 0) + goto out; + } + + rc = seccomp_load(ctx); + if (rc != 0) + goto out; + + if (write(fd, buf, buf_len) < buf_len) { + rc = errno; + goto out; + } + if (close(fd) < 0) { + rc = errno; + goto out; + } + + rc = 160; + +out: + seccomp_release(ctx); + return (rc < 0 ? -rc : rc); +} diff --git a/tests/54-live-binary_tree.py b/tests/54-live-binary_tree.py new file mode 100755 index 00000000..125c888c --- /dev/null +++ b/tests/54-live-binary_tree.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python + +# +# Seccomp Library test program +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of version 2.1 of the GNU Lesser General Public License as +# published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see . +# + +import argparse +import sys + +import util + +from seccomp import * + +blacklist = [ + "times", + "ptrace", + "getuid", + "syslog", + "getgid", + "setuid", + "setgid", + "geteuid", + "getegid", + "setpgid", + "getppid", + "getpgrp", + "setsid", + "setreuid", + "setregid", + "getgroups", + "setgroups", + "setresuid", + "getresuid", + "setresgid", + "getresgid", + "getpgid", + "setfsuid", + "setfsgid", +] + +def test(): + action = util.parse_action(sys.argv[1]) + if not action == ALLOW: + quit(1) + util.install_trap() + f = SyscallFilter(TRAP) + f.set_attr(Attr.CTL_TSYNC, 1) + # NOTE: additional syscalls required for python + f.add_rule(ALLOW, "stat") + f.add_rule(ALLOW, "fstat") + f.add_rule(ALLOW, "open") + f.add_rule(ALLOW, "openat") + f.add_rule(ALLOW, "mmap") + f.add_rule(ALLOW, "munmap") + f.add_rule(ALLOW, "read") + f.add_rule(ALLOW, "write") + f.add_rule(ALLOW, "close") + f.add_rule(ALLOW, "rt_sigaction") + f.add_rule(ALLOW, "rt_sigreturn") + f.add_rule(ALLOW, "sigreturn") + f.add_rule(ALLOW, "sigaltstack") + f.add_rule(ALLOW, "brk") + f.add_rule(ALLOW, "exit_group") + + for syscall in blacklist: + f.add_rule(KILL, syscall) + + f.load() + try: + util.write_file("/dev/null") + except OSError as ex: + quit(ex.errno) + quit(160) + +test() + +# kate: syntax python; +# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/tests/54-live-binary_tree.tests b/tests/54-live-binary_tree.tests new file mode 100644 index 00000000..63575e9a --- /dev/null +++ b/tests/54-live-binary_tree.tests @@ -0,0 +1,11 @@ +# +# libseccomp regression test automation data +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +test type: live + +# Testname API Result +54-live-binary_tree 1 ALLOW diff --git a/tests/55-basic-pfc_binary_tree.c b/tests/55-basic-pfc_binary_tree.c new file mode 100644 index 00000000..6a45cece --- /dev/null +++ b/tests/55-basic-pfc_binary_tree.c @@ -0,0 +1,91 @@ +/** + * Seccomp Library test program + * + * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Author: Tom Hromatka + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include +#include +#include +#include + +#include + +#include "util.h" + +#define MAX_SYSCALL (330) + +#include + +int main(int argc, char *argv[]) +{ + int rc, fd, i; + scmp_filter_ctx ctx = NULL; + + /* stdout */ + fd = 1; + + ctx = seccomp_init(SCMP_ACT_ALLOW); + if (ctx == NULL) { + rc = ENOMEM; + goto out; + } + + rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); + if (rc < 0) + goto out; + rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); + if (rc < 0) + goto out; + rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_OPTIMIZE, 2); + if (rc < 0) + goto out; + + /* NOTE: this test is entirely fabricated and should not be + * replicated in the real world. + * + * The MAX_SYSCALL number (330) was chosen to force seccomp to + * build an unbalanced binary tree - and it happens to be less + * than the current syscall max. The syscall numbers are + * hardcoded to simplify the test. A few syscalls have + * argument chains to further complicate the filter. + */ + + for (i = 0; i < MAX_SYSCALL; i++) { + /* arbitrarily make the filter more complex by filtering + * on arguments for a few syscalls + */ + if (i == 10 || i == 53 || i == 61 || i == 255) + rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 1, + SCMP_A0(SCMP_CMP_EQ, i)); + else + rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(i), i, 0); + if (rc < 0) + goto out; + } + + rc = seccomp_export_pfc(ctx, fd); + if (rc < 0) + goto out; + +out: + seccomp_release(ctx); + close(fd); + return (rc < 0 ? -rc : rc); +} diff --git a/tests/55-basic-pfc_binary_tree.pfc b/tests/55-basic-pfc_binary_tree.pfc new file mode 100644 index 00000000..10b4f870 --- /dev/null +++ b/tests/55-basic-pfc_binary_tree.pfc @@ -0,0 +1,1174 @@ +# +# pseudo filter code start +# +# filter for arch x86_64 (3221225534) +if ($arch == 3221225534) + if ($syscall > 73) + if ($syscall > 201) + if ($syscall > 265) + if ($syscall > 297) + if ($syscall > 313) + if ($syscall > 321) + if ($syscall > 325) + # filter for syscall "pkey_mprotect" (329) [priority: 65535] + if ($syscall == 329) + action ERRNO(329); + # filter for syscall "pwritev2" (328) [priority: 65535] + if ($syscall == 328) + action ERRNO(328); + # filter for syscall "preadv2" (327) [priority: 65535] + if ($syscall == 327) + action ERRNO(327); + # filter for syscall "copy_file_range" (326) [priority: 65535] + if ($syscall == 326) + action ERRNO(326); + else # ($syscall <= 325) + # filter for syscall "mlock2" (325) [priority: 65535] + if ($syscall == 325) + action ERRNO(325); + # filter for syscall "membarrier" (324) [priority: 65535] + if ($syscall == 324) + action ERRNO(324); + # filter for syscall "userfaultfd" (323) [priority: 65535] + if ($syscall == 323) + action ERRNO(323); + # filter for syscall "execveat" (322) [priority: 65535] + if ($syscall == 322) + action ERRNO(322); + else # ($syscall <= 321) + if ($syscall > 317) + # filter for syscall "bpf" (321) [priority: 65535] + if ($syscall == 321) + action ERRNO(321); + # filter for syscall "kexec_file_load" (320) [priority: 65535] + if ($syscall == 320) + action ERRNO(320); + # filter for syscall "memfd_create" (319) [priority: 65535] + if ($syscall == 319) + action ERRNO(319); + # filter for syscall "getrandom" (318) [priority: 65535] + if ($syscall == 318) + action ERRNO(318); + else # ($syscall <= 317) + # filter for syscall "seccomp" (317) [priority: 65535] + if ($syscall == 317) + action ERRNO(317); + # filter for syscall "renameat2" (316) [priority: 65535] + if ($syscall == 316) + action ERRNO(316); + # filter for syscall "sched_getattr" (315) [priority: 65535] + if ($syscall == 315) + action ERRNO(315); + # filter for syscall "sched_setattr" (314) [priority: 65535] + if ($syscall == 314) + action ERRNO(314); + else # ($syscall <= 313) + if ($syscall > 305) + if ($syscall > 309) + # filter for syscall "finit_module" (313) [priority: 65535] + if ($syscall == 313) + action ERRNO(313); + # filter for syscall "kcmp" (312) [priority: 65535] + if ($syscall == 312) + action ERRNO(312); + # filter for syscall "process_vm_writev" (311) [priority: 65535] + if ($syscall == 311) + action ERRNO(311); + # filter for syscall "process_vm_readv" (310) [priority: 65535] + if ($syscall == 310) + action ERRNO(310); + else # ($syscall <= 309) + # filter for syscall "getcpu" (309) [priority: 65535] + if ($syscall == 309) + action ERRNO(309); + # filter for syscall "setns" (308) [priority: 65535] + if ($syscall == 308) + action ERRNO(308); + # filter for syscall "sendmmsg" (307) [priority: 65535] + if ($syscall == 307) + action ERRNO(307); + # filter for syscall "syncfs" (306) [priority: 65535] + if ($syscall == 306) + action ERRNO(306); + else # ($syscall <= 305) + if ($syscall > 301) + # filter for syscall "clock_adjtime" (305) [priority: 65535] + if ($syscall == 305) + action ERRNO(305); + # filter for syscall "open_by_handle_at" (304) [priority: 65535] + if ($syscall == 304) + action ERRNO(304); + # filter for syscall "name_to_handle_at" (303) [priority: 65535] + if ($syscall == 303) + action ERRNO(303); + # filter for syscall "prlimit64" (302) [priority: 65535] + if ($syscall == 302) + action ERRNO(302); + else # ($syscall <= 301) + # filter for syscall "fanotify_mark" (301) [priority: 65535] + if ($syscall == 301) + action ERRNO(301); + # filter for syscall "fanotify_init" (300) [priority: 65535] + if ($syscall == 300) + action ERRNO(300); + # filter for syscall "recvmmsg" (299) [priority: 65535] + if ($syscall == 299) + action ERRNO(299); + # filter for syscall "perf_event_open" (298) [priority: 65535] + if ($syscall == 298) + action ERRNO(298); + else # ($syscall <= 297) + if ($syscall > 281) + if ($syscall > 289) + if ($syscall > 293) + # filter for syscall "rt_tgsigqueueinfo" (297) [priority: 65535] + if ($syscall == 297) + action ERRNO(297); + # filter for syscall "pwritev" (296) [priority: 65535] + if ($syscall == 296) + action ERRNO(296); + # filter for syscall "preadv" (295) [priority: 65535] + if ($syscall == 295) + action ERRNO(295); + # filter for syscall "inotify_init1" (294) [priority: 65535] + if ($syscall == 294) + action ERRNO(294); + else # ($syscall <= 293) + # filter for syscall "pipe2" (293) [priority: 65535] + if ($syscall == 293) + action ERRNO(293); + # filter for syscall "dup3" (292) [priority: 65535] + if ($syscall == 292) + action ERRNO(292); + # filter for syscall "epoll_create1" (291) [priority: 65535] + if ($syscall == 291) + action ERRNO(291); + # filter for syscall "eventfd2" (290) [priority: 65535] + if ($syscall == 290) + action ERRNO(290); + else # ($syscall <= 289) + if ($syscall > 285) + # filter for syscall "signalfd4" (289) [priority: 65535] + if ($syscall == 289) + action ERRNO(289); + # filter for syscall "accept4" (288) [priority: 65535] + if ($syscall == 288) + action ERRNO(288); + # filter for syscall "timerfd_gettime" (287) [priority: 65535] + if ($syscall == 287) + action ERRNO(287); + # filter for syscall "timerfd_settime" (286) [priority: 65535] + if ($syscall == 286) + action ERRNO(286); + else # ($syscall <= 285) + # filter for syscall "fallocate" (285) [priority: 65535] + if ($syscall == 285) + action ERRNO(285); + # filter for syscall "eventfd" (284) [priority: 65535] + if ($syscall == 284) + action ERRNO(284); + # filter for syscall "timerfd_create" (283) [priority: 65535] + if ($syscall == 283) + action ERRNO(283); + # filter for syscall "signalfd" (282) [priority: 65535] + if ($syscall == 282) + action ERRNO(282); + else # ($syscall <= 281) + if ($syscall > 273) + if ($syscall > 277) + # filter for syscall "epoll_pwait" (281) [priority: 65535] + if ($syscall == 281) + action ERRNO(281); + # filter for syscall "utimensat" (280) [priority: 65535] + if ($syscall == 280) + action ERRNO(280); + # filter for syscall "move_pages" (279) [priority: 65535] + if ($syscall == 279) + action ERRNO(279); + # filter for syscall "vmsplice" (278) [priority: 65535] + if ($syscall == 278) + action ERRNO(278); + else # ($syscall <= 277) + # filter for syscall "sync_file_range" (277) [priority: 65535] + if ($syscall == 277) + action ERRNO(277); + # filter for syscall "tee" (276) [priority: 65535] + if ($syscall == 276) + action ERRNO(276); + # filter for syscall "splice" (275) [priority: 65535] + if ($syscall == 275) + action ERRNO(275); + # filter for syscall "get_robust_list" (274) [priority: 65535] + if ($syscall == 274) + action ERRNO(274); + else # ($syscall <= 273) + if ($syscall > 269) + # filter for syscall "set_robust_list" (273) [priority: 65535] + if ($syscall == 273) + action ERRNO(273); + # filter for syscall "unshare" (272) [priority: 65535] + if ($syscall == 272) + action ERRNO(272); + # filter for syscall "ppoll" (271) [priority: 65535] + if ($syscall == 271) + action ERRNO(271); + # filter for syscall "pselect6" (270) [priority: 65535] + if ($syscall == 270) + action ERRNO(270); + else # ($syscall <= 269) + # filter for syscall "faccessat" (269) [priority: 65535] + if ($syscall == 269) + action ERRNO(269); + # filter for syscall "fchmodat" (268) [priority: 65535] + if ($syscall == 268) + action ERRNO(268); + # filter for syscall "readlinkat" (267) [priority: 65535] + if ($syscall == 267) + action ERRNO(267); + # filter for syscall "symlinkat" (266) [priority: 65535] + if ($syscall == 266) + action ERRNO(266); + else # ($syscall <= 265) + if ($syscall > 233) + if ($syscall > 249) + if ($syscall > 257) + if ($syscall > 261) + # filter for syscall "linkat" (265) [priority: 65535] + if ($syscall == 265) + action ERRNO(265); + # filter for syscall "renameat" (264) [priority: 65535] + if ($syscall == 264) + action ERRNO(264); + # filter for syscall "unlinkat" (263) [priority: 65535] + if ($syscall == 263) + action ERRNO(263); + # filter for syscall "newfstatat" (262) [priority: 65535] + if ($syscall == 262) + action ERRNO(262); + else # ($syscall <= 261) + # filter for syscall "futimesat" (261) [priority: 65535] + if ($syscall == 261) + action ERRNO(261); + # filter for syscall "fchownat" (260) [priority: 65535] + if ($syscall == 260) + action ERRNO(260); + # filter for syscall "mknodat" (259) [priority: 65535] + if ($syscall == 259) + action ERRNO(259); + # filter for syscall "mkdirat" (258) [priority: 65535] + if ($syscall == 258) + action ERRNO(258); + else # ($syscall <= 257) + if ($syscall > 253) + # filter for syscall "openat" (257) [priority: 65535] + if ($syscall == 257) + action ERRNO(257); + # filter for syscall "migrate_pages" (256) [priority: 65535] + if ($syscall == 256) + action ERRNO(256); + # filter for syscall "inotify_rm_watch" (255) [priority: 65533] + if ($syscall == 255) + if ($a0.hi32 == 0) + if ($a0.lo32 == 255) + action ERRNO(255); + # filter for syscall "inotify_add_watch" (254) [priority: 65535] + if ($syscall == 254) + action ERRNO(254); + else # ($syscall <= 253) + # filter for syscall "inotify_init" (253) [priority: 65535] + if ($syscall == 253) + action ERRNO(253); + # filter for syscall "ioprio_get" (252) [priority: 65535] + if ($syscall == 252) + action ERRNO(252); + # filter for syscall "ioprio_set" (251) [priority: 65535] + if ($syscall == 251) + action ERRNO(251); + # filter for syscall "keyctl" (250) [priority: 65535] + if ($syscall == 250) + action ERRNO(250); + else # ($syscall <= 249) + if ($syscall > 241) + if ($syscall > 245) + # filter for syscall "request_key" (249) [priority: 65535] + if ($syscall == 249) + action ERRNO(249); + # filter for syscall "add_key" (248) [priority: 65535] + if ($syscall == 248) + action ERRNO(248); + # filter for syscall "waitid" (247) [priority: 65535] + if ($syscall == 247) + action ERRNO(247); + # filter for syscall "kexec_load" (246) [priority: 65535] + if ($syscall == 246) + action ERRNO(246); + else # ($syscall <= 245) + # filter for syscall "mq_getsetattr" (245) [priority: 65535] + if ($syscall == 245) + action ERRNO(245); + # filter for syscall "mq_notify" (244) [priority: 65535] + if ($syscall == 244) + action ERRNO(244); + # filter for syscall "mq_timedreceive" (243) [priority: 65535] + if ($syscall == 243) + action ERRNO(243); + # filter for syscall "mq_timedsend" (242) [priority: 65535] + if ($syscall == 242) + action ERRNO(242); + else # ($syscall <= 241) + if ($syscall > 237) + # filter for syscall "mq_unlink" (241) [priority: 65535] + if ($syscall == 241) + action ERRNO(241); + # filter for syscall "mq_open" (240) [priority: 65535] + if ($syscall == 240) + action ERRNO(240); + # filter for syscall "get_mempolicy" (239) [priority: 65535] + if ($syscall == 239) + action ERRNO(239); + # filter for syscall "set_mempolicy" (238) [priority: 65535] + if ($syscall == 238) + action ERRNO(238); + else # ($syscall <= 237) + # filter for syscall "mbind" (237) [priority: 65535] + if ($syscall == 237) + action ERRNO(237); + # filter for syscall "vserver" (236) [priority: 65535] + if ($syscall == 236) + action ERRNO(236); + # filter for syscall "utimes" (235) [priority: 65535] + if ($syscall == 235) + action ERRNO(235); + # filter for syscall "tgkill" (234) [priority: 65535] + if ($syscall == 234) + action ERRNO(234); + else # ($syscall <= 233) + if ($syscall > 217) + if ($syscall > 225) + if ($syscall > 229) + # filter for syscall "epoll_ctl" (233) [priority: 65535] + if ($syscall == 233) + action ERRNO(233); + # filter for syscall "epoll_wait" (232) [priority: 65535] + if ($syscall == 232) + action ERRNO(232); + # filter for syscall "exit_group" (231) [priority: 65535] + if ($syscall == 231) + action ERRNO(231); + # filter for syscall "clock_nanosleep" (230) [priority: 65535] + if ($syscall == 230) + action ERRNO(230); + else # ($syscall <= 229) + # filter for syscall "clock_getres" (229) [priority: 65535] + if ($syscall == 229) + action ERRNO(229); + # filter for syscall "clock_gettime" (228) [priority: 65535] + if ($syscall == 228) + action ERRNO(228); + # filter for syscall "clock_settime" (227) [priority: 65535] + if ($syscall == 227) + action ERRNO(227); + # filter for syscall "timer_delete" (226) [priority: 65535] + if ($syscall == 226) + action ERRNO(226); + else # ($syscall <= 225) + if ($syscall > 221) + # filter for syscall "timer_getoverrun" (225) [priority: 65535] + if ($syscall == 225) + action ERRNO(225); + # filter for syscall "timer_gettime" (224) [priority: 65535] + if ($syscall == 224) + action ERRNO(224); + # filter for syscall "timer_settime" (223) [priority: 65535] + if ($syscall == 223) + action ERRNO(223); + # filter for syscall "timer_create" (222) [priority: 65535] + if ($syscall == 222) + action ERRNO(222); + else # ($syscall <= 221) + # filter for syscall "fadvise64" (221) [priority: 65535] + if ($syscall == 221) + action ERRNO(221); + # filter for syscall "semtimedop" (220) [priority: 65535] + if ($syscall == 220) + action ERRNO(220); + # filter for syscall "restart_syscall" (219) [priority: 65535] + if ($syscall == 219) + action ERRNO(219); + # filter for syscall "set_tid_address" (218) [priority: 65535] + if ($syscall == 218) + action ERRNO(218); + else # ($syscall <= 217) + if ($syscall > 209) + if ($syscall > 213) + # filter for syscall "getdents64" (217) [priority: 65535] + if ($syscall == 217) + action ERRNO(217); + # filter for syscall "remap_file_pages" (216) [priority: 65535] + if ($syscall == 216) + action ERRNO(216); + # filter for syscall "epoll_wait_old" (215) [priority: 65535] + if ($syscall == 215) + action ERRNO(215); + # filter for syscall "epoll_ctl_old" (214) [priority: 65535] + if ($syscall == 214) + action ERRNO(214); + else # ($syscall <= 213) + # filter for syscall "epoll_create" (213) [priority: 65535] + if ($syscall == 213) + action ERRNO(213); + # filter for syscall "lookup_dcookie" (212) [priority: 65535] + if ($syscall == 212) + action ERRNO(212); + # filter for syscall "get_thread_area" (211) [priority: 65535] + if ($syscall == 211) + action ERRNO(211); + # filter for syscall "io_cancel" (210) [priority: 65535] + if ($syscall == 210) + action ERRNO(210); + else # ($syscall <= 209) + if ($syscall > 205) + # filter for syscall "io_submit" (209) [priority: 65535] + if ($syscall == 209) + action ERRNO(209); + # filter for syscall "io_getevents" (208) [priority: 65535] + if ($syscall == 208) + action ERRNO(208); + # filter for syscall "io_destroy" (207) [priority: 65535] + if ($syscall == 207) + action ERRNO(207); + # filter for syscall "io_setup" (206) [priority: 65535] + if ($syscall == 206) + action ERRNO(206); + else # ($syscall <= 205) + # filter for syscall "set_thread_area" (205) [priority: 65535] + if ($syscall == 205) + action ERRNO(205); + # filter for syscall "sched_getaffinity" (204) [priority: 65535] + if ($syscall == 204) + action ERRNO(204); + # filter for syscall "sched_setaffinity" (203) [priority: 65535] + if ($syscall == 203) + action ERRNO(203); + # filter for syscall "futex" (202) [priority: 65535] + if ($syscall == 202) + action ERRNO(202); + else # ($syscall <= 201) + if ($syscall > 137) + if ($syscall > 169) + if ($syscall > 185) + if ($syscall > 193) + if ($syscall > 197) + # filter for syscall "time" (201) [priority: 65535] + if ($syscall == 201) + action ERRNO(201); + # filter for syscall "tkill" (200) [priority: 65535] + if ($syscall == 200) + action ERRNO(200); + # filter for syscall "fremovexattr" (199) [priority: 65535] + if ($syscall == 199) + action ERRNO(199); + # filter for syscall "lremovexattr" (198) [priority: 65535] + if ($syscall == 198) + action ERRNO(198); + else # ($syscall <= 197) + # filter for syscall "removexattr" (197) [priority: 65535] + if ($syscall == 197) + action ERRNO(197); + # filter for syscall "flistxattr" (196) [priority: 65535] + if ($syscall == 196) + action ERRNO(196); + # filter for syscall "llistxattr" (195) [priority: 65535] + if ($syscall == 195) + action ERRNO(195); + # filter for syscall "listxattr" (194) [priority: 65535] + if ($syscall == 194) + action ERRNO(194); + else # ($syscall <= 193) + if ($syscall > 189) + # filter for syscall "fgetxattr" (193) [priority: 65535] + if ($syscall == 193) + action ERRNO(193); + # filter for syscall "lgetxattr" (192) [priority: 65535] + if ($syscall == 192) + action ERRNO(192); + # filter for syscall "getxattr" (191) [priority: 65535] + if ($syscall == 191) + action ERRNO(191); + # filter for syscall "fsetxattr" (190) [priority: 65535] + if ($syscall == 190) + action ERRNO(190); + else # ($syscall <= 189) + # filter for syscall "lsetxattr" (189) [priority: 65535] + if ($syscall == 189) + action ERRNO(189); + # filter for syscall "setxattr" (188) [priority: 65535] + if ($syscall == 188) + action ERRNO(188); + # filter for syscall "readahead" (187) [priority: 65535] + if ($syscall == 187) + action ERRNO(187); + # filter for syscall "gettid" (186) [priority: 65535] + if ($syscall == 186) + action ERRNO(186); + else # ($syscall <= 185) + if ($syscall > 177) + if ($syscall > 181) + # filter for syscall "security" (185) [priority: 65535] + if ($syscall == 185) + action ERRNO(185); + # filter for syscall "tuxcall" (184) [priority: 65535] + if ($syscall == 184) + action ERRNO(184); + # filter for syscall "afs_syscall" (183) [priority: 65535] + if ($syscall == 183) + action ERRNO(183); + # filter for syscall "putpmsg" (182) [priority: 65535] + if ($syscall == 182) + action ERRNO(182); + else # ($syscall <= 181) + # filter for syscall "getpmsg" (181) [priority: 65535] + if ($syscall == 181) + action ERRNO(181); + # filter for syscall "nfsservctl" (180) [priority: 65535] + if ($syscall == 180) + action ERRNO(180); + # filter for syscall "quotactl" (179) [priority: 65535] + if ($syscall == 179) + action ERRNO(179); + # filter for syscall "query_module" (178) [priority: 65535] + if ($syscall == 178) + action ERRNO(178); + else # ($syscall <= 177) + if ($syscall > 173) + # filter for syscall "get_kernel_syms" (177) [priority: 65535] + if ($syscall == 177) + action ERRNO(177); + # filter for syscall "delete_module" (176) [priority: 65535] + if ($syscall == 176) + action ERRNO(176); + # filter for syscall "init_module" (175) [priority: 65535] + if ($syscall == 175) + action ERRNO(175); + # filter for syscall "create_module" (174) [priority: 65535] + if ($syscall == 174) + action ERRNO(174); + else # ($syscall <= 173) + # filter for syscall "ioperm" (173) [priority: 65535] + if ($syscall == 173) + action ERRNO(173); + # filter for syscall "iopl" (172) [priority: 65535] + if ($syscall == 172) + action ERRNO(172); + # filter for syscall "setdomainname" (171) [priority: 65535] + if ($syscall == 171) + action ERRNO(171); + # filter for syscall "sethostname" (170) [priority: 65535] + if ($syscall == 170) + action ERRNO(170); + else # ($syscall <= 169) + if ($syscall > 153) + if ($syscall > 161) + if ($syscall > 165) + # filter for syscall "reboot" (169) [priority: 65535] + if ($syscall == 169) + action ERRNO(169); + # filter for syscall "swapoff" (168) [priority: 65535] + if ($syscall == 168) + action ERRNO(168); + # filter for syscall "swapon" (167) [priority: 65535] + if ($syscall == 167) + action ERRNO(167); + # filter for syscall "umount2" (166) [priority: 65535] + if ($syscall == 166) + action ERRNO(166); + else # ($syscall <= 165) + # filter for syscall "mount" (165) [priority: 65535] + if ($syscall == 165) + action ERRNO(165); + # filter for syscall "settimeofday" (164) [priority: 65535] + if ($syscall == 164) + action ERRNO(164); + # filter for syscall "acct" (163) [priority: 65535] + if ($syscall == 163) + action ERRNO(163); + # filter for syscall "sync" (162) [priority: 65535] + if ($syscall == 162) + action ERRNO(162); + else # ($syscall <= 161) + if ($syscall > 157) + # filter for syscall "chroot" (161) [priority: 65535] + if ($syscall == 161) + action ERRNO(161); + # filter for syscall "setrlimit" (160) [priority: 65535] + if ($syscall == 160) + action ERRNO(160); + # filter for syscall "adjtimex" (159) [priority: 65535] + if ($syscall == 159) + action ERRNO(159); + # filter for syscall "arch_prctl" (158) [priority: 65535] + if ($syscall == 158) + action ERRNO(158); + else # ($syscall <= 157) + # filter for syscall "prctl" (157) [priority: 65535] + if ($syscall == 157) + action ERRNO(157); + # filter for syscall "_sysctl" (156) [priority: 65535] + if ($syscall == 156) + action ERRNO(156); + # filter for syscall "pivot_root" (155) [priority: 65535] + if ($syscall == 155) + action ERRNO(155); + # filter for syscall "modify_ldt" (154) [priority: 65535] + if ($syscall == 154) + action ERRNO(154); + else # ($syscall <= 153) + if ($syscall > 145) + if ($syscall > 149) + # filter for syscall "vhangup" (153) [priority: 65535] + if ($syscall == 153) + action ERRNO(153); + # filter for syscall "munlockall" (152) [priority: 65535] + if ($syscall == 152) + action ERRNO(152); + # filter for syscall "mlockall" (151) [priority: 65535] + if ($syscall == 151) + action ERRNO(151); + # filter for syscall "munlock" (150) [priority: 65535] + if ($syscall == 150) + action ERRNO(150); + else # ($syscall <= 149) + # filter for syscall "mlock" (149) [priority: 65535] + if ($syscall == 149) + action ERRNO(149); + # filter for syscall "sched_rr_get_interval" (148) [priority: 65535] + if ($syscall == 148) + action ERRNO(148); + # filter for syscall "sched_get_priority_min" (147) [priority: 65535] + if ($syscall == 147) + action ERRNO(147); + # filter for syscall "sched_get_priority_max" (146) [priority: 65535] + if ($syscall == 146) + action ERRNO(146); + else # ($syscall <= 145) + if ($syscall > 141) + # filter for syscall "sched_getscheduler" (145) [priority: 65535] + if ($syscall == 145) + action ERRNO(145); + # filter for syscall "sched_setscheduler" (144) [priority: 65535] + if ($syscall == 144) + action ERRNO(144); + # filter for syscall "sched_getparam" (143) [priority: 65535] + if ($syscall == 143) + action ERRNO(143); + # filter for syscall "sched_setparam" (142) [priority: 65535] + if ($syscall == 142) + action ERRNO(142); + else # ($syscall <= 141) + # filter for syscall "setpriority" (141) [priority: 65535] + if ($syscall == 141) + action ERRNO(141); + # filter for syscall "getpriority" (140) [priority: 65535] + if ($syscall == 140) + action ERRNO(140); + # filter for syscall "sysfs" (139) [priority: 65535] + if ($syscall == 139) + action ERRNO(139); + # filter for syscall "fstatfs" (138) [priority: 65535] + if ($syscall == 138) + action ERRNO(138); + else # ($syscall <= 137) + if ($syscall > 105) + if ($syscall > 121) + if ($syscall > 129) + if ($syscall > 133) + # filter for syscall "statfs" (137) [priority: 65535] + if ($syscall == 137) + action ERRNO(137); + # filter for syscall "ustat" (136) [priority: 65535] + if ($syscall == 136) + action ERRNO(136); + # filter for syscall "personality" (135) [priority: 65535] + if ($syscall == 135) + action ERRNO(135); + # filter for syscall "uselib" (134) [priority: 65535] + if ($syscall == 134) + action ERRNO(134); + else # ($syscall <= 133) + # filter for syscall "mknod" (133) [priority: 65535] + if ($syscall == 133) + action ERRNO(133); + # filter for syscall "utime" (132) [priority: 65535] + if ($syscall == 132) + action ERRNO(132); + # filter for syscall "sigaltstack" (131) [priority: 65535] + if ($syscall == 131) + action ERRNO(131); + # filter for syscall "rt_sigsuspend" (130) [priority: 65535] + if ($syscall == 130) + action ERRNO(130); + else # ($syscall <= 129) + if ($syscall > 125) + # filter for syscall "rt_sigqueueinfo" (129) [priority: 65535] + if ($syscall == 129) + action ERRNO(129); + # filter for syscall "rt_sigtimedwait" (128) [priority: 65535] + if ($syscall == 128) + action ERRNO(128); + # filter for syscall "rt_sigpending" (127) [priority: 65535] + if ($syscall == 127) + action ERRNO(127); + # filter for syscall "capset" (126) [priority: 65535] + if ($syscall == 126) + action ERRNO(126); + else # ($syscall <= 125) + # filter for syscall "capget" (125) [priority: 65535] + if ($syscall == 125) + action ERRNO(125); + # filter for syscall "getsid" (124) [priority: 65535] + if ($syscall == 124) + action ERRNO(124); + # filter for syscall "setfsgid" (123) [priority: 65535] + if ($syscall == 123) + action ERRNO(123); + # filter for syscall "setfsuid" (122) [priority: 65535] + if ($syscall == 122) + action ERRNO(122); + else # ($syscall <= 121) + if ($syscall > 113) + if ($syscall > 117) + # filter for syscall "getpgid" (121) [priority: 65535] + if ($syscall == 121) + action ERRNO(121); + # filter for syscall "getresgid" (120) [priority: 65535] + if ($syscall == 120) + action ERRNO(120); + # filter for syscall "setresgid" (119) [priority: 65535] + if ($syscall == 119) + action ERRNO(119); + # filter for syscall "getresuid" (118) [priority: 65535] + if ($syscall == 118) + action ERRNO(118); + else # ($syscall <= 117) + # filter for syscall "setresuid" (117) [priority: 65535] + if ($syscall == 117) + action ERRNO(117); + # filter for syscall "setgroups" (116) [priority: 65535] + if ($syscall == 116) + action ERRNO(116); + # filter for syscall "getgroups" (115) [priority: 65535] + if ($syscall == 115) + action ERRNO(115); + # filter for syscall "setregid" (114) [priority: 65535] + if ($syscall == 114) + action ERRNO(114); + else # ($syscall <= 113) + if ($syscall > 109) + # filter for syscall "setreuid" (113) [priority: 65535] + if ($syscall == 113) + action ERRNO(113); + # filter for syscall "setsid" (112) [priority: 65535] + if ($syscall == 112) + action ERRNO(112); + # filter for syscall "getpgrp" (111) [priority: 65535] + if ($syscall == 111) + action ERRNO(111); + # filter for syscall "getppid" (110) [priority: 65535] + if ($syscall == 110) + action ERRNO(110); + else # ($syscall <= 109) + # filter for syscall "setpgid" (109) [priority: 65535] + if ($syscall == 109) + action ERRNO(109); + # filter for syscall "getegid" (108) [priority: 65535] + if ($syscall == 108) + action ERRNO(108); + # filter for syscall "geteuid" (107) [priority: 65535] + if ($syscall == 107) + action ERRNO(107); + # filter for syscall "setgid" (106) [priority: 65535] + if ($syscall == 106) + action ERRNO(106); + else # ($syscall <= 105) + if ($syscall > 89) + if ($syscall > 97) + if ($syscall > 101) + # filter for syscall "setuid" (105) [priority: 65535] + if ($syscall == 105) + action ERRNO(105); + # filter for syscall "getgid" (104) [priority: 65535] + if ($syscall == 104) + action ERRNO(104); + # filter for syscall "syslog" (103) [priority: 65535] + if ($syscall == 103) + action ERRNO(103); + # filter for syscall "getuid" (102) [priority: 65535] + if ($syscall == 102) + action ERRNO(102); + else # ($syscall <= 101) + # filter for syscall "ptrace" (101) [priority: 65535] + if ($syscall == 101) + action ERRNO(101); + # filter for syscall "times" (100) [priority: 65535] + if ($syscall == 100) + action ERRNO(100); + # filter for syscall "sysinfo" (99) [priority: 65535] + if ($syscall == 99) + action ERRNO(99); + # filter for syscall "getrusage" (98) [priority: 65535] + if ($syscall == 98) + action ERRNO(98); + else # ($syscall <= 97) + if ($syscall > 93) + # filter for syscall "getrlimit" (97) [priority: 65535] + if ($syscall == 97) + action ERRNO(97); + # filter for syscall "gettimeofday" (96) [priority: 65535] + if ($syscall == 96) + action ERRNO(96); + # filter for syscall "umask" (95) [priority: 65535] + if ($syscall == 95) + action ERRNO(95); + # filter for syscall "lchown" (94) [priority: 65535] + if ($syscall == 94) + action ERRNO(94); + else # ($syscall <= 93) + # filter for syscall "fchown" (93) [priority: 65535] + if ($syscall == 93) + action ERRNO(93); + # filter for syscall "chown" (92) [priority: 65535] + if ($syscall == 92) + action ERRNO(92); + # filter for syscall "fchmod" (91) [priority: 65535] + if ($syscall == 91) + action ERRNO(91); + # filter for syscall "chmod" (90) [priority: 65535] + if ($syscall == 90) + action ERRNO(90); + else # ($syscall <= 89) + if ($syscall > 81) + if ($syscall > 85) + # filter for syscall "readlink" (89) [priority: 65535] + if ($syscall == 89) + action ERRNO(89); + # filter for syscall "symlink" (88) [priority: 65535] + if ($syscall == 88) + action ERRNO(88); + # filter for syscall "unlink" (87) [priority: 65535] + if ($syscall == 87) + action ERRNO(87); + # filter for syscall "link" (86) [priority: 65535] + if ($syscall == 86) + action ERRNO(86); + else # ($syscall <= 85) + # filter for syscall "creat" (85) [priority: 65535] + if ($syscall == 85) + action ERRNO(85); + # filter for syscall "rmdir" (84) [priority: 65535] + if ($syscall == 84) + action ERRNO(84); + # filter for syscall "mkdir" (83) [priority: 65535] + if ($syscall == 83) + action ERRNO(83); + # filter for syscall "rename" (82) [priority: 65535] + if ($syscall == 82) + action ERRNO(82); + else # ($syscall <= 81) + if ($syscall > 77) + # filter for syscall "fchdir" (81) [priority: 65535] + if ($syscall == 81) + action ERRNO(81); + # filter for syscall "chdir" (80) [priority: 65535] + if ($syscall == 80) + action ERRNO(80); + # filter for syscall "getcwd" (79) [priority: 65535] + if ($syscall == 79) + action ERRNO(79); + # filter for syscall "getdents" (78) [priority: 65535] + if ($syscall == 78) + action ERRNO(78); + else # ($syscall <= 77) + # filter for syscall "ftruncate" (77) [priority: 65535] + if ($syscall == 77) + action ERRNO(77); + # filter for syscall "truncate" (76) [priority: 65535] + if ($syscall == 76) + action ERRNO(76); + # filter for syscall "fdatasync" (75) [priority: 65535] + if ($syscall == 75) + action ERRNO(75); + # filter for syscall "fsync" (74) [priority: 65535] + if ($syscall == 74) + action ERRNO(74); + else # ($syscall <= 73) + if ($syscall > 9) + if ($syscall > 41) + if ($syscall > 57) + if ($syscall > 65) + if ($syscall > 69) + # filter for syscall "flock" (73) [priority: 65535] + if ($syscall == 73) + action ERRNO(73); + # filter for syscall "fcntl" (72) [priority: 65535] + if ($syscall == 72) + action ERRNO(72); + # filter for syscall "msgctl" (71) [priority: 65535] + if ($syscall == 71) + action ERRNO(71); + # filter for syscall "msgrcv" (70) [priority: 65535] + if ($syscall == 70) + action ERRNO(70); + else # ($syscall <= 69) + # filter for syscall "msgsnd" (69) [priority: 65535] + if ($syscall == 69) + action ERRNO(69); + # filter for syscall "msgget" (68) [priority: 65535] + if ($syscall == 68) + action ERRNO(68); + # filter for syscall "shmdt" (67) [priority: 65535] + if ($syscall == 67) + action ERRNO(67); + # filter for syscall "semctl" (66) [priority: 65535] + if ($syscall == 66) + action ERRNO(66); + else # ($syscall <= 65) + if ($syscall > 61) + # filter for syscall "semop" (65) [priority: 65535] + if ($syscall == 65) + action ERRNO(65); + # filter for syscall "semget" (64) [priority: 65535] + if ($syscall == 64) + action ERRNO(64); + # filter for syscall "uname" (63) [priority: 65535] + if ($syscall == 63) + action ERRNO(63); + # filter for syscall "kill" (62) [priority: 65535] + if ($syscall == 62) + action ERRNO(62); + else # ($syscall <= 61) + # filter for syscall "wait4" (61) [priority: 65533] + if ($syscall == 61) + if ($a0.hi32 == 0) + if ($a0.lo32 == 61) + action ERRNO(61); + # filter for syscall "exit" (60) [priority: 65535] + if ($syscall == 60) + action ERRNO(60); + # filter for syscall "execve" (59) [priority: 65535] + if ($syscall == 59) + action ERRNO(59); + # filter for syscall "vfork" (58) [priority: 65535] + if ($syscall == 58) + action ERRNO(58); + else # ($syscall <= 57) + if ($syscall > 49) + if ($syscall > 53) + # filter for syscall "fork" (57) [priority: 65535] + if ($syscall == 57) + action ERRNO(57); + # filter for syscall "clone" (56) [priority: 65535] + if ($syscall == 56) + action ERRNO(56); + # filter for syscall "getsockopt" (55) [priority: 65535] + if ($syscall == 55) + action ERRNO(55); + # filter for syscall "setsockopt" (54) [priority: 65535] + if ($syscall == 54) + action ERRNO(54); + else # ($syscall <= 53) + # filter for syscall "socketpair" (53) [priority: 65533] + if ($syscall == 53) + if ($a0.hi32 == 0) + if ($a0.lo32 == 53) + action ERRNO(53); + # filter for syscall "getpeername" (52) [priority: 65535] + if ($syscall == 52) + action ERRNO(52); + # filter for syscall "getsockname" (51) [priority: 65535] + if ($syscall == 51) + action ERRNO(51); + # filter for syscall "listen" (50) [priority: 65535] + if ($syscall == 50) + action ERRNO(50); + else # ($syscall <= 49) + if ($syscall > 45) + # filter for syscall "bind" (49) [priority: 65535] + if ($syscall == 49) + action ERRNO(49); + # filter for syscall "shutdown" (48) [priority: 65535] + if ($syscall == 48) + action ERRNO(48); + # filter for syscall "recvmsg" (47) [priority: 65535] + if ($syscall == 47) + action ERRNO(47); + # filter for syscall "sendmsg" (46) [priority: 65535] + if ($syscall == 46) + action ERRNO(46); + else # ($syscall <= 45) + # filter for syscall "recvfrom" (45) [priority: 65535] + if ($syscall == 45) + action ERRNO(45); + # filter for syscall "sendto" (44) [priority: 65535] + if ($syscall == 44) + action ERRNO(44); + # filter for syscall "accept" (43) [priority: 65535] + if ($syscall == 43) + action ERRNO(43); + # filter for syscall "connect" (42) [priority: 65535] + if ($syscall == 42) + action ERRNO(42); + else # ($syscall <= 41) + if ($syscall > 25) + if ($syscall > 33) + if ($syscall > 37) + # filter for syscall "socket" (41) [priority: 65535] + if ($syscall == 41) + action ERRNO(41); + # filter for syscall "sendfile" (40) [priority: 65535] + if ($syscall == 40) + action ERRNO(40); + # filter for syscall "getpid" (39) [priority: 65535] + if ($syscall == 39) + action ERRNO(39); + # filter for syscall "setitimer" (38) [priority: 65535] + if ($syscall == 38) + action ERRNO(38); + else # ($syscall <= 37) + # filter for syscall "alarm" (37) [priority: 65535] + if ($syscall == 37) + action ERRNO(37); + # filter for syscall "getitimer" (36) [priority: 65535] + if ($syscall == 36) + action ERRNO(36); + # filter for syscall "nanosleep" (35) [priority: 65535] + if ($syscall == 35) + action ERRNO(35); + # filter for syscall "pause" (34) [priority: 65535] + if ($syscall == 34) + action ERRNO(34); + else # ($syscall <= 33) + if ($syscall > 29) + # filter for syscall "dup2" (33) [priority: 65535] + if ($syscall == 33) + action ERRNO(33); + # filter for syscall "dup" (32) [priority: 65535] + if ($syscall == 32) + action ERRNO(32); + # filter for syscall "shmctl" (31) [priority: 65535] + if ($syscall == 31) + action ERRNO(31); + # filter for syscall "shmat" (30) [priority: 65535] + if ($syscall == 30) + action ERRNO(30); + else # ($syscall <= 29) + # filter for syscall "shmget" (29) [priority: 65535] + if ($syscall == 29) + action ERRNO(29); + # filter for syscall "madvise" (28) [priority: 65535] + if ($syscall == 28) + action ERRNO(28); + # filter for syscall "mincore" (27) [priority: 65535] + if ($syscall == 27) + action ERRNO(27); + # filter for syscall "msync" (26) [priority: 65535] + if ($syscall == 26) + action ERRNO(26); + else # ($syscall <= 25) + if ($syscall > 17) + if ($syscall > 21) + # filter for syscall "mremap" (25) [priority: 65535] + if ($syscall == 25) + action ERRNO(25); + # filter for syscall "sched_yield" (24) [priority: 65535] + if ($syscall == 24) + action ERRNO(24); + # filter for syscall "select" (23) [priority: 65535] + if ($syscall == 23) + action ERRNO(23); + # filter for syscall "pipe" (22) [priority: 65535] + if ($syscall == 22) + action ERRNO(22); + else # ($syscall <= 21) + # filter for syscall "access" (21) [priority: 65535] + if ($syscall == 21) + action ERRNO(21); + # filter for syscall "writev" (20) [priority: 65535] + if ($syscall == 20) + action ERRNO(20); + # filter for syscall "readv" (19) [priority: 65535] + if ($syscall == 19) + action ERRNO(19); + # filter for syscall "pwrite64" (18) [priority: 65535] + if ($syscall == 18) + action ERRNO(18); + else # ($syscall <= 17) + if ($syscall > 13) + # filter for syscall "pread64" (17) [priority: 65535] + if ($syscall == 17) + action ERRNO(17); + # filter for syscall "ioctl" (16) [priority: 65535] + if ($syscall == 16) + action ERRNO(16); + # filter for syscall "rt_sigreturn" (15) [priority: 65535] + if ($syscall == 15) + action ERRNO(15); + # filter for syscall "rt_sigprocmask" (14) [priority: 65535] + if ($syscall == 14) + action ERRNO(14); + else # ($syscall <= 13) + # filter for syscall "rt_sigaction" (13) [priority: 65535] + if ($syscall == 13) + action ERRNO(13); + # filter for syscall "brk" (12) [priority: 65535] + if ($syscall == 12) + action ERRNO(12); + # filter for syscall "munmap" (11) [priority: 65535] + if ($syscall == 11) + action ERRNO(11); + # filter for syscall "mprotect" (10) [priority: 65533] + if ($syscall == 10) + if ($a0.hi32 == 0) + if ($a0.lo32 == 10) + action ERRNO(10); + else # ($syscall <= 9) + if ($syscall > 1) + if ($syscall > 5) + # filter for syscall "mmap" (9) [priority: 65535] + if ($syscall == 9) + action ERRNO(9); + # filter for syscall "lseek" (8) [priority: 65535] + if ($syscall == 8) + action ERRNO(8); + # filter for syscall "poll" (7) [priority: 65535] + if ($syscall == 7) + action ERRNO(7); + # filter for syscall "lstat" (6) [priority: 65535] + if ($syscall == 6) + action ERRNO(6); + else # ($syscall <= 5) + # filter for syscall "fstat" (5) [priority: 65535] + if ($syscall == 5) + action ERRNO(5); + # filter for syscall "stat" (4) [priority: 65535] + if ($syscall == 4) + action ERRNO(4); + # filter for syscall "close" (3) [priority: 65535] + if ($syscall == 3) + action ERRNO(3); + # filter for syscall "open" (2) [priority: 65535] + if ($syscall == 2) + action ERRNO(2); + else # ($syscall <= 1) + # filter for syscall "write" (1) [priority: 65535] + if ($syscall == 1) + action ERRNO(1); + # filter for syscall "read" (0) [priority: 65535] + if ($syscall == 0) + action ERRNO(0); + # default action + action ALLOW; +# invalid architecture action +action KILL; +# +# pseudo filter code end +# diff --git a/tests/55-basic-pfc_binary_tree.sh b/tests/55-basic-pfc_binary_tree.sh new file mode 100755 index 00000000..a12c69ce --- /dev/null +++ b/tests/55-basic-pfc_binary_tree.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# +# libseccomp regression test automation data +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +#### +# functions + +# +# Dependency check +# +# Arguments: +# 1 Dependency to check for +# +function check_deps() { + [[ -z "$1" ]] && return + which "$1" >& /dev/null + return $? +} + +# +# Dependency verification +# +# Arguments: +# 1 Dependency to check for +# +function verify_deps() { + [[ -z "$1" ]] && return + if ! check_deps "$1"; then + echo "error: install \"$1\" and include it in your \$PATH" + exit 1 + fi +} + +#### +# functions + +verify_deps diff + +# compare output to the known good output, fail if different +./55-basic-pfc_binary_tree | \ + diff -q ${srcdir:=.}/55-basic-pfc_binary_tree.pfc - > /dev/null diff --git a/tests/55-basic-pfc_binary_tree.tests b/tests/55-basic-pfc_binary_tree.tests new file mode 100644 index 00000000..8269a643 --- /dev/null +++ b/tests/55-basic-pfc_binary_tree.tests @@ -0,0 +1,11 @@ +# +# libseccomp regression test automation data +# +# Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +test type: basic + +# Test command +55-basic-pfc_binary_tree.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index 406d5a1c..4bd19c80 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -91,7 +91,10 @@ check_PROGRAMS = \ 49-sim-64b_comparisons \ 50-sim-hash_collision \ 51-live-user_notification \ - 52-basic-load + 52-basic-load \ + 53-sim-binary_tree \ + 54-live-binary_tree \ + 55-basic-pfc_binary_tree EXTRA_DIST_TESTPYTHON = \ util.py \ @@ -145,7 +148,9 @@ EXTRA_DIST_TESTPYTHON = \ 49-sim-64b_comparisons.py \ 50-sim-hash_collision.py \ 51-live-user_notification.py \ - 52-basic-load.py + 52-basic-load.py \ + 53-sim-binary_tree.py \ + 54-live-binary_tree.py EXTRA_DIST_TESTCFGS = \ 01-sim-allow.tests \ @@ -199,10 +204,14 @@ EXTRA_DIST_TESTCFGS = \ 49-sim-64b_comparisons.tests \ 50-sim-hash_collision.tests \ 51-live-user_notification.tests \ - 52-basic-load.tests + 52-basic-load.tests \ + 53-sim-binary_tree.tests \ + 54-live-binary_tree.tests \ + 55-basic-pfc_binary_tree.tests EXTRA_DIST_TESTSCRIPTS = \ - 38-basic-pfc_coverage.sh 38-basic-pfc_coverage.pfc + 38-basic-pfc_coverage.sh 38-basic-pfc_coverage.pfc \ + 55-basic-pfc_binary_tree.sh 55-basic-pfc_binary_tree.pfc EXTRA_DIST_TESTTOOLS = regression testdiff testgen