tests: add some new tests on override replace

Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
This commit is contained in:
Andrea Terzolo
2024-01-10 15:36:38 +01:00
committed by poiana
parent 8ebdbe3e6f
commit ee78c862ad
3 changed files with 84 additions and 10 deletions

View File

@@ -374,6 +374,34 @@ TEST_F(engine_loader_test, macro_override_append_before_macro_definition)
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_MACRO)); ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_MACRO));
} }
TEST_F(engine_loader_test, macro_override_replace_before_macro_definition)
{
std::string rules_content = R"END(
- macro: open_simple
condition: or evt.type = openat2
override:
condition: replace
- macro: open_simple
condition: evt.type in (open,openat)
- rule: test_rule
desc: simple rule
condition: open_simple
output: command=%proc.cmdline
priority: INFO
)END";
// The first override defines a macro that is overridden by the second macro definition
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
std::string rule_name = "test_rule";
auto rule_description = m_engine->describe_rule(&rule_name, {});
ASSERT_EQ(rule_description["rules"][0]["details"]["condition_compiled"].template get<std::string>(),
"evt.type in (open, openat)");
}
TEST_F(engine_loader_test, macro_append_before_macro_definition) TEST_F(engine_loader_test, macro_append_before_macro_definition)
{ {
std::string rules_content = R"END( std::string rules_content = R"END(
@@ -470,7 +498,27 @@ TEST_F(engine_loader_test, rule_override_append_before_rule_definition)
)END"; )END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml")); ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE)); ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_APPEND));
}
TEST_F(engine_loader_test, rule_override_replace_before_rule_definition)
{
std::string rules_content = R"END(
- rule: test_rule
condition: and proc.name = cat
override:
condition: replace
- rule: test_rule
desc: simple rule
condition: evt.type in (open,openat)
output: command=%proc.cmdline
priority: INFO
)END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_REPLACE));
} }
TEST_F(engine_loader_test, rule_append_before_rule_definition) TEST_F(engine_loader_test, rule_append_before_rule_definition)
@@ -489,7 +537,7 @@ TEST_F(engine_loader_test, rule_append_before_rule_definition)
)END"; )END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml")); ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE)); ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_APPEND));
} }
TEST_F(engine_loader_test, rule_override_append_after_rule_definition) TEST_F(engine_loader_test, rule_override_append_after_rule_definition)
@@ -594,6 +642,33 @@ TEST_F(engine_loader_test, list_override_append_before_list_definition)
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_LIST)); ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_LIST));
} }
TEST_F(engine_loader_test, list_override_replace_before_list_definition)
{
std::string rules_content = R"END(
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
override:
items: replace
- list: dev_creation_binaries
items: [blkid]
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
// With override replace we define a first list that then is overridden by the second one.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
std::string rule_name = "test_rule";
auto rule_description = m_engine->describe_rule(&rule_name, {});
ASSERT_EQ(rule_description["rules"][0]["details"]["condition_compiled"].template get<std::string>(),
"(evt.type = execve and proc.name in (blkid))");
}
TEST_F(engine_loader_test, list_append_before_list_definition) TEST_F(engine_loader_test, list_append_before_list_definition)
{ {
std::string rules_content = R"END( std::string rules_content = R"END(

View File

@@ -20,6 +20,7 @@ limitations under the License.
#include "falco_engine.h" #include "falco_engine.h"
#include "rule_loader_collector.h" #include "rule_loader_collector.h"
#include "rule_loading_messages.h"
#define THROW(cond, err, ctx) { if ((cond)) { throw rule_loader::rule_load_exception(falco::load_result::LOAD_ERR_VALIDATE, (err), (ctx)); } } #define THROW(cond, err, ctx) { if ((cond)) { throw rule_loader::rule_load_exception(falco::load_result::LOAD_ERR_VALIDATE, (err), (ctx)); } }
@@ -239,7 +240,7 @@ void rule_loader::collector::append(configuration& cfg, rule_update_info& info)
{ {
auto prev = m_rule_infos.at(info.name); auto prev = m_rule_infos.at(info.name);
THROW(!prev, ERROR_NO_PREVIOUS_RULE, info.ctx); THROW(!prev, ERROR_NO_PREVIOUS_RULE_APPEND, info.ctx);
THROW(!info.has_any_value(), THROW(!info.has_any_value(),
"Appended rule must have exceptions or condition property", "Appended rule must have exceptions or condition property",
// "Appended rule must have at least one field that can be appended to", // TODO replace with this and update testing // "Appended rule must have at least one field that can be appended to", // TODO replace with this and update testing
@@ -322,9 +323,7 @@ void rule_loader::collector::selective_replace(configuration& cfg, rule_update_i
{ {
auto prev = m_rule_infos.at(info.name); auto prev = m_rule_infos.at(info.name);
THROW(!prev, THROW(!prev, ERROR_NO_PREVIOUS_RULE_REPLACE, info.ctx);
"An replace to a rule was requested but no rule by that name already exists",
info.ctx);
THROW(!info.has_any_value(), THROW(!info.has_any_value(),
"The rule must have at least one field that can be replaced", "The rule must have at least one field that can be replaced",
info.ctx); info.ctx);

View File

@@ -1,16 +1,16 @@
#pragma once #pragma once
// Error message used when both 'override' and 'append' keys are specified. // todo: rename putting error at the beginning
#define OVERRIDE_APPEND_ERROR_MESSAGE "Keys 'override' and 'append: true' cannot be used together. Add an 'append' entry (e.g. 'condition: append') under 'override' instead." #define OVERRIDE_APPEND_ERROR_MESSAGE "Keys 'override' and 'append: true' cannot be used together. Add an 'append' entry (e.g. 'condition: append') under 'override' instead."
// Warning message used when 'append' key is used.
#define WARNING_APPEND_MESSAGE "'append' key is deprecated. Add an 'append' entry (e.g. 'condition: append') under 'override' instead." #define WARNING_APPEND_MESSAGE "'append' key is deprecated. Add an 'append' entry (e.g. 'condition: append') under 'override' instead."
// Warning message used when 'enabled' is used without 'override' key.
#define WARNING_ENABLED_MESSAGE "The standalone 'enabled' key usage is deprecated. The correct approach requires also a 'replace' entry under the 'override' key (i.e. 'enabled: replace')." #define WARNING_ENABLED_MESSAGE "The standalone 'enabled' key usage is deprecated. The correct approach requires also a 'replace' entry under the 'override' key (i.e. 'enabled: replace')."
#define ERROR_NO_PREVIOUS_MACRO "Macro uses 'append' or 'override.condition: append' but no macro by that name already exists" #define ERROR_NO_PREVIOUS_MACRO "Macro uses 'append' or 'override.condition: append' but no macro by that name already exists"
#define ERROR_NO_PREVIOUS_LIST "List uses 'append' or 'override.items: append' but no list by that name already exists" #define ERROR_NO_PREVIOUS_LIST "List uses 'append' or 'override.items: append' but no list by that name already exists"
#define ERROR_NO_PREVIOUS_RULE "Rule uses 'append' or 'override.<key>: append' but no rule by that name already exists" #define ERROR_NO_PREVIOUS_RULE_APPEND "Rule uses 'append' or 'override.<key>: append' but no rule by that name already exists"
#define ERROR_NO_PREVIOUS_RULE_REPLACE "An 'override.<key>: replace' to a rule was requested but no rule by that name already exists"