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 6cdfac8d4d4..5dfbd5aaa8c 100644 --- a/unit_tests/falco/app/actions/test_configure_interesting_sets.cpp +++ b/unit_tests/falco/app/actions/test_configure_interesting_sets.cpp @@ -17,6 +17,7 @@ limitations under the License. #include +#include #include #include @@ -199,14 +200,14 @@ TEST(ConfigureInterestingSets, selection_not_allevents) 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_event_names(io_set); + auto ignored_set = falco::app::ignored_sc_set(); + auto erased_sc_names = libsinsp::events::sc_set_to_event_names(ignored_set); ASSERT_NAMES_NOCONTAIN(selected_sc_names, erased_sc_names); // check that final selected set is exactly sinsp state + ruleset auto rule_set = s2.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) + for (const auto &erased : ignored_set) { rule_set.remove(erased); state_set.remove(erased); @@ -273,7 +274,7 @@ TEST(ConfigureInterestingSets, selection_generic_evts) "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_event_names(libsinsp::events::io_sc_set()); + auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set()); ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names); } @@ -361,7 +362,7 @@ TEST(ConfigureInterestingSets, selection_custom_base_set) "connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit" }); ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names); - auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(libsinsp::events::io_sc_set()); + auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set()); ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names); } @@ -389,7 +390,7 @@ TEST(ConfigureInterestingSets, selection_custom_base_set_repair) "bind", "socket", "clone3", "close", "setuid" }); ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names); - auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(libsinsp::events::io_sc_set()); + auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set()); ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names); } @@ -418,3 +419,13 @@ TEST(ConfigureInterestingSets, selection_empty_custom_base_set_repair) ASSERT_EQ(s7.selected_sc_set, s7_state_set); ASSERT_EQ(s7.selected_sc_set.size(), s7_state_set.size()); } + +TEST(ConfigureInterestingSets, ignored_set_expected_size) +{ + // unit test fence to make sure we don't have unexpected regressions + // in the ignored set, to be updated in the future + ASSERT_EQ(falco::app::ignored_sc_set().size(), 14); + + // we don't expect to ignore any syscall in the default base set + ASSERT_EQ(falco::app::ignored_sc_set().intersect(libsinsp::events::sinsp_state_sc_set()).size(), 0); +} diff --git a/userspace/falco/app/actions/configure_interesting_sets.cpp b/userspace/falco/app/actions/configure_interesting_sets.cpp index 90fa5db763c..8dc64093b27 100644 --- a/userspace/falco/app/actions/configure_interesting_sets.cpp +++ b/userspace/falco/app/actions/configure_interesting_sets.cpp @@ -15,6 +15,8 @@ limitations under the License. */ #include "actions.h" +#include "helpers.h" +#include "../app.h" using namespace falco::app; using namespace falco::app::actions; @@ -44,7 +46,7 @@ static void check_for_rules_unsupported_events(falco::app::state& s, const libsi { /* Unsupported events are those events that are used in the rules * but that are not part of the selected event set. For now, this - * is expected to happen only for high volume I/O syscalls for + * is expected to happen only for high volume syscalls for * performance reasons. */ auto unsupported_sc_set = rules_sc_set.diff(s.selected_sc_set); if (unsupported_sc_set.empty()) @@ -55,7 +57,7 @@ static void check_for_rules_unsupported_events(falco::app::state& s, const libsi /* Get the names of the events (syscall and non syscall events) that were not activated and print them. */ auto names = libsinsp::events::sc_set_to_event_names(unsupported_sc_set); std::cerr << "Loaded rules match syscalls that are not activated (e.g. were removed via config settings such as no -A flag or negative base_syscalls elements) or unsupported with current configuration: warning (unsupported-evttype): " + concat_set_in_order(names) << std::endl; - std::cerr << "If syscalls in rules include high volume I/O syscalls (-> activate via `-A` flag), else syscalls may have been removed via base_syscalls option or might be associated with syscalls undefined on your architecture (https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html)" << std::endl; + std::cerr << "If syscalls in rules include high volume syscalls (-> activate via `-A` flag), else syscalls may have been removed via base_syscalls option or might be associated with syscalls undefined on your architecture (https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html)" << std::endl; } static void select_event_set(falco::app::state& s, const libsinsp::events::set& rules_sc_set) @@ -158,12 +160,12 @@ static void select_event_set(falco::app::state& s, const libsinsp::events::set

