From 9075eea62f08fb4e29e87784b5888acd5e9404d3 Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Fri, 15 Oct 2021 16:36:30 -0700 Subject: [PATCH] Falco engine support for plugins Mostly plugins are just handled as a new filter/formatter factory with a new source based on the loaded input plugin, but there are a few changes at the engine level: - is_source_valid returns whether a filter/formatter factory exists for a given source. Will be used by rules loaded to skip rules for an unknown source. - the falco engine now holds the required_plugin_version predicates found in rules files and a method is_plugin_compatible returns whether a plugin semver is compatible with the predicates in the rules - Update the falco engine version and fields checksum for plugins Co-authored-by: Leonardo Grasso Co-authored-by: Loris Degioanni Signed-off-by: Mark Stemm --- userspace/engine/falco_engine.cpp | 51 +++++++++++++++++++++++-- userspace/engine/falco_engine.h | 16 +++++++- userspace/engine/falco_engine_version.h | 11 +++--- 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index 4f04aba7..008ccf86 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -19,6 +19,9 @@ limitations under the License. #include #include +#include +#include + #include "falco_engine.h" #include "falco_utils.h" #include "falco_engine_version.h" @@ -52,6 +55,8 @@ falco_engine::falco_engine(bool seed_rng, const std::string& alternate_lua_dir) falco_common::init(m_lua_main_filename.c_str(), alternate_lua_dir.c_str()); falco_rules::init(m_ls); + m_required_plugin_versions.clear(); + if(seed_rng) { srandom((unsigned) getpid()); @@ -152,7 +157,7 @@ void falco_engine::load_rules(const string &rules_content, bool verbose, bool al } } - m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority, required_engine_version); + m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority, required_engine_version, m_required_plugin_versions); } void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events) @@ -325,9 +330,9 @@ unique_ptr falco_engine::process_event(std::string &s return process_event(source, ev, m_default_ruleset_id); } -void falco_engine::add_source(std::string &source, - std::shared_ptr filter_factory, - std::shared_ptr formatter_factory) +void falco_engine::add_source(const std::string &source, + std::shared_ptr filter_factory, + std::shared_ptr formatter_factory) { m_filter_factories[source] = filter_factory; m_format_factories[source] = formatter_factory; @@ -427,6 +432,42 @@ void falco_engine::add_filter(std::shared_ptr filter, it->second->add(rule, tags, filter); } +bool falco_engine::is_source_valid(const std::string &source) +{ + return (m_rulesets.find(source) != m_rulesets.end()); +} + +bool falco_engine::is_plugin_compatible(const std::string &name, + const std::string &version, + std::string &required_version) +{ + sinsp_plugin::version plugin_version(version.c_str()); + + if(!plugin_version.m_valid) + { + throw falco_exception(string("Plugin version string ") + version + " not valid"); + } + + if(m_required_plugin_versions.find(name) == m_required_plugin_versions.end()) + { + // No required engine versions, so no restrictions. Compatible. + return true; + } + + for(auto &rversion : m_required_plugin_versions[name]) + { + sinsp_plugin::version req_version(rversion.c_str()); + if(req_version.m_version_major > plugin_version.m_version_major) + { + required_version = rversion; + return false; + } + + } + + return true; +} + void falco_engine::clear_filters() { m_rulesets.clear(); @@ -436,6 +477,8 @@ void falco_engine::clear_filters() std::shared_ptr ruleset(new falco_ruleset()); m_rulesets[it.first] = ruleset; } + + m_required_plugin_versions.clear(); } void falco_engine::set_sampling_ratio(uint32_t sampling_ratio) diff --git a/userspace/engine/falco_engine.h b/userspace/engine/falco_engine.h index 570df791..dee86045 100644 --- a/userspace/engine/falco_engine.h +++ b/userspace/engine/falco_engine.h @@ -184,10 +184,14 @@ public: // Configure the engine to support events with the provided // source, with the provided filter factory and formatter factory. // - void add_source(std::string &source, + void add_source(const std::string &source, std::shared_ptr filter_factory, std::shared_ptr formatter_factory); + // Return whether or not there is a valid filter/formatter + // factory for this source. + bool is_source_valid(const std::string &source); + // // Add a filter for the provided event source to the engine // @@ -216,6 +220,12 @@ public: std::shared_ptr create_formatter(const std::string &source, const std::string &output); + // Return whether the provided plugin name + version is + // compatible with the current set of loaded rules files. + // required_version will be filled in with the required + // version when the method returns false. + bool is_plugin_compatible(const std::string &name, const std::string &version, std::string &required_version); + private: // @@ -239,6 +249,10 @@ private: std::map m_known_rulesets; falco_common::priority_type m_min_priority; + // Maps from plugin to a list of required plugin versions + // found in any loaded rules files. + std::map> m_required_plugin_versions; + void populate_rule_result(unique_ptr &res, gen_event *ev); // diff --git a/userspace/engine/falco_engine_version.h b/userspace/engine/falco_engine_version.h index ce45e5c4..cbfe025d 100644 --- a/userspace/engine/falco_engine_version.h +++ b/userspace/engine/falco_engine_version.h @@ -1,5 +1,5 @@ /* -Copyright (C) 2020 The Falco Authors. +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. @@ -14,11 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -// The version of rules/filter fields/etc supported by this falco +// The version of rules/filter fields/etc supported by this Falco // engine. -#define FALCO_ENGINE_VERSION (9) +#define FALCO_ENGINE_VERSION (10) // This is the result of running "falco --list -N | sha256sum" and -// represents the fields supported by this version of falco. It's used +// represents the fields supported by this version of Falco. It's used // at build time to detect a changed set of fields. -#define FALCO_FIELDS_CHECKSUM "3153c620bf3640fab536a2d0e42aa69f10482d741ef3fa72fd8d994b0261ec55" +#define FALCO_FIELDS_CHECKSUM "64c449b28013e400cd4d67c993a253752199d749f820c90c4314946c999c5a9f" +