From 71ca58cebdf71021ba4b64c807adedbbd6601e0a Mon Sep 17 00:00:00 2001 From: Jason Dellaluce Date: Tue, 5 Apr 2022 15:10:00 +0000 Subject: [PATCH] test(userspace/engine): port unit tests for evttypes resolver from linsinsp Signed-off-by: Jason Dellaluce --- tests/CMakeLists.txt | 2 + tests/engine/test_filter_evttype_resolver.cpp | 237 ++++++++++++++++++ 2 files changed, 239 insertions(+) create mode 100644 tests/engine/test_filter_evttype_resolver.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 8f885612..135d2982 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,6 +21,7 @@ if(MINIMAL_BUILD) engine/test_rulesets.cpp engine/test_falco_utils.cpp engine/test_filter_macro_resolver.cpp + engine/test_filter_evttype_resolver.cpp falco/test_configuration.cpp ) else() @@ -30,6 +31,7 @@ else() engine/test_rulesets.cpp engine/test_falco_utils.cpp engine/test_filter_macro_resolver.cpp + engine/test_filter_evttype_resolver.cpp falco/test_configuration.cpp falco/test_webserver.cpp ) diff --git a/tests/engine/test_filter_evttype_resolver.cpp b/tests/engine/test_filter_evttype_resolver.cpp new file mode 100644 index 00000000..fa0187de --- /dev/null +++ b/tests/engine/test_filter_evttype_resolver.cpp @@ -0,0 +1,237 @@ +/* +Copyright (C) 2021 The Falco Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*/ + +#include "filter_evttype_resolver.h" +#include +#include +#include + +using namespace std; +using namespace libsinsp::filter; + +string to_string(set s) +{ + string out = "["; + for(auto &val : s) + { + out += out.size() == 1 ? "" : ", "; + out += to_string(val); + } + out += "]"; + return out; +} + +void compare_evttypes(ast::expr* f, set &expected) +{ + set actual; + filter_evttype_resolver resolver; + resolver.evttypes(f, actual); + for(auto &etype : expected) + { + REQUIRE(actual.find(etype) != actual.end()); + } + for(auto &etype : actual) + { + REQUIRE(expected.find(etype) != expected.end()); + } +} + +ast::expr* compile(const string &fltstr) +{ + libsinsp::filter::parser p(fltstr); + return p.parse(); +} + +TEST_CASE("Should find event types from filter", "[rule_loader]") +{ + filter_evttype_resolver resolver; + set openat_only{ + PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X }; + + set close_only{ + PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X }; + + set openat_close{ + PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X, + PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X }; + + set not_openat; + set not_openat_close; + set not_close; + set all_events; + set no_events; + for(uint32_t i = 2; i < PPM_EVENT_MAX; i++) + { + // Skip "old" event versions that have been replaced + // by newer event versions, or events that are unused. + if(g_infotables.m_event_info[i].flags & (EF_OLD_VERSION | EF_UNUSED)) + { + continue; + } + all_events.insert(i); + if(openat_only.find(i) == openat_only.end()) + { + not_openat.insert(i); + } + if(openat_close.find(i) == openat_close.end()) + { + not_openat_close.insert(i); + } + if (close_only.find(i) == close_only.end()) + { + not_close.insert(i); + } + } + + SECTION("evt_type_eq") + { + auto f = compile("evt.type=openat"); + compare_evttypes(f, openat_only); + } + + SECTION("evt_type_in") + { + auto f = compile("evt.type in (openat, close)"); + compare_evttypes(f, openat_close); + } + + SECTION("evt_type_ne") + { + auto f = compile("evt.type!=openat"); + compare_evttypes(f, not_openat); + } + + SECTION("not_evt_type_eq") + { + auto f = compile("not evt.type=openat"); + compare_evttypes(f, not_openat); + } + + SECTION("not_evt_type_in") + { + auto f = compile("not evt.type in (openat, close)"); + compare_evttypes(f, not_openat_close); + } + + SECTION("not_evt_type_ne") + { + auto f = compile("not evt.type != openat"); + compare_evttypes(f, openat_only); + } + + SECTION("evt_type_or") + { + auto f = compile("evt.type=openat or evt.type=close"); + compare_evttypes(f, openat_close); + } + + SECTION("not_evt_type_or") + { + auto f = compile("evt.type!=openat or evt.type!=close"); + compare_evttypes(f, all_events); + } + + SECTION("evt_type_or_ne") + { + auto f = compile("evt.type=close or evt.type!=openat"); + compare_evttypes(f, not_openat); + } + + SECTION("evt_type_and") + { + auto f = compile("evt.type=close and evt.type=openat"); + compare_evttypes(f, no_events); + } + + SECTION("evt_type_and_non_evt_type") + { + auto f = compile("evt.type=openat and proc.name=nginx"); + compare_evttypes(f, openat_only); + } + + SECTION("evt_type_and_non_evt_type_not") + { + auto f = compile("evt.type=openat and not proc.name=nginx"); + compare_evttypes(f, openat_only); + } + + SECTION("evt_type_and_nested") + { + auto f = compile("evt.type=openat and (proc.name=nginx)"); + compare_evttypes(f, openat_only); + } + + SECTION("evt_type_and_nested_multi") + { + auto f = compile("evt.type=openat and (evt.type=close and proc.name=nginx)"); + compare_evttypes(f, no_events); + } + + SECTION("non_evt_type") + { + auto f = compile("proc.name=nginx"); + compare_evttypes(f, all_events); + } + + SECTION("non_evt_type_or") + { + auto f = compile("evt.type=openat or proc.name=nginx"); + compare_evttypes(f, all_events); + } + + SECTION("non_evt_type_or_nested_first") + { + auto f = compile("(evt.type=openat) or proc.name=nginx"); + compare_evttypes(f, all_events); + } + + SECTION("non_evt_type_or_nested_second") + { + auto f = compile("evt.type=openat or (proc.name=nginx)"); + compare_evttypes(f, all_events); + } + + SECTION("non_evt_type_or_nested_multi") + { + auto f = compile("evt.type=openat or (evt.type=close and proc.name=nginx)"); + compare_evttypes(f, openat_close); + } + + SECTION("non_evt_type_or_nested_multi_not") + { + auto f = compile("evt.type=openat or not (evt.type=close and proc.name=nginx)"); + compare_evttypes(f, not_close); + } + + SECTION("non_evt_type_and_nested_multi_not") + { + auto f = compile("evt.type=openat and not (evt.type=close and proc.name=nginx)"); + compare_evttypes(f, openat_only); + } + + SECTION("ne_and_and") + { + auto f = compile("evt.type!=openat and evt.type!=close"); + compare_evttypes(f, not_openat_close); + } + + SECTION("not_not") + { + auto f = compile("not (not evt.type=openat)"); + compare_evttypes(f, openat_only); + } +} \ No newline at end of file