diff options
-rw-r--r-- | cooker/filter.c | 21 | ||||
-rw-r--r-- | cooker/filter.h | 8 | ||||
-rw-r--r-- | tests/unit/test_filter.c | 16 | ||||
-rw-r--r-- | tests/unit/test_filter_build.c | 55 | ||||
-rw-r--r-- | tests/unit/testutil.h | 3 | ||||
-rw-r--r-- | tests/unit/util.c | 2 |
6 files changed, 56 insertions, 49 deletions
diff --git a/cooker/filter.c b/cooker/filter.c index 29c2d64..9a2c9f1 100644 --- a/cooker/filter.c +++ b/cooker/filter.c @@ -158,7 +158,7 @@ static unsigned get_n_args_syscall_entry(const struct bpf_call *entry) unsigned i, n = 0; for (i = 0; i < 6; i++) - if (entry->args[i].type != NO_CHECK) + if (entry->args[i].cmp != NO_CHECK) n++; return n; } @@ -183,6 +183,8 @@ static unsigned int get_n_args_syscall_instr(const struct syscall_entry *table) entry = table->entry + i; n = 0; for (unsigned int k = 0; k < 6; k++) { + if (entry->args[k].cmp == NO_CHECK) + continue; switch (entry->args[k].type) { case U32: /* For 32 bit arguments: 2 instructions, @@ -197,8 +199,6 @@ static unsigned int get_n_args_syscall_instr(const struct syscall_entry *table) */ n += 4; break; - case NO_CHECK: - break; } } total_instr += n; @@ -229,12 +229,11 @@ static unsigned int get_total_args_instr(const struct syscall_entry table[], } static bool check_args_syscall_entry(const struct bpf_call *entry){ - return entry->args[0].type != NO_CHECK || - entry->args[1].type != NO_CHECK || - entry->args[2].type != NO_CHECK || - entry->args[3].type != NO_CHECK || - entry->args[4].type != NO_CHECK || - entry->args[5].type != NO_CHECK; + return entry->args[0].cmp != NO_CHECK || + entry->args[1].cmp != NO_CHECK || + entry->args[2].cmp != NO_CHECK || + entry->args[3].cmp != NO_CHECK || + entry->args[4].cmp != NO_CHECK || entry->args[5].cmp != NO_CHECK; } static bool check_args_syscall(const struct syscall_entry *table) @@ -352,10 +351,10 @@ unsigned int create_bfp_program(struct syscall_entry table[], entry = table[i].entry + j; next_args_off = get_n_args_syscall_entry(entry); for (k = 0; k < 6; k++) { + if (entry->args[k].cmp == NO_CHECK) + continue; offset = next_args_off - n_checks; switch (entry->args[k].type) { - case NO_CHECK: - break; case U64: size += eq_u64_filter( &filter[size], k, diff --git a/cooker/filter.h b/cooker/filter.h index 7705414..afdd0b9 100644 --- a/cooker/filter.h +++ b/cooker/filter.h @@ -33,16 +33,20 @@ #define MAX_JUMPS 128 #define EMPTY -1 -enum arg_type { NO_CHECK, U32, U64 }; +enum arg_type { U32, U64 }; union arg_value { uint32_t v32; uint64_t v64; }; +enum arg_cmp { NO_CHECK, EQ, NE, LE, LT, GE, GT, AND_EQ, AND_NE }; + struct arg { - enum arg_type type; union arg_value value; + enum arg_type type; + enum arg_cmp cmp; + union arg_value op2; }; struct bpf_call { diff --git a/tests/unit/test_filter.c b/tests/unit/test_filter.c index 4d7c9d8..90ffa2b 100644 --- a/tests/unit/test_filter.c +++ b/tests/unit/test_filter.c @@ -32,10 +32,10 @@ static int generate_install_filter(struct args_target *at) for (i = 0; i < 6; i++) { if (at->args[i] == NULL) { - calls[0].args[i].type = NO_CHECK; + calls[0].args[i].cmp = NO_CHECK; continue; } - switch (at->arg_type[i]) { + switch (at->type[i]) { case U32: calls[0].args[i].value.v32 = (uint32_t)at->args[i]; calls[0].args[i].type = U32; @@ -44,13 +44,9 @@ static int generate_install_filter(struct args_target *at) calls[0].args[i].value.v64 = (uint64_t)at->args[i]; calls[0].args[i].type = U64; break; - case NO_CHECK: - calls[0].args[i].type = NO_CHECK; - break; } } size = create_bfp_program(table, filter, 1); - bpf_disasm_all(filter, size); return install_filter(filter, size); } @@ -76,7 +72,7 @@ START_TEST(with_getsid) at->nr = __NR_getsid; set_args_no_check(at); at->args[0] = &id; - at->arg_type[0] = U32; + at->type[0] = U32; at->install_filter = generate_install_filter; setup(); mock_syscall_target(); @@ -93,9 +89,9 @@ START_TEST(with_getpriority) at->nr = __NR_getpriority; set_args_no_check(at); at->args[0] = &which; - at->arg_type[0] = U32; + at->type[0] = U32; at->args[1] = &who; - at->arg_type[0] = U32; + at->type[0] = U32; at->install_filter = generate_install_filter; setup(); mock_syscall_target(); @@ -121,7 +117,7 @@ static void test_lseek(off_t offset) at->target = target_lseek; set_args_no_check(at); at->args[1] = offset; - at->arg_type[1] = U64; + at->type[1] = U64; at->install_filter = generate_install_filter; setup(); mock_syscall_target(); diff --git a/tests/unit/test_filter_build.c b/tests/unit/test_filter_build.c index 4727e51..343d020 100644 --- a/tests/unit/test_filter_build.c +++ b/tests/unit/test_filter_build.c @@ -68,12 +68,13 @@ START_TEST(test_single_instr_two_args) unsigned int size; long nr = 42; struct bpf_call calls[] = { - { - .name = "test1", - .args = { 0, 123, 321, 0, 0, 0 }, - .check_arg = { NO_CHECK, U32, U32, NO_CHECK, NO_CHECK, - NO_CHECK }, - }, + { .name = "test1", + .args = { [1] = { .cmp = EQ, + .value = { .v32 = 123 }, + .type = U32 }, + [2] = { .cmp = EQ, + .value = { .v32 = 321 }, + .type = U32 } } }, }; struct syscall_entry table[] = { { .count = 1, .nr = nr, .entry = &calls[0] }, @@ -198,15 +199,21 @@ START_TEST(test_multiple_instr_with_args) unsigned int size; struct bpf_call calls[] = { { .name = "test1", - .args = { 0, 123, 321, 0, 0, 0 }, - .check_arg = { NO_CHECK, U32, U32, NO_CHECK, NO_CHECK, - NO_CHECK } }, + .args = { [1] = { .cmp = EQ, + .value = { .v32 = 123 }, + .type = U32 }, + [2] = { .cmp = EQ, + .value = { .v32 = 321 }, + .type = U32 } } }, { .name = "test2" }, { .name = "test3" }, { .name = "test4", - .args = { 0, 123, 321, 0, 0, 0 }, - .check_arg = { NO_CHECK, U32, U32, NO_CHECK, NO_CHECK, - NO_CHECK } }, + .args = { [1] = { .cmp = EQ, + .value = { .v32 = 123 }, + .type = U32 }, + [2] = { .cmp = EQ, + .value = { .v32 = 321 }, + .type = U32 } } }, { .name = "test5" }, }; struct syscall_entry table[] = { @@ -274,23 +281,23 @@ START_TEST(test_multiple_instance_same_instr) unsigned int size; struct bpf_call calls[] = { { .name = "test1", - .args = { 0, 123, 0, 0, 0, 0 }, - .check_arg = { NO_CHECK, U32, NO_CHECK, NO_CHECK, NO_CHECK, - NO_CHECK } }, + .args = { [1] = { .cmp = EQ, + .value = { .v32 = 123 }, + .type = U32 } } }, { .name = "test1", - .args = { 0, 0, 321, 0, 0, 0 }, - .check_arg = { NO_CHECK, NO_CHECK, U32, NO_CHECK, NO_CHECK, - NO_CHECK } }, + .args = { [2] = { .cmp = EQ, + .value = { .v32 = 321 }, + .type = U32 } } }, { .name = "test2" }, { .name = "test3" }, { .name = "test4", - .args = { 0, 123, 0, 0, 0, 0 }, - .check_arg = { NO_CHECK, U32, NO_CHECK, NO_CHECK, NO_CHECK, - NO_CHECK } }, + .args = { [1] = { .cmp = EQ, + .value = { .v32 = 123 }, + .type = U32 } } }, { .name = "test4", - .args = { 0, 0, 321, 0, 0, 0 }, - .check_arg = { NO_CHECK, NO_CHECK, U32, NO_CHECK, NO_CHECK, - NO_CHECK } }, + .args = { [2] = { .cmp = EQ, + .value = { .v32 = 321 }, + .type = U32 } } }, { .name = "test5" }, }; struct syscall_entry table[] = { diff --git a/tests/unit/testutil.h b/tests/unit/testutil.h index 7bb971a..4bd5550 100644 --- a/tests/unit/testutil.h +++ b/tests/unit/testutil.h @@ -19,7 +19,8 @@ struct args_target { bool open_path; int fd; int nr; - enum arg_type arg_type[6]; + enum arg_cmp cmp[6]; + enum arg_type type[6]; void *args[6]; int (*install_filter)(struct args_target *at); int (*target)(void *); diff --git a/tests/unit/util.c b/tests/unit/util.c index 7e5ec83..89d5d73 100644 --- a/tests/unit/util.c +++ b/tests/unit/util.c @@ -188,7 +188,7 @@ void mock_syscall_target() void set_args_no_check(struct args_target *at) { for (unsigned int i = 0; i < 6; i++) - at->arg_type[i] = NO_CHECK; + at->cmp[i] = NO_CHECK; } void setup() |