diff options
author | Tom Hromatka <tom.hromatka@oracle.com> | 2019-11-15 07:38:28 -0700 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2020-02-28 08:32:41 -0500 |
commit | 19f4f4838b209b846e8e5c677283e32ac289a05f (patch) | |
tree | 0ecc22a7d8622a27b13e6226c362cf521fdeb8dd | |
parent | 5432e15521d5ce5a7d3f26bf78674cbaa9d73d1f (diff) | |
download | libseccomp-19f4f4838b209b846e8e5c677283e32ac289a05f.tar.gz |
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 <tom.hromatka@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r-- | src/gen_bpf.c | 113 |
1 files changed, 48 insertions, 65 deletions
diff --git a/src/gen_bpf.c b/src/gen_bpf.c index 1b559b0..10855c5 100644 --- a/src/gen_bpf.c +++ b/src/gen_bpf.c @@ -1144,6 +1144,50 @@ chain_failure: } /** + * 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 * @param sys the syscall filter DB entry @@ -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)) |