add api maat_state_sort_rules to sort rule_uuid by order: 1.priority 2.condition_num 3.uuid
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user