summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hromatka <tom.hromatka@oracle.com>2019-11-15 07:38:28 -0700
committerPaul Moore <paul@paul-moore.com>2020-02-28 08:32:41 -0500
commit19f4f4838b209b846e8e5c677283e32ac289a05f (patch)
tree0ecc22a7d8622a27b13e6226c362cf521fdeb8dd
parent5432e15521d5ce5a7d3f26bf78674cbaa9d73d1f (diff)
downloadlibseccomp-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.c113
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))