mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-18 07:51:12 +00:00
test(unit_test): adapt and grow tests on configure_intertesting_sets
The test now take in accoint pre/post-conditions of the actions, usage of the -A option, and the newly-introduced base_syscall user configuration. This also makes sure that the event selection properly handles generic events and options/configs precedence. Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com> Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
@@ -15,137 +15,337 @@ limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
#include "falco_utils.h"
|
||||
#include "evttype_index_ruleset.h"
|
||||
#include <filter/parser.h>
|
||||
#include <falco_engine.h>
|
||||
|
||||
#include <falco/app/state.h>
|
||||
#include <falco/app/actions/actions.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace libsinsp::filter;
|
||||
using namespace falco::utils;
|
||||
|
||||
// todo(jasondellaluce): these tests do not test the actual
|
||||
// `configure_interesting_sets` action, but instead reproduces its logic
|
||||
// and asserts the pre and post conditions. For now, this is the only thing
|
||||
// we can do due to the falco_engine class lacking adequate accessor methods.
|
||||
// In the future, we need to refactor this.
|
||||
|
||||
static std::shared_ptr<gen_event_filter_factory> create_factory()
|
||||
{
|
||||
std::shared_ptr<gen_event_filter_factory> ret(new sinsp_filter_factory(NULL));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(
|
||||
std::shared_ptr<gen_event_filter_factory> f, std::string fltstr)
|
||||
{
|
||||
libsinsp::filter::parser parser(fltstr);
|
||||
std::shared_ptr<libsinsp::filter::ast::expr> ret(parser.parse());
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::shared_ptr<gen_event_filter> create_filter(
|
||||
std::shared_ptr<gen_event_filter_factory> f,
|
||||
std::shared_ptr<libsinsp::filter::ast::expr> ast)
|
||||
{
|
||||
sinsp_filter_compiler compiler(f, ast.get());
|
||||
std::shared_ptr<gen_event_filter> filter(compiler.compile());
|
||||
return filter;
|
||||
}
|
||||
|
||||
static std::shared_ptr<filter_ruleset> create_ruleset(
|
||||
std::shared_ptr<gen_event_filter_factory> f)
|
||||
{
|
||||
std::shared_ptr<filter_ruleset> ret(new evttype_index_ruleset(f));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static std::shared_ptr<filter_ruleset> get_test_rulesets(const std::unordered_set<std::string>& fltstrs)
|
||||
{
|
||||
auto f = create_factory();
|
||||
auto r = create_ruleset(f);
|
||||
|
||||
for (const auto &fltstr : fltstrs)
|
||||
{
|
||||
auto rule_ast = create_ast(f, fltstr);
|
||||
auto rule_filter = create_filter(f, rule_ast);
|
||||
falco_rule rule;
|
||||
rule.name = fltstr;
|
||||
rule.source = falco_common::syscall_source;
|
||||
r->add(rule, rule_filter, rule_ast);
|
||||
r->enable(fltstr, true, 0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static libsinsp::events::set<ppm_event_code> extract_rules_event_set(std::shared_ptr<filter_ruleset>& r)
|
||||
{
|
||||
std::set<uint16_t> tmp;
|
||||
libsinsp::events::set<ppm_event_code> events;
|
||||
auto source = falco_common::syscall_source;
|
||||
r->enabled_evttypes(tmp, 0);
|
||||
for (const auto &ev : tmp)
|
||||
{
|
||||
events.insert((ppm_event_code) ev);
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
#define ASSERT_NAMES_EQ(a, b) { \
|
||||
ASSERT_EQ(std::set<std::string>(a.begin(), a.end()), std::set<std::string>(b.begin(), b.end())); \
|
||||
ASSERT_EQ(_order(a).size(), _order(b).size()); \
|
||||
ASSERT_EQ(_order(a), _order(b)); \
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, configure_interesting_sets)
|
||||
#define ASSERT_NAMES_CONTAIN(a, b) { \
|
||||
ASSERT_NAMES_EQ(unordered_set_intersection(a, b), b); \
|
||||
}
|
||||
|
||||
#define ASSERT_NAMES_NOCONTAIN(a, b) { \
|
||||
ASSERT_NAMES_EQ(unordered_set_intersection(a, b), strset_t({})); \
|
||||
}
|
||||
|
||||
using strset_t = std::unordered_set<std::string>;
|
||||
|
||||
static std::set<std::string> _order(const strset_t& s)
|
||||
{
|
||||
/* Test scenario:
|
||||
* Include one I/O syscall
|
||||
* Include one non syscall event type
|
||||
* Include one exclusionary syscall definition test ruleset
|
||||
* Check sinsp enforced syscalls dependencies for:
|
||||
* - spawned processes
|
||||
* - network related syscalls
|
||||
* Check that non syscalls events are enforced */
|
||||
std::unordered_set<std::string> fltstrs = {
|
||||
"(evt.type=connect or evt.type=accept)",
|
||||
"evt.type in (open, ptrace, mmap, execve, read, container)",
|
||||
"evt.type in (open, execve, mprotect) and not evt.type=mprotect"};
|
||||
std::unordered_set<std::string> expected_syscalls_names = {
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read", "container"};
|
||||
std::unordered_set<std::string> base_syscalls_sinsp_state_spawned_process = {"clone", "clone3", "fork", "vfork"};
|
||||
std::unordered_set<std::string> base_syscalls_sinsp_state_network = {"socket", "bind", "close"};
|
||||
std::unordered_set<std::string> base_events = {"procexit", "container"};
|
||||
|
||||
auto r = get_test_rulesets(fltstrs);
|
||||
ASSERT_EQ(r->enabled_count(0), fltstrs.size());
|
||||
|
||||
/* Test if event types names were extracted from each rule in test ruleset. */
|
||||
auto rules_event_set = extract_rules_event_set(r);
|
||||
auto rules_names = libsinsp::events::event_set_to_names(rules_event_set);
|
||||
ASSERT_NAMES_EQ(rules_names, expected_syscalls_names);
|
||||
|
||||
/* Enforce sinsp state syscalls and test if ruleset syscalls are in final set of syscalls. */
|
||||
auto base_event_set = libsinsp::events::sinsp_state_event_set();
|
||||
auto selected_event_set = base_event_set.merge(rules_event_set);
|
||||
auto selected_names = libsinsp::events::event_set_to_names(selected_event_set);
|
||||
auto intersection = unordered_set_intersection(selected_names, expected_syscalls_names);
|
||||
ASSERT_NAMES_EQ(intersection, expected_syscalls_names);
|
||||
|
||||
/* Test if sinsp state enforcement activated required syscalls for test ruleset. */
|
||||
intersection = unordered_set_intersection(selected_names, base_syscalls_sinsp_state_spawned_process);
|
||||
ASSERT_NAMES_EQ(intersection, base_syscalls_sinsp_state_spawned_process);
|
||||
intersection = unordered_set_intersection(selected_names, base_syscalls_sinsp_state_network);
|
||||
ASSERT_NAMES_EQ(intersection, base_syscalls_sinsp_state_network);
|
||||
|
||||
/* Test that no I/O syscalls are in the final set. */
|
||||
auto io_event_set = libsinsp::events::sc_set_to_event_set(libsinsp::events::io_sc_set());
|
||||
auto erased_event_set = selected_event_set.intersect(io_event_set);
|
||||
selected_event_set = selected_event_set.diff(io_event_set);
|
||||
selected_names = libsinsp::events::event_set_to_names(selected_event_set);
|
||||
intersection = unordered_set_intersection(selected_names, libsinsp::events::event_set_to_names(erased_event_set));
|
||||
ASSERT_EQ(intersection.size(), 0);
|
||||
|
||||
/* Test that enforced non syscalls events are in final events set. */
|
||||
intersection = unordered_set_intersection(selected_names, base_events);
|
||||
ASSERT_NAMES_EQ(intersection, base_events);
|
||||
|
||||
return std::set<std::string>(s.begin(), s.end());
|
||||
}
|
||||
|
||||
static std::string s_sample_ruleset = "sample-ruleset";
|
||||
|
||||
static std::string s_sample_source = falco_common::syscall_source;
|
||||
|
||||
static strset_t s_sample_filters = {
|
||||
"evt.type=connect or evt.type=accept",
|
||||
"evt.type in (open, ptrace, mmap, execve, read, container)",
|
||||
"evt.type in (open, execve, mprotect) and not evt.type=mprotect"};
|
||||
|
||||
static strset_t s_sample_generic_filters = {
|
||||
"evt.type=syncfs or evt.type=fanotify_init"};
|
||||
|
||||
static strset_t s_sample_nonsyscall_filters = {
|
||||
"evt.type in (procexit, switch, pluginevent, container)"};
|
||||
|
||||
|
||||
// todo(jasondellaluce): once we have deeper and more modular
|
||||
// control on the falco engine, make this a little nicer
|
||||
static std::shared_ptr<falco_engine> mock_engine_from_filters(const strset_t& filters)
|
||||
{
|
||||
// craft a fake ruleset with the given filters
|
||||
int n_rules = 0;
|
||||
std::string dummy_rules;
|
||||
falco::load_result::rules_contents_t content = {{"dummy_rules.yaml", dummy_rules}};
|
||||
for (const auto& f : filters)
|
||||
{
|
||||
n_rules++;
|
||||
dummy_rules +=
|
||||
"- rule: Dummy Rule " + std::to_string(n_rules) + "\n"
|
||||
+ " output: Dummy Output " + std::to_string(n_rules) + "\n"
|
||||
+ " condition: " + f + "\n"
|
||||
+ " desc: Dummy Desc " + std::to_string(n_rules) + "\n"
|
||||
+ " priority: CRITICAL\n\n";
|
||||
}
|
||||
|
||||
// create a falco engine and load the ruleset
|
||||
std::shared_ptr<falco_engine> res(new falco_engine());
|
||||
auto filter_factory = std::shared_ptr<gen_event_filter_factory>(
|
||||
new sinsp_filter_factory(nullptr));
|
||||
auto formatter_factory = std::shared_ptr<gen_event_formatter_factory>(
|
||||
new sinsp_evt_formatter_factory(nullptr));
|
||||
res->add_source(s_sample_source, filter_factory, formatter_factory);
|
||||
res->load_rules(dummy_rules, "dummy_rules.yaml");
|
||||
res->enable_rule("", true, s_sample_ruleset);
|
||||
return res;
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, engine_codes_syscalls_set)
|
||||
{
|
||||
auto engine = mock_engine_from_filters(s_sample_filters);
|
||||
auto enabled_count = engine->num_rules_for_ruleset(s_sample_ruleset);
|
||||
ASSERT_EQ(enabled_count, s_sample_filters.size());
|
||||
|
||||
// test if event code names were extracted from each rule in test ruleset.
|
||||
auto rules_event_set = engine->event_codes_for_ruleset(s_sample_source);
|
||||
auto rules_event_names = libsinsp::events::event_set_to_names(rules_event_set);
|
||||
ASSERT_NAMES_EQ(rules_event_names, strset_t({
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read", "container"}));
|
||||
|
||||
// test if sc code names were extracted from each rule in test ruleset.
|
||||
// note, this is not supposed to contain "container", as that's an event
|
||||
// not mapped through the ppm_sc_code enumerative.
|
||||
auto rules_sc_set = engine->sc_codes_for_ruleset(s_sample_source);
|
||||
auto rules_sc_names = libsinsp::events::sc_set_to_names(rules_sc_set);
|
||||
ASSERT_NAMES_EQ(rules_sc_names, strset_t({
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read"}));
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, preconditions_postconditions)
|
||||
{
|
||||
falco::app::state s;
|
||||
auto mock_engine = mock_engine_from_filters(s_sample_filters);
|
||||
|
||||
s.engine = mock_engine;
|
||||
s.config = nullptr;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_FALSE(result.success);
|
||||
ASSERT_NE(result.errstr, "");
|
||||
|
||||
s.engine = nullptr;
|
||||
s.config = std::make_shared<falco_configuration>();
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_FALSE(result.success);
|
||||
ASSERT_NE(result.errstr, "");
|
||||
|
||||
s.engine = mock_engine;
|
||||
s.config = std::make_shared<falco_configuration>();
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
auto prev_selection_size = s.selected_sc_set.size();
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
ASSERT_EQ(prev_selection_size, s.selected_sc_set.size());
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, engine_codes_nonsyscalls_set)
|
||||
{
|
||||
auto filters = s_sample_filters;
|
||||
filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end());
|
||||
filters.insert(s_sample_nonsyscall_filters.begin(), s_sample_nonsyscall_filters.end());
|
||||
|
||||
auto engine = mock_engine_from_filters(filters);
|
||||
auto enabled_count = engine->num_rules_for_ruleset(s_sample_ruleset);
|
||||
ASSERT_EQ(enabled_count, filters.size());
|
||||
|
||||
auto rules_event_set = engine->event_codes_for_ruleset(s_sample_source);
|
||||
auto rules_event_names = libsinsp::events::event_set_to_names(rules_event_set);
|
||||
// note: including even one generic event will cause PPME_GENERIC_E to be
|
||||
// inluded in the ruleset's event codes. As such, when translating to names,
|
||||
// PPME_GENERIC_E will cause all names of generic events to be added!
|
||||
// This is a good example of information loss from ppm_event_code <-> ppm_sc_code.
|
||||
auto generic_names = libsinsp::events::event_set_to_names({ppm_event_code::PPME_GENERIC_E});
|
||||
auto expected_names = strset_t({
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read", "container", // ruleset
|
||||
"procexit", "switch", "pluginevent"}); // from non-syscall event filters
|
||||
expected_names.insert(generic_names.begin(), generic_names.end());
|
||||
ASSERT_NAMES_EQ(rules_event_names, expected_names);
|
||||
|
||||
auto rules_sc_set = engine->sc_codes_for_ruleset(s_sample_source);
|
||||
auto rules_sc_names = libsinsp::events::sc_set_to_names(rules_sc_set);
|
||||
ASSERT_NAMES_EQ(rules_sc_names, strset_t({
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read",
|
||||
"syncfs", "fanotify_init", // from generic event filters
|
||||
}));
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_not_allevents)
|
||||
{
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s.options.all_events = false;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
// todo(jasondellaluce): once we have deeper control on falco's outputs,
|
||||
// also check if a warning has been printed in stderr
|
||||
|
||||
// check that the final selected set is the one expected
|
||||
ASSERT_NE(s.selected_sc_set.size(), 0);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: we expect the "read" syscall to have been erased
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", // from ruleset
|
||||
"clone", "clone3", "fork", "vfork", // from sinsp state set (spawned_process)
|
||||
"socket", "bind", "close" // from sinsp state set (network, files)
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// check that all IO syscalls have been erased from the selection
|
||||
auto io_set = libsinsp::events::io_sc_set();
|
||||
auto erased_sc_names = libsinsp::events::sc_set_to_names(io_set);
|
||||
ASSERT_NAMES_NOCONTAIN(selected_sc_names, erased_sc_names);
|
||||
|
||||
// check that final selected set is exactly sinsp state + ruleset
|
||||
auto rule_set = s.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
auto state_set = libsinsp::events::sinsp_state_sc_set();
|
||||
for (const auto &erased : io_set)
|
||||
{
|
||||
rule_set.remove(erased);
|
||||
state_set.remove(erased);
|
||||
}
|
||||
auto union_set = state_set.merge(rule_set);
|
||||
auto inter_set = state_set.intersect(rule_set);
|
||||
ASSERT_EQ(s.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
|
||||
ASSERT_EQ(s.selected_sc_set, union_set);
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_allevents)
|
||||
{
|
||||
// run app action with fake engine and with the `-A` option
|
||||
falco::app::state s;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
s.options.all_events = true;
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
// todo(jasondellaluce): once we have deeper control on falco's outputs,
|
||||
// also check if a warning has not been printed in stderr
|
||||
|
||||
// check that the final selected set is the one expected
|
||||
ASSERT_NE(s.selected_sc_set.size(), 0);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: we expect the "read" syscall to not be erased
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read", // from ruleset
|
||||
"clone", "clone3", "fork", "vfork", // from sinsp state set (spawned_process)
|
||||
"socket", "bind", "close" // from sinsp state set (network, files)
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// check that final selected set is exactly sinsp state + ruleset
|
||||
auto rule_set = s.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
|
||||
auto state_set = libsinsp::events::sinsp_state_sc_set();
|
||||
auto union_set = state_set.merge(rule_set);
|
||||
auto inter_set = state_set.intersect(rule_set);
|
||||
ASSERT_EQ(s.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
|
||||
ASSERT_EQ(s.selected_sc_set, union_set);
|
||||
}
|
||||
|
||||
TEST(ConfigureInterestingSets, selection_generic_evts)
|
||||
{
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
auto filters = s_sample_filters;
|
||||
filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end());
|
||||
s.engine = mock_engine_from_filters(filters);
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
|
||||
// check that the final selected set is the one expected
|
||||
ASSERT_NE(s.selected_sc_set.size(), 0);
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: we expect the "read" syscall to not be erased
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", // from ruleset
|
||||
"syncfs", "fanotify_init", // from ruleset (generic events)
|
||||
"clone", "clone3", "fork", "vfork", // from sinsp state set (spawned_process)
|
||||
"socket", "bind", "close" // from sinsp state set (network, files)
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
}
|
||||
|
||||
// expected combinations precedence:
|
||||
// - final selected set is the union of rules events and base events
|
||||
// (either default or custom positive set)
|
||||
// - events in the custom negative set are removed from the selected set
|
||||
// - if `-A` is not set, events from the IO set are removed from the selected set
|
||||
TEST(ConfigureInterestingSets, selection_custom_base_set)
|
||||
{
|
||||
// run app action with fake engine and without the `-A` option
|
||||
falco::app::state s;
|
||||
s.options.all_events = true;
|
||||
s.engine = mock_engine_from_filters(s_sample_filters);
|
||||
auto default_base_set = libsinsp::events::sinsp_state_sc_set();
|
||||
|
||||
// non-empty custom base set (both positive and negative)
|
||||
s.config->m_base_syscalls = {"syncfs", "!accept"};
|
||||
auto result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
auto selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
auto expected_sc_names = strset_t({
|
||||
// note: `syncfs` has been added due to the custom base set, and `accept`
|
||||
// has been remove due to the negative base set.
|
||||
// note: `read` is not ignored due to the "-A" option being set.
|
||||
// note: `accept` is not included even though it is matched by the rules,
|
||||
// which means that the custom negation base set has precedence over the
|
||||
// final selection set as a whole
|
||||
"connect", "open", "ptrace", "mmap", "execve", "read", "syncfs"
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (both positive and negative with collision)
|
||||
s.config->m_base_syscalls = {"syncfs", "accept", "!accept"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
// note: in case of collision, negation has priority, so the expected
|
||||
// names are the same as the case above
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (only positive)
|
||||
s.config->m_base_syscalls = {"syncfs"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
expected_sc_names = strset_t({
|
||||
// note: accept is not negated anymore
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve", "read", "syncfs"
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (only negative)
|
||||
s.config->m_base_syscalls = {"!accept"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
expected_sc_names = unordered_set_union(
|
||||
libsinsp::events::sc_set_to_names(default_base_set),
|
||||
strset_t({ "connect", "open", "ptrace", "mmap", "execve", "read"}));
|
||||
expected_sc_names.erase("accept");
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
|
||||
// non-empty custom base set (positive, without -A)
|
||||
s.options.all_events = false;
|
||||
s.config->m_base_syscalls = {"read"};
|
||||
result = falco::app::actions::configure_interesting_sets(s);
|
||||
ASSERT_TRUE(result.success);
|
||||
ASSERT_EQ(result.errstr, "");
|
||||
selected_sc_names = libsinsp::events::sc_set_to_names(s.selected_sc_set);
|
||||
expected_sc_names = strset_t({
|
||||
// note: read is both part of the custom base set and the rules set,
|
||||
// but we expect the unset -A option to take precence
|
||||
"connect", "accept", "open", "ptrace", "mmap", "execve",
|
||||
});
|
||||
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
|
||||
}
|
||||
|
Reference in New Issue
Block a user