diff --git a/cmake/modules/driver.cmake b/cmake/modules/driver.cmake index c6e6df28680..78d4eb34597 100644 --- a/cmake/modules/driver.cmake +++ b/cmake/modules/driver.cmake @@ -26,8 +26,8 @@ else() # In case you want to test against another driver version (or branch, or commit) just pass the variable - # ie., `cmake -DDRIVER_VERSION=dev ..` if(NOT DRIVER_VERSION) - set(DRIVER_VERSION "e006bf38219d392cd5aeb3c1109e4bdaa9ef1617") - set(DRIVER_CHECKSUM "SHA256=185963f6d658e8963f218ec1d45056b7f6e391d05244f6499aec74807d2190fb") + set(DRIVER_VERSION "2024af2e264e1cd76ec8bc43924f1857937848a8") + set(DRIVER_CHECKSUM "SHA256=af98c4c505882a899eab38a7f7b7cc92cba634d81a110a18c42243214f9ffc5f") endif() # cd /path/to/build && cmake /path/to/source diff --git a/cmake/modules/falcosecurity-libs.cmake b/cmake/modules/falcosecurity-libs.cmake index c116b9af841..8a0bc22ba5d 100644 --- a/cmake/modules/falcosecurity-libs.cmake +++ b/cmake/modules/falcosecurity-libs.cmake @@ -27,8 +27,8 @@ else() # In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable - # ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..` if(NOT FALCOSECURITY_LIBS_VERSION) - set(FALCOSECURITY_LIBS_VERSION "e006bf38219d392cd5aeb3c1109e4bdaa9ef1617") - set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=185963f6d658e8963f218ec1d45056b7f6e391d05244f6499aec74807d2190fb") + set(FALCOSECURITY_LIBS_VERSION "2024af2e264e1cd76ec8bc43924f1857937848a8") + set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=af98c4c505882a899eab38a7f7b7cc92cba634d81a110a18c42243214f9ffc5f") endif() # cd /path/to/build && cmake /path/to/source diff --git a/falco.yaml b/falco.yaml index af3c6129a31..98f363acaea 100644 --- a/falco.yaml +++ b/falco.yaml @@ -451,66 +451,87 @@ metadata_download: watch_freq_sec: 1 -# base_syscalls ! Use with caution ! +# base_syscalls ! Use with caution, read carefully ! # # --- [Description] # -# With this option you are in full control of the total set of syscalls that +# With this option you are in full control of the set of syscalls that # Falco will enable in the kernel for active tracing. -# All syscalls and events from each enabled Falco rule will automatically be activated -# even when choosing this option. This option provides full end user control to specifically -# define a static set of base syscalls that will be activated in addition to the +# All syscalls and events from each enabled Falco rule are activated +# even when choosing this option. This option allows you to define a +# set of base syscalls that will be activated in addition to the # syscalls defined in the rules. # -# When using this option, Falco does not add any other syscalls that may be needed for -# Falco's state engine. The union of all syscalls from the rules (including resolved macros) -# and the ones specified here compose the final set of syscalls that are traced in the kernel. -# This puts the end user in the driver seat, but if not used correctly Falco logs may be -# incomplete or wrong. This option however can be very useful to lower CPU utilization and -# allowing you to tailor Falco to specific environments according to your -# organization's threat model and security posture as well as cost budget. - -# !!! When NOT using this option, Falco defaults to adding a static set of syscalls in addition -# to the rules system calls you need for Falco's state engine build-up and life-cycle management. +# You may ask yourself why do we need to activate syscalls in addition to the rules? +# +# Falco requires a set of syscalls to build up state in userspace. This is because for +# example when spawning a new process or creating a network connection more than one syscall +# is involved. Furthermore, properties of a process during its life time can be modified +# by syscalls. Falco takes care of this by activating more syscalls than the ones defined +# in the rules and by managing a smart process cache table in userspace. +# Processes are purged when a process exits. +# +# Looking back to what this option does, it activates all syscalls from the rules +# (including resolved macros) and the ones specified here. # +# This puts the end user in the driver seat to tell Falco what it needs, but if not used correctly +# Falco logs may be incomplete or wrong or Falco won't work at all. This option however can be +# very useful to lower CPU utilization and allowing you to tailor Falco to specific environments +# according to your organization's threat model and cost budget. +# +# !!! When NOT using this option, Falco defaults to adding a static (more verbose) set of syscalls +# in addition to the rules system calls Falco needs for its state engine build-up and life-cycle management. +# +# `base_syscalls.repair` is an experimental alternative to Falco's default state engine enforcement. +# `base_syscalls.repair` is designed to be the most resourceful option to ensure Falco runs correctly +# while activating a most minimal set of additional syscalls. The recommendations listed in the suggestions +# section is effectively what `base_syscalls.repair` is doing in an automated manner. `base_syscalls.repair` +# can be used with an empty custom set. # # --- [Usage] # # List of system calls names () plus negative ("!") notation supported. # -# base_syscalls: [, , "!"] +# base_syscalls.repair: +# base_syscalls.custom_set: [, , "!"] # # # --- [Suggestions] # -# Here are a few recommendations that may help you to use the full power of this option: +# Here are a few recommendations that may help you. +# Setting `base_syscalls.repair: true` automates these recommendations for you. # # Consider to at minimum add the following syscalls regardless of the syscalls used in the rules. # # [clone, clone3, fork, vfork, execve, execveat, close] # -# This is because some Falco fields you may output for an execve* system call are retrieved -# from the associated "clone", "clone3", "fork", "vfork" syscall when spawning a new process. -# The "close" system call is used to purge file descriptors from Falco's internal -# thread / process cache table and therefore should always be added when you have rules around fds +# This is because some Falco fields for an execve* system call are retrieved +# from the associated `clone`, `clone3`, `fork`, `vfork` syscall when spawning a +# new process. The `close` system call is used to purge file descriptors from Falco's +# internal thread / process cache table and should always be added when you have +# rules around file descriptors. # (e.g. open, openat, openat2, socket, connect, accept, accept4 ... and many more) # # When network syscalls are used in rules we recommend to at minimum set # # [clone, clone3, fork, vfork, execve, execveat, close, socket, bind, getsockopt] # -# It turns out that while you absolutely can log connect or accept* syscalls without the socket -# system call, the log however would not contain the ip tuples. -# For listen and accept* system calls you also need the bind system call. +# It turns out that while you can log `connect` or `accept*` syscalls without the +# socket system call, the log however would not contain the ip tuples. +# For `listen` and `accept*` system calls you also need the `bind` system call. # -# Lastly, if you care about the correct uid, gid or sid, pgid of a process when that process then -# opens a file or makes a network connection or any other action, consider also -# adding the following syscalls: +# Lastly, if you care about the correct `uid`, `gid` or `sid`, `pgid` of a process when the +# running process opens a file or makes a network connection, consider adding the following syscalls: # # setresuid, setsid, setuid, setgid, setpgid, setresgid, setsid, capset, chdir, chroot, fchdir # -# Only exclude syscalls, e.g. "!mprotect" if you need a fast deployment update (overriding rules), -# else rather remove unwanted or not needed syscalls from the Falco rules. +# We recommend to only exclude syscalls, e.g. "!mprotect" if you need a fast deployment update +# (overriding rules), else remove unwanted syscalls from the Falco rules. +# +# Passing `-o "log_level=debug"` to Falco's cmd args during a dry-run will print the +# final set of syscalls to STDOUT. -base_syscalls: [] +base_syscalls: + repair: false + custom_set: [] diff --git a/unit_tests/falco/app/actions/test_configure_interesting_sets.cpp b/unit_tests/falco/app/actions/test_configure_interesting_sets.cpp index af602d2be1e..8688de11802 100644 --- a/unit_tests/falco/app/actions/test_configure_interesting_sets.cpp +++ b/unit_tests/falco/app/actions/test_configure_interesting_sets.cpp @@ -23,7 +23,7 @@ limitations under the License. #include #define ASSERT_NAMES_EQ(a, b) { \ - ASSERT_EQ(_order(a).size(), _order(b).size()); \ + EXPECT_EQ(_order(a).size(), _order(b).size()); \ ASSERT_EQ(_order(a), _order(b)); \ } @@ -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 })); } @@ -185,11 +185,11 @@ TEST(ConfigureInterestingSets, selection_not_allevents) // 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); + ASSERT_GT(s.selected_sc_set.size(), 1); 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) }); @@ -228,11 +228,11 @@ TEST(ConfigureInterestingSets, selection_allevents) // 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); + ASSERT_GT(s.selected_sc_set.size(), 1); 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) }); @@ -251,6 +251,7 @@ TEST(ConfigureInterestingSets, selection_generic_evts) { // run app action with fake engine and without the `-A` option falco::app::state s; + s.options.all_events = false; auto filters = s_sample_filters; filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end()); s.engine = mock_engine_from_filters(filters); @@ -259,16 +260,18 @@ TEST(ConfigureInterestingSets, selection_generic_evts) ASSERT_EQ(result.errstr, ""); // check that the final selected set is the one expected - ASSERT_NE(s.selected_sc_set.size(), 0); + ASSERT_GT(s.selected_sc_set.size(), 1); 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) }); ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names); + auto unexpected_sc_names = libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set()); + ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names); } // expected combinations precedence: @@ -285,7 +288,8 @@ 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_repair = false; + 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,48 +301,51 @@ 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" + // todo(jasondellaluce): add "accept4" once names_to_sc_set is polished on the libs side + "connect", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "sched_process_exit" }); - ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names); + ASSERT_NAMES_EQ(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_repair = false; + 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, ""); 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); + ASSERT_NAMES_EQ(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", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "sched_process_exit" }); - ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names); + ASSERT_NAMES_EQ(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, ""); 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"})); + strset_t({ "connect", "umount2", "open", "ptrace", "mmap", "execve", "read"})); expected_sc_names.erase("accept"); + // todo(jasondellaluce): add "accept4" once names_to_sc_set is polished on the libs side expected_sc_names.erase("accept4"); - ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names); + ASSERT_NAMES_EQ(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"}; + 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 +353,38 @@ 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", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "sched_process_exit" + }); + ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names); + auto unexpected_sc_names = libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set()); + ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names); +} + +TEST(ConfigureInterestingSets, selection_custom_base_set_repair) +{ + // run app action with fake engine and without the `-A` option + falco::app::state s; + s.options.all_events = false; + s.engine = mock_engine_from_filters(s_sample_filters); + + // simulate empty custom set but repair option set. + // note: here we use file syscalls (e.g. open, openat) and have a custom + // positive set, so we expect syscalls such as "close" to be selected as + // repaired. Also, given that we use some network syscalls, we expect "bind" + // to be selected event if we negate it, because repairment should have + // take precedence. + s.config->m_base_syscalls_custom_set = {"openat", "!bind"}; + s.config->m_base_syscalls_repair = true; + 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: expecting syscalls from mock rules and `sinsp_repair_state_sc_set` enforced syscalls + "connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "sched_process_exit", \ + "bind", "socket", "clone3", "close", "setuid" }); ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names); + auto unexpected_sc_names = libsinsp::events::sc_set_to_names(libsinsp::events::io_sc_set()); + ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names); } diff --git a/userspace/falco/app/actions/configure_interesting_sets.cpp b/userspace/falco/app/actions/configure_interesting_sets.cpp index e4171017abf..6d661b9cf19 100644 --- a/userspace/falco/app/actions/configure_interesting_sets.cpp +++ b/userspace/falco/app/actions/configure_interesting_sets.cpp @@ -71,21 +71,21 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set

Final set is union of (1) and (2) * - * Fall-back if no valid positive syscalls in "base_syscalls", - * e.g. when using "base_syscalls" only for negative syscalls. + * Fall-back if no valid positive syscalls in `base_syscalls.custom_set`, + * e.g. when using `base_syscalls.custom_set` only for negative syscalls. */ auto base_sc_set = libsinsp::events::sinsp_state_sc_set(); - /* USER OVERRIDE INPUT OPTION "base_syscalls". */ + /* USER OVERRIDE INPUT OPTION `base_syscalls.custom_set` etc. */ std::unordered_set user_positive_names = {}; std::unordered_set user_negative_names = {}; - extract_base_syscalls_names(s.config->m_base_syscalls, user_positive_names, user_negative_names); + extract_base_syscalls_names(s.config->m_base_syscalls_custom_set, user_positive_names, user_negative_names); auto user_positive_sc_set = libsinsp::events::names_to_sc_set(user_positive_names); auto user_negative_sc_set = libsinsp::events::names_to_sc_set(user_negative_names); @@ -100,12 +100,31 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set

m_base_syscalls_repair && user_positive_sc_set.empty()) + { + /* If `base_syscalls.repair` is specified, but `base_syscalls.custom_set` is empty we are replacing + * the default `sinsp_state_sc_set()` enforcement with the alternative `sinsp_repair_state_sc_set`. + * This approach only activates additional syscalls Falco needs beyond the + * syscalls defined in each Falco rule that are absolutely necessary based + * on the current rules configuration. */ + + // returned set already has rules_sc_set merged + s.selected_sc_set = libsinsp::events::sinsp_repair_state_sc_set(rules_sc_set); + } + if (!user_negative_sc_set.empty()) { /* Remove negative base_syscalls events. */ @@ -117,6 +136,12 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set

m_base_syscalls_repair && !s.config->m_base_syscalls_custom_set.empty()) + { + /* If base_syscalls.repair is specified enforce state using `sinsp_repair_state_sc_set`. + * This approach is an alternative to the default `sinsp_state_sc_set()` state enforcement + * and only activates additional syscalls Falco needs beyond the syscalls defined in the + * Falco rules that are absolutely necessary based on the current rules configuration. */ + auto selected_sc_set = s.selected_sc_set; + s.selected_sc_set = libsinsp::events::sinsp_repair_state_sc_set(s.selected_sc_set); + auto repaired_sc_set = s.selected_sc_set.diff(selected_sc_set); + if (!repaired_sc_set.empty()) + { + auto repaired_sc_set_names = libsinsp::events::sc_set_to_names(repaired_sc_set); + falco_logger::log(LOG_INFO, "+(" + std::to_string(repaired_sc_set_names.size()) + + ") repaired syscalls: " + concat_set_in_order(repaired_sc_set_names) + "\n"); + } + } + + /* Hidden safety enforcement for `base_syscalls.custom_set` user + * input override option (but keep as general safety enforcement) + * -> sched_process_exit trace point activation (procexit event) + * is necessary for continuous state engine cleanup, + * else memory would grow rapidly and linearly over time. */ + s.selected_sc_set.insert(ppm_sc_code::PPM_SC_SCHED_PROCESS_EXIT); + if (!s.selected_sc_set.empty()) { auto selected_sc_set_names = libsinsp::events::sc_set_to_names(s.selected_sc_set); diff --git a/userspace/falco/configuration.cpp b/userspace/falco/configuration.cpp index ba3fc758229..8d6a75f7bd6 100644 --- a/userspace/falco/configuration.cpp +++ b/userspace/falco/configuration.cpp @@ -316,8 +316,9 @@ void falco_configuration::load_yaml(const std::string& config_name, const yaml_h m_syscall_drop_failed_exit = config.get_scalar("syscall_drop_failed_exit", false); - m_base_syscalls.clear(); - config.get_sequence>(m_base_syscalls, std::string("base_syscalls")); + m_base_syscalls_custom_set.clear(); + config.get_sequence>(m_base_syscalls_custom_set, std::string("base_syscalls.custom_set")); + m_base_syscalls_repair = config.get_scalar("base_syscalls.repair", false); std::set load_plugins; diff --git a/userspace/falco/configuration.h b/userspace/falco/configuration.h index 3b9c8310e6b..b1a8f577a38 100644 --- a/userspace/falco/configuration.h +++ b/userspace/falco/configuration.h @@ -109,7 +109,8 @@ class falco_configuration bool m_syscall_drop_failed_exit; // User supplied base_syscalls, overrides any Falco state engine enforcement. - std::unordered_set m_base_syscalls; + std::unordered_set m_base_syscalls_custom_set; + bool m_base_syscalls_repair; std::vector m_plugins;