mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-13 20:05:49 +00:00
refactor(userspace/engine): adapt existing ruleset implementation to new filter_ruleset interface
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
parent
bbbdb311e0
commit
3af8d1c0d2
@ -15,7 +15,7 @@ set(FALCO_ENGINE_SOURCE_FILES
|
||||
falco_engine.cpp
|
||||
falco_utils.cpp
|
||||
json_evt.cpp
|
||||
ruleset.cpp
|
||||
evttype_index_ruleset.cpp
|
||||
formats.cpp
|
||||
filter_macro_resolver.cpp
|
||||
filter_evttype_resolver.cpp
|
||||
|
@ -14,30 +14,32 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ruleset.h"
|
||||
#include "evttype_index_ruleset.h"
|
||||
#include "filter_evttype_resolver.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
falco_ruleset::falco_ruleset()
|
||||
evttype_index_ruleset::evttype_index_ruleset(
|
||||
std::shared_ptr<gen_event_filter_factory> f): m_filter_factory(f)
|
||||
{
|
||||
}
|
||||
|
||||
falco_ruleset::~falco_ruleset()
|
||||
evttype_index_ruleset::~evttype_index_ruleset()
|
||||
{
|
||||
}
|
||||
|
||||
falco_ruleset::ruleset_filters::ruleset_filters()
|
||||
evttype_index_ruleset::ruleset_filters::ruleset_filters()
|
||||
{
|
||||
}
|
||||
|
||||
falco_ruleset::ruleset_filters::~ruleset_filters()
|
||||
evttype_index_ruleset::ruleset_filters::~ruleset_filters()
|
||||
{
|
||||
}
|
||||
|
||||
void falco_ruleset::ruleset_filters::add_wrapper_to_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap)
|
||||
void evttype_index_ruleset::ruleset_filters::add_wrapper_to_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap)
|
||||
{
|
||||
// This is O(n) but it's also uncommon
|
||||
// (when loading rules only).
|
||||
@ -51,7 +53,7 @@ void falco_ruleset::ruleset_filters::add_wrapper_to_list(filter_wrapper_list &wr
|
||||
}
|
||||
}
|
||||
|
||||
void falco_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap)
|
||||
void evttype_index_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap)
|
||||
{
|
||||
// This is O(n) but it's also uncommon
|
||||
// (when loading rules only).
|
||||
@ -64,7 +66,7 @@ void falco_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wrapper_lis
|
||||
}
|
||||
}
|
||||
|
||||
void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap)
|
||||
void evttype_index_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap)
|
||||
{
|
||||
if(wrap->evttypes.empty())
|
||||
{
|
||||
@ -87,7 +89,7 @@ void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper>
|
||||
m_filters.insert(wrap);
|
||||
}
|
||||
|
||||
void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap)
|
||||
void evttype_index_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap)
|
||||
{
|
||||
if(wrap->evttypes.empty())
|
||||
{
|
||||
@ -107,12 +109,12 @@ void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrappe
|
||||
m_filters.erase(wrap);
|
||||
}
|
||||
|
||||
uint64_t falco_ruleset::ruleset_filters::num_filters()
|
||||
uint64_t evttype_index_ruleset::ruleset_filters::num_filters()
|
||||
{
|
||||
return m_filters.size();
|
||||
}
|
||||
|
||||
bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
||||
bool evttype_index_ruleset::ruleset_filters::run(gen_event *evt, falco_rule& match)
|
||||
{
|
||||
if(evt->get_type() < m_filter_by_event_type.size())
|
||||
{
|
||||
@ -120,6 +122,7 @@ bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
||||
{
|
||||
if(wrap->filter->run(evt))
|
||||
{
|
||||
match = wrap->rule;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -130,6 +133,7 @@ bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
||||
{
|
||||
if(wrap->filter->run(evt))
|
||||
{
|
||||
match = wrap->rule;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -137,7 +141,7 @@ bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
||||
return false;
|
||||
}
|
||||
|
||||
void falco_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &evttypes)
|
||||
void evttype_index_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &evttypes)
|
||||
{
|
||||
evttypes.clear();
|
||||
|
||||
@ -147,23 +151,54 @@ void falco_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &ev
|
||||
}
|
||||
}
|
||||
|
||||
void falco_ruleset::add(string &source,
|
||||
string &name,
|
||||
set<string> &tags,
|
||||
set<uint16_t> &evttypes,
|
||||
std::shared_ptr<gen_event_filter> filter)
|
||||
void evttype_index_ruleset::add(
|
||||
const falco_rule& rule,
|
||||
std::shared_ptr<libsinsp::filter::ast::expr> condition)
|
||||
{
|
||||
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
|
||||
wrap->source = source;
|
||||
wrap->name = name;
|
||||
wrap->tags = tags;
|
||||
wrap->filter = filter;
|
||||
wrap->evttypes = evttypes;
|
||||
|
||||
m_filters.insert(wrap);
|
||||
try
|
||||
{
|
||||
sinsp_filter_compiler compiler(m_filter_factory, condition.get());
|
||||
shared_ptr<gen_event_filter> filter(compiler.compile());
|
||||
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
|
||||
filter_evttype_resolver resolver;
|
||||
wrap->rule = rule;
|
||||
wrap->filter = filter;
|
||||
resolver.evttypes(condition, wrap->evttypes);
|
||||
m_filters.insert(wrap);
|
||||
}
|
||||
catch (const sinsp_exception& e)
|
||||
{
|
||||
throw falco_exception(string(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
void falco_ruleset::enable(const string &substring, bool match_exact, bool enabled, uint16_t ruleset)
|
||||
uint16_t evttype_index_ruleset::ruleset_id(const std::string &name)
|
||||
{
|
||||
auto it = find(m_ruleset_names.begin(), m_ruleset_names.end(), name);
|
||||
if (it != m_ruleset_names.end())
|
||||
{
|
||||
return it - m_ruleset_names.begin();
|
||||
}
|
||||
m_ruleset_names.push_back(name);
|
||||
return m_ruleset_names.size() - 1;
|
||||
}
|
||||
|
||||
void evttype_index_ruleset::on_loading_complete()
|
||||
{
|
||||
// nothing to do for now
|
||||
}
|
||||
|
||||
void evttype_index_ruleset::clear()
|
||||
{
|
||||
for (size_t i = 0; i < m_rulesets.size(); i++)
|
||||
{
|
||||
std::shared_ptr<ruleset_filters> r(new ruleset_filters());
|
||||
m_rulesets[i] = r;
|
||||
}
|
||||
m_filters.clear();
|
||||
}
|
||||
|
||||
void evttype_index_ruleset::enable(const string &substring, bool match_exact, bool enabled, uint16_t ruleset)
|
||||
{
|
||||
while(m_rulesets.size() < (size_t)ruleset + 1)
|
||||
{
|
||||
@ -176,14 +211,14 @@ void falco_ruleset::enable(const string &substring, bool match_exact, bool enabl
|
||||
|
||||
if(match_exact)
|
||||
{
|
||||
size_t pos = wrap->name.find(substring);
|
||||
size_t pos = wrap->rule.name.find(substring);
|
||||
|
||||
matches = (substring == "" || (pos == 0 &&
|
||||
substring.size() == wrap->name.size()));
|
||||
substring.size() == wrap->rule.name.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
matches = (substring == "" || (wrap->name.find(substring) != string::npos));
|
||||
matches = (substring == "" || (wrap->rule.name.find(substring) != string::npos));
|
||||
}
|
||||
|
||||
if(matches)
|
||||
@ -200,7 +235,7 @@ void falco_ruleset::enable(const string &substring, bool match_exact, bool enabl
|
||||
}
|
||||
}
|
||||
|
||||
void falco_ruleset::enable_tags(const set<string> &tags, bool enabled, uint16_t ruleset)
|
||||
void evttype_index_ruleset::enable_tags(const set<string> &tags, bool enabled, uint16_t ruleset)
|
||||
{
|
||||
while(m_rulesets.size() < (size_t)ruleset + 1)
|
||||
{
|
||||
@ -212,7 +247,7 @@ void falco_ruleset::enable_tags(const set<string> &tags, bool enabled, uint16_t
|
||||
std::set<string> intersect;
|
||||
|
||||
set_intersection(tags.begin(), tags.end(),
|
||||
wrap->tags.begin(), wrap->tags.end(),
|
||||
wrap->rule.tags.begin(), wrap->rule.tags.end(),
|
||||
inserter(intersect, intersect.begin()));
|
||||
|
||||
if(!intersect.empty())
|
||||
@ -229,7 +264,7 @@ void falco_ruleset::enable_tags(const set<string> &tags, bool enabled, uint16_t
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t falco_ruleset::num_rules_for_ruleset(uint16_t ruleset)
|
||||
uint64_t evttype_index_ruleset::enabled_count(uint16_t ruleset)
|
||||
{
|
||||
while(m_rulesets.size() < (size_t)ruleset + 1)
|
||||
{
|
||||
@ -239,17 +274,17 @@ uint64_t falco_ruleset::num_rules_for_ruleset(uint16_t ruleset)
|
||||
return m_rulesets[ruleset]->num_filters();
|
||||
}
|
||||
|
||||
bool falco_ruleset::run(gen_event *evt, uint16_t ruleset)
|
||||
bool evttype_index_ruleset::run(gen_event *evt, falco_rule& match, uint16_t ruleset)
|
||||
{
|
||||
if(m_rulesets.size() < (size_t)ruleset + 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_rulesets[ruleset]->run(evt);
|
||||
return m_rulesets[ruleset]->run(evt, match);
|
||||
}
|
||||
|
||||
void falco_ruleset::evttypes_for_ruleset(set<uint16_t> &evttypes, uint16_t ruleset)
|
||||
void evttype_index_ruleset::enabled_evttypes(set<uint16_t> &evttypes, uint16_t ruleset)
|
||||
{
|
||||
if(m_rulesets.size() < (size_t)ruleset + 1)
|
||||
{
|
140
userspace/engine/evttype_index_ruleset.h
Normal file
140
userspace/engine/evttype_index_ruleset.h
Normal file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
#include "ruleset.h"
|
||||
#include "sinsp.h"
|
||||
#include "filter.h"
|
||||
#include "event.h"
|
||||
|
||||
#include "gen_filter.h"
|
||||
|
||||
/*!
|
||||
\brief A filter_ruleset that indexes enabled rules by event type,
|
||||
and performs linear search on each event type bucket
|
||||
*/
|
||||
class evttype_index_ruleset: public filter_ruleset
|
||||
{
|
||||
public:
|
||||
evttype_index_ruleset(std::shared_ptr<gen_event_filter_factory> factory);
|
||||
virtual ~evttype_index_ruleset();
|
||||
|
||||
void add(
|
||||
const falco_rule& rule,
|
||||
std::shared_ptr<libsinsp::filter::ast::expr> condition) override;
|
||||
|
||||
void clear() override;
|
||||
|
||||
uint16_t ruleset_id(const std::string &name) override;
|
||||
|
||||
bool run(gen_event *evt, falco_rule& match, uint16_t ruleset = 0);
|
||||
|
||||
uint64_t enabled_count(uint16_t ruleset = 0) override;
|
||||
|
||||
void on_loading_complete() override;
|
||||
|
||||
void enable(
|
||||
const std::string &substring,
|
||||
bool match_exact,
|
||||
bool enabled,
|
||||
uint16_t ruleset = 0) override;
|
||||
|
||||
void enable_tags(
|
||||
const std::set<std::string> &tags,
|
||||
bool enabled,
|
||||
uint16_t ruleset = 0) override;
|
||||
|
||||
// evttypes for a ruleset
|
||||
void enabled_evttypes(
|
||||
std::set<uint16_t> &evttypes,
|
||||
uint16_t ruleset) override;
|
||||
|
||||
private:
|
||||
|
||||
struct filter_wrapper
|
||||
{
|
||||
falco_rule rule;
|
||||
std::set<uint16_t> evttypes;
|
||||
std::shared_ptr<gen_event_filter> filter;
|
||||
};
|
||||
|
||||
typedef std::list<std::shared_ptr<filter_wrapper>> filter_wrapper_list;
|
||||
|
||||
// A group of filters all having the same ruleset
|
||||
class ruleset_filters {
|
||||
public:
|
||||
ruleset_filters();
|
||||
|
||||
virtual ~ruleset_filters();
|
||||
|
||||
void add_filter(std::shared_ptr<filter_wrapper> wrap);
|
||||
void remove_filter(std::shared_ptr<filter_wrapper> wrap);
|
||||
|
||||
uint64_t num_filters();
|
||||
|
||||
bool run(gen_event *evt, falco_rule& match);
|
||||
|
||||
void evttypes_for_ruleset(std::set<uint16_t> &evttypes);
|
||||
|
||||
private:
|
||||
void add_wrapper_to_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap);
|
||||
void remove_wrapper_from_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap);
|
||||
|
||||
// Vector indexes from event type to a set of filters. There can
|
||||
// be multiple filters for a given event type.
|
||||
// NOTE: This is used only when the event sub-type is 0.
|
||||
std::vector<filter_wrapper_list> m_filter_by_event_type;
|
||||
|
||||
filter_wrapper_list m_filter_all_event_types;
|
||||
|
||||
// All filters added. Used to make num_filters() fast.
|
||||
std::set<std::shared_ptr<filter_wrapper>> m_filters;
|
||||
};
|
||||
|
||||
// Vector indexes from ruleset id to set of rules.
|
||||
std::vector<std::shared_ptr<ruleset_filters>> m_rulesets;
|
||||
|
||||
// All filters added. The set of enabled filters is held in m_rulesets
|
||||
std::set<std::shared_ptr<filter_wrapper>> m_filters;
|
||||
|
||||
std::shared_ptr<gen_event_filter_factory> m_filter_factory;
|
||||
std::vector<std::string> m_ruleset_names;
|
||||
};
|
||||
|
||||
class evttype_index_ruleset_factory: public filter_ruleset_factory
|
||||
{
|
||||
public:
|
||||
inline evttype_index_ruleset_factory(
|
||||
std::shared_ptr<gen_event_filter_factory> factory
|
||||
): m_filter_factory(factory) { }
|
||||
|
||||
inline std::shared_ptr<filter_ruleset> new_ruleset() override
|
||||
{
|
||||
std::shared_ptr<filter_ruleset> ret(
|
||||
new evttype_index_ruleset(m_filter_factory));
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<gen_event_filter_factory> m_filter_factory;
|
||||
};
|
@ -22,6 +22,7 @@ limitations under the License.
|
||||
|
||||
struct falco_rule
|
||||
{
|
||||
size_t id;
|
||||
std::string source;
|
||||
std::string name;
|
||||
std::string description;
|
||||
|
Loading…
Reference in New Issue
Block a user