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 <me@leonardograsso.com>
Co-authored-by: Loris Degioanni <loris@sysdig.com>
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
Mark Stemm 2021-10-15 16:36:30 -07:00 committed by poiana
parent 69e32f7ed1
commit 9075eea62f
3 changed files with 68 additions and 10 deletions

View File

@ -19,6 +19,9 @@ limitations under the License.
#include <string>
#include <fstream>
#include <sinsp.h>
#include <plugin.h>
#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::rule_result> 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<gen_event_filter_factory> filter_factory,
std::shared_ptr<gen_event_formatter_factory> formatter_factory)
void falco_engine::add_source(const std::string &source,
std::shared_ptr<gen_event_filter_factory> filter_factory,
std::shared_ptr<gen_event_formatter_factory> 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<gen_event_filter> 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<falco_ruleset> ruleset(new falco_ruleset());
m_rulesets[it.first] = ruleset;
}
m_required_plugin_versions.clear();
}
void falco_engine::set_sampling_ratio(uint32_t sampling_ratio)

View File

@ -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<gen_event_filter_factory> filter_factory,
std::shared_ptr<gen_event_formatter_factory> 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<gen_event_formatter> 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<string, uint16_t> 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<std::string, std::list<std::string>> m_required_plugin_versions;
void populate_rule_result(unique_ptr<struct rule_result> &res, gen_event *ev);
//

View File

@ -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"