From 1c36e1cb218c67b519170ec23d3ccfcde6b615e7 Mon Sep 17 00:00:00 2001 From: liuchang Date: Tue, 26 Nov 2024 06:33:14 +0000 Subject: [PATCH] add api maat_state_sort_rules to sort rule_uuid by order: 1.priority 2.condition_num 3.uuid --- include/maat.h | 7 +++++ src/inc_internal/maat_rule.h | 2 ++ src/maat_api.c | 21 +++++++++++++ src/maat_config_monitor.c | 5 +++ src/maat_rule.c | 57 +++++++++++++++++++++++++++++++++-- test/maat_framework_gtest.cpp | 29 ++++++++++++++---- test/maat_json.json | 8 ++--- test/test_utils.cpp | 2 ++ 8 files changed, 119 insertions(+), 12 deletions(-) diff --git a/include/maat.h b/include/maat.h index 1167cd5..fdc07de 100644 --- a/include/maat.h +++ b/include/maat.h @@ -308,6 +308,13 @@ void maat_state_reset(struct maat_state *state); void maat_state_free(struct maat_state *state); +/** + * @param rule_uuids: input rule_uuid array, and also store the result of sorted rule uuids + * + * @retval count of sorted rule_uuids +*/ +size_t maat_state_sort_rules(struct maat *maat_inst, const char *table_name, uuid_t *rule_uuids, uuid_t *sorted_rule_uuids, size_t n_rule_uuids); + int maat_state_set_scan_rule_table(struct maat_state *state, const char *rule_table_name); int maat_state_get_hit_paths(struct maat_state *state, struct maat_hit_path *path_array, diff --git a/src/inc_internal/maat_rule.h b/src/inc_internal/maat_rule.h index ca2e9e5..7f818cc 100644 --- a/src/inc_internal/maat_rule.h +++ b/src/inc_internal/maat_rule.h @@ -72,6 +72,8 @@ int rule_compile_state_update(struct maat_state *maat_state, struct maat *maat_i const char *field_name, int custom_rule_tbl_id, int Nth_scan, struct maat_item *hit_items, size_t n_hit_item); +size_t rule_compile_state_sort_rules(struct rule_runtime *rule_rt, uuid_t *rule_uuids, uuid_t *sorted_rule_uuids, size_t n_rule_uuids); + void rule_compile_state_clear_last_hit_object(struct rule_compile_state *rule_state); void rule_compile_state_not_logic_update(struct rule_compile_state *rule_compile_state, diff --git a/src/maat_api.c b/src/maat_api.c index 45fe377..ec78eee 100644 --- a/src/maat_api.c +++ b/src/maat_api.c @@ -1964,6 +1964,27 @@ void maat_state_free(struct maat_state *state) thread_id, sizeof(struct maat_state)); } +size_t maat_state_sort_rules(struct maat *maat_inst, const char *table_name, uuid_t *rule_uuids, uuid_t *sorted_rule_uuids, size_t n_rule_uuids) +{ + if (NULL == table_name || NULL == rule_uuids || 0 == n_rule_uuids) { + return 0; + } + + int rule_table_id = table_manager_get_table_id(maat_inst->tbl_mgr, table_name); + + if (rule_table_id < 0) { + return 0; + } + + void *rule_rt = table_manager_get_runtime(maat_inst->tbl_mgr, + rule_table_id); + if (NULL == rule_rt) { + return 0; + } + + return rule_compile_state_sort_rules(rule_rt, rule_uuids, sorted_rule_uuids, n_rule_uuids); +} + int maat_state_set_scan_rule_table(struct maat_state *state, const char *rule_table_name) { if (NULL == state) { diff --git a/src/maat_config_monitor.c b/src/maat_config_monitor.c index a28bfaf..88c9999 100644 --- a/src/maat_config_monitor.c +++ b/src/maat_config_monitor.c @@ -373,6 +373,11 @@ void convert_maat_json_rule(cJSON **json_root, unsigned char *json_buff) */ cJSON *tmp_rule = NULL; cJSON_ArrayForEach(tmp_rule, rules) { + cJSON *priority_obj = cJSON_GetObjectItem(tmp_rule, "priority"); + if (priority_obj == NULL) { + cJSON_AddNumberToObject(tmp_rule, "priority", 1000); + } + cJSON *tmp_and_condition = NULL; cJSON *condition_array = cJSON_GetObjectItem(tmp_rule, "and_conditions"); cJSON_ArrayForEach(tmp_and_condition, condition_array) { diff --git a/src/maat_rule.c b/src/maat_rule.c index 471b80d..aed1a0b 100644 --- a/src/maat_rule.c +++ b/src/maat_rule.c @@ -43,6 +43,7 @@ struct rule_schema { struct rule_item { int condition_num; + int priority; uuid_t rule_uuid; char *table_line; size_t table_line_len; @@ -107,6 +108,7 @@ struct rule_condition { struct rule_sort_para { int condition_num; + int priority; uuid_t rule_uuid; }; @@ -114,6 +116,7 @@ struct rule_sort_para { struct maat_rule { uint32_t magic_num; int condition_num; + int priority; int table_id; uuid_t rule_uuid; void *user_data; // rule_item @@ -250,6 +253,15 @@ static struct maat_rule *maat_rule_new(struct rule_runtime *rule_rt, struct rule rule->magic_num = MAAT_RULE_MAGIC; uuid_copy(rule->rule_uuid, rule_uuid); + tmp_obj = cJSON_GetObjectItem(table_json, "priority"); + if (tmp_obj == NULL || tmp_obj->type != cJSON_Number) { + log_fatal(logger, MODULE_RULE, + "[%s:%d] table: <%s> has no priority or not number format", + __FUNCTION__, __LINE__, table_name); + goto error; + } + rule->priority = tmp_obj->valueint; + for(int i = 0; i < MAX_ITEMS_PER_BOOL_EXPR; i++) { utarray_new(rule->conditions[i].literals, &ut_condition_literal_icd); rule->conditions[i].in_use = 0; @@ -343,6 +355,7 @@ static struct maat_rule *maat_rule_new(struct rule_runtime *rule_rt, struct rule } rule_item->condition_num = rule->condition_num; + rule_item->priority = rule->priority; rule->user_data = rule_item; if (table_json) { @@ -1024,6 +1037,43 @@ void rule_compile_state_free(struct rule_compile_state *rule_compile_state, thread_id, free_bytes); } +static int compare_rule(const void *a, const void *b) +{ + const struct maat_rule *ra = *(const struct maat_rule **)a; + const struct maat_rule *rb = *(const struct maat_rule **)b; + + if (ra->priority != rb->priority) { + return ra->priority - rb->priority; + } else if (ra->condition_num != rb->condition_num) { + return (rb->condition_num - ra->condition_num); + } else { + return uuid_compare(rb->rule_uuid, ra->rule_uuid); + } +} + +size_t rule_compile_state_sort_rules(struct rule_runtime *rule_rt, uuid_t *rule_uuids, uuid_t *sorted_rule_uuids, size_t n_rule_uuids) +{ + struct maat_rule *rules[n_rule_uuids]; + size_t rule_cnt = 0; + for (size_t i = 0; i < n_rule_uuids; i++) { + struct maat_rule *tmp_rule = rcu_hash_find(rule_rt->cfg_hash, (const char*)(rule_uuids[i]), sizeof(uuid_t)); + if (NULL == tmp_rule) { + continue; + } + + rules[rule_cnt] = tmp_rule; + rule_cnt++; + } + + qsort(rules, rule_cnt, sizeof(struct maat_rule *), compare_rule); + + for (size_t i = 0; i < rule_cnt; i++) { + uuid_copy(sorted_rule_uuids[i], rules[i]->rule_uuid); + } + + return rule_cnt; +} + static void rule_compile_state_add_internal_hit_path(struct rule_compile_state *rule_compile_state, uuid_t item_uuid, uuid_t object_uuid, @@ -1687,8 +1737,10 @@ static int rule_sort_para_compare(const struct rule_sort_para *a, const struct rule_sort_para *b) { //If rule rule's execute sequences are not specified or equal. - if (a->condition_num != b->condition_num) { - return (a->condition_num - b->condition_num); + if (a->priority != b->priority) { + return a->priority - b->priority; + } else if (a->condition_num != b->condition_num) { + return (b->condition_num - a->condition_num); } else { return uuid_compare(b->rule_uuid, a->rule_uuid); } @@ -1699,6 +1751,7 @@ static void rule_sort_para_set(struct rule_sort_para *para, { uuid_copy(para->rule_uuid, item->rule_uuid); para->condition_num = item->condition_num; + para->priority = item->priority; } static int compare_rule_item(const void *a, const void *b) diff --git a/test/maat_framework_gtest.cpp b/test/maat_framework_gtest.cpp index 4325835..23af5fc 100644 --- a/test/maat_framework_gtest.cpp +++ b/test/maat_framework_gtest.cpp @@ -950,9 +950,9 @@ TEST_P(StringScan, PrefixAndSuffix) { EXPECT_EQ(n_hit_result, 2); char uuid_str[UUID_STR_LEN] = {0}; uuid_unparse(results[0], uuid_str); - EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000151"); - uuid_unparse(results[1], uuid_str); EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000152"); + uuid_unparse(results[1], uuid_str); + EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000151"); ret = maat_scan_not_logic(maat_inst, mail_addr_table_name, mail_addr_field_name, results, ARRAY_SIZE, &n_hit_result, state); @@ -5278,14 +5278,14 @@ TEST_F(Policy, EvaluationOrder) { EXPECT_EQ(n_hit_result, 3); char uuid_str[UUID_STR_LEN] = {0}; uuid_unparse(results[0], uuid_str); - EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000166"); - - uuid_unparse(results[1], uuid_str); EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000168"); - uuid_unparse(results[2], uuid_str); + uuid_unparse(results[1], uuid_str); EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000167"); + uuid_unparse(results[2], uuid_str); + EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000166"); + struct maat_hit_path hit_path[128]; memset(hit_path, 0, sizeof(hit_path)); size_t n_hit_path = maat_state_get_hit_paths(state, hit_path, 128); @@ -5369,6 +5369,23 @@ TEST_F(Policy, EvaluationOrder) { &n_hit_result, state); EXPECT_EQ(ret, MAAT_SCAN_OK); + uuid_parse("00000000-0000-0000-0000-000000000166", results[0]); + uuid_parse("00000000-0000-0000-0000-000000000168", results[1]); + uuid_parse("00000000-0000-0000-0000-000000000167", results[2]); + uuid_parse("00000000-0000-0000-0000-000000000165", results[3]); + uuid_t sorted_results[4]; + ret = maat_state_sort_rules(maat_inst, "RULE_CONJUNCTION", results, sorted_results, 4); + EXPECT_EQ(ret, 4); + + uuid_unparse(sorted_results[0], uuid_str); + EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000165"); + uuid_unparse(sorted_results[1], uuid_str); + EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000168"); + uuid_unparse(sorted_results[2], uuid_str); + EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000167"); + uuid_unparse(sorted_results[3], uuid_str); + EXPECT_STREQ(uuid_str, "00000000-0000-0000-0000-000000000166"); + maat_state_free(state); } diff --git a/test/maat_json.json b/test/maat_json.json index f159902..51292e9 100644 --- a/test/maat_json.json +++ b/test/maat_json.json @@ -1970,7 +1970,7 @@ "do_log": 1, "action_parameter": "EvaluationOrder", "is_valid": "yes", - "evaluation_order": "2.111", + "priority": 1, "and_conditions": [ { "field_name": "HTTP_URL", @@ -2020,7 +2020,7 @@ "do_log": 1, "action_parameter": "EvaluationOrder", "is_valid": "yes", - "evaluation_order": "100.233", + "priority": 2, "and_conditions": [ { "field_name": "HTTP_URL", @@ -2051,7 +2051,7 @@ "do_log": 1, "action_parameter": "EvaluationOrder", "is_valid": "yes", - "evaluation_order": "300.999", + "priority": 2, "and_conditions": [ { "field_name": "HTTP_URL", @@ -2077,7 +2077,7 @@ "do_log": 1, "action_parameter": "EvaluationOrder", "is_valid": "yes", - "evaluation_order": "0", + "priority": 2, "and_conditions": [ { "field_name": "HTTP_URL", diff --git a/test/test_utils.cpp b/test/test_utils.cpp index 63cbb87..135b50d 100644 --- a/test/test_utils.cpp +++ b/test/test_utils.cpp @@ -177,6 +177,8 @@ int rule_table_set_line(struct maat *maat_inst, const char *table_name, cJSON_AddStringToObject(json_root, "action_parameter", action_para_str); } + cJSON_AddNumberToObject(json_root, "priority", 1000);//TODO: support config priority + char *json_str = cJSON_PrintUnformatted(json_root); struct maat_cmd_line line_rule;