fix(app_actions): enforce PPM_SC_SCHED_PROCESS_EXIT for base_syscalls.custom_set

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
This commit is contained in:
Melissa Kilby 2023-03-27 03:29:56 +00:00 committed by poiana
parent 692abf71eb
commit e360175c15
2 changed files with 20 additions and 16 deletions

View File

@ -47,7 +47,7 @@ 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=connect or evt.type=accept or evt.type=accept4 or evt.type=umount2",
"evt.type in (open, ptrace, mmap, execve, read, container)",
"evt.type in (open, execve, mprotect) and not evt.type=mprotect"};
@ -99,7 +99,7 @@ TEST(ConfigureInterestingSets, engine_codes_syscalls_set)
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"}));
"connect", "accept", "accept4", "umount2", "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
@ -107,7 +107,7 @@ TEST(ConfigureInterestingSets, engine_codes_syscalls_set)
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", "accept4", "open", "ptrace", "mmap", "execve", "read"}));
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read"}));
}
TEST(ConfigureInterestingSets, preconditions_postconditions)
@ -158,7 +158,7 @@ TEST(ConfigureInterestingSets, engine_codes_nonsyscalls_set)
// 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
"connect", "accept", "accept4", "umount2", "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);
@ -166,7 +166,7 @@ TEST(ConfigureInterestingSets, engine_codes_nonsyscalls_set)
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", "accept4", "open", "ptrace", "mmap", "execve", "read",
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read",
"syncfs", "fanotify_init", // from generic event filters
}));
}
@ -189,7 +189,7 @@ TEST(ConfigureInterestingSets, selection_not_allevents)
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
"connect", "accept", "accept4", "umount2", "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)
});
@ -232,7 +232,7 @@ TEST(ConfigureInterestingSets, selection_allevents)
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
"connect", "accept", "accept4", "umount2", "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)
});
@ -263,7 +263,7 @@ TEST(ConfigureInterestingSets, selection_generic_evts)
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
"connect", "accept", "accept4", "umount2", "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)
@ -285,7 +285,7 @@ TEST(ConfigureInterestingSets, selection_custom_base_set)
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"};
s.config->m_base_syscalls_custom_set = {"syncfs", "!accept"};
auto result = falco::app::actions::configure_interesting_sets(s);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
@ -297,12 +297,12 @@ TEST(ConfigureInterestingSets, selection_custom_base_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"
"connect", "open", "ptrace", "mmap", "execve", "read", "syncfs", "sched_process_exit"
});
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"};
s.config->m_base_syscalls_custom_set = {"syncfs", "accept", "!accept"};
result = falco::app::actions::configure_interesting_sets(s);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
@ -312,19 +312,19 @@ TEST(ConfigureInterestingSets, selection_custom_base_set)
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
// non-empty custom base set (only positive)
s.config->m_base_syscalls = {"syncfs"};
s.config->m_base_syscalls_custom_set = {"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"
"connect", "accept", "open", "ptrace", "mmap", "execve", "read", "syncfs", "sched_process_exit"
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
// non-empty custom base set (only negative)
s.config->m_base_syscalls = {"!accept"};
s.config->m_base_syscalls_custom_set = {"!accept"};
result = falco::app::actions::configure_interesting_sets(s);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
@ -338,7 +338,7 @@ TEST(ConfigureInterestingSets, selection_custom_base_set)
// non-empty custom base set (positive, without -A)
s.options.all_events = false;
s.config->m_base_syscalls = {"read"};
s.config->m_base_syscalls_custom_set = {"read"};
result = falco::app::actions::configure_interesting_sets(s);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
@ -346,7 +346,7 @@ TEST(ConfigureInterestingSets, selection_custom_base_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 precedence
"connect", "accept", "open", "ptrace", "mmap", "execve",
"connect", "accept", "open", "ptrace", "mmap", "execve", "sched_process_exit"
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
}

View File

@ -107,6 +107,10 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set<p
{
std::cerr << "Invalid (positive) syscall names: warning (base_syscalls override): " + concat_set_in_order(invalid_positive_sc_set_names) << std::endl;
}
/* Hidden safety enforcement for `base_syscalls.custom_set` user input override option -> sched_process_exit trace point activation
* (procexit event) is necessary for continuous state engine cleanup, else memory would grow rapidly and linearly over time. */
base_sc_set.insert(PPM_SC_SCHED_PROCESS_EXIT);
}
// selected events are the union of the rules events set and the