; +libsinsp::events::set falco::app::ignored_sc_set() +{ + // we ignore all the I/O syscalls that can have very high throughput and + // that can badly impact performance. Of those, we avoid ignoring the + // ones that are part of the base set used by libsinsp for maintaining + // its internal state. + return libsinsp::events::io_sc_set().diff(libsinsp::events::sinsp_state_sc_set()); +} + bool falco::app::run(int argc, char** argv, bool& restart, std::string& errstr) { falco::app::state s; diff --git a/userspace/falco/app/app.h b/userspace/falco/app/app.h index d5a54b8c7fd..c8f11f3c305 100644 --- a/userspace/falco/app/app.h +++ b/userspace/falco/app/app.h @@ -23,7 +23,10 @@ limitations under the License. namespace falco { namespace app { +libsinsp::events::set ignored_sc_set(); + bool run(int argc, char** argv, bool& restart, std::string& errstr); + bool run(falco::app::state& s, bool& restart, std::string& errstr); }; // namespace app diff --git a/userspace/falco/app/options.cpp b/userspace/falco/app/options.cpp index ca4af8ac0db..303996a8f5e 100644 --- a/userspace/falco/app/options.cpp +++ b/userspace/falco/app/options.cpp @@ -164,7 +164,7 @@ void options::define(cxxopts::Options& opts) #else ("c", "Configuration file. If not specified tries " FALCO_SOURCE_CONF_FILE ", " FALCO_INSTALL_CONF_FILE ".", cxxopts::value(conf_filename), "") #endif - ("A", "Monitor each event defined in rules and configs + high volume I/O syscalls. Please use the -i option to list the I/O syscalls Falco supports. This option affects live captures only. Setting -A can impact performance.", cxxopts::value(all_events)->default_value("false")) + ("A", "Monitor all events supported by Falco defined in rules and configs. Please use the -i option to list the events ignored by default without -A. This option affects live captures only. Setting -A can impact performance.", cxxopts::value(all_events)->default_value("false")) ("b,print-base64", "Print data buffers in base64. This is useful for encoding binary data that needs to be used over media designed to consume this format.") ("cri", "Path to CRI socket for container metadata. Use the specified socket to fetch data from a CRI-compatible runtime. If not specified, uses the libs default. This option can be passed multiple times to specify socket to be tried until a successful one is found.", cxxopts::value(cri_socket_paths), "") ("d,daemon", "Run as a daemon.", cxxopts::value(daemon)->default_value("false")) @@ -182,7 +182,7 @@ void options::define(cxxopts::Options& opts) #ifdef HAS_MODERN_BPF ("modern-bpf", "[EXPERIMENTAL] Use BPF modern probe to capture system events.", cxxopts::value(modern_bpf)->default_value("false")) #endif - ("i", "Print all high volume I/O syscalls that are ignored by default (i.e. without the -A flag) and exit.", cxxopts::value(print_ignored_events)->default_value("false")) + ("i", "Print all high volume syscalls that are ignored by default for performance reasons (i.e. without the -A flag) and exit.", cxxopts::value(print_ignored_events)->default_value("false")) #ifndef MINIMAL_BUILD ("k,k8s-api", "Enable Kubernetes support by connecting to the API server specified as argument. E.g. \"http://admin:password@127.0.0.1:8080\". The API server can also be specified via the environment variable FALCO_K8S_API.", cxxopts::value(k8s_api), "") ("K,k8s-api-cert", "Use the provided files names to authenticate user and (optionally) verify the K8S API server identity. Each entry must specify full (absolute, or relative to the current directory) path to the respective file. Private key password is optional (needed only if key is password protected). CA certificate is optional. For all files, only PEM file format is supported. Specifying CA certificate only is obsoleted - when single entry is provided for this option, it will be interpreted as the name of a file containing bearer token. Note that the format of this command-line option prohibits use of files whose names contain ':' or '#' characters in the file name.", cxxopts::value(k8s_api_cert), "( | :[:])")