mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-16 13:17:04 +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_engine.cpp
|
||||||
falco_utils.cpp
|
falco_utils.cpp
|
||||||
json_evt.cpp
|
json_evt.cpp
|
||||||
ruleset.cpp
|
evttype_index_ruleset.cpp
|
||||||
formats.cpp
|
formats.cpp
|
||||||
filter_macro_resolver.cpp
|
filter_macro_resolver.cpp
|
||||||
filter_evttype_resolver.cpp
|
filter_evttype_resolver.cpp
|
||||||
|
@ -14,30 +14,32 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
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 "banned.h" // This raises a compilation error when certain functions are used
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std;
|
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
|
// This is O(n) but it's also uncommon
|
||||||
// (when loading rules only).
|
// (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
|
// This is O(n) but it's also uncommon
|
||||||
// (when loading rules only).
|
// (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())
|
if(wrap->evttypes.empty())
|
||||||
{
|
{
|
||||||
@ -87,7 +89,7 @@ void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper>
|
|||||||
m_filters.insert(wrap);
|
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())
|
if(wrap->evttypes.empty())
|
||||||
{
|
{
|
||||||
@ -107,12 +109,12 @@ void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrappe
|
|||||||
m_filters.erase(wrap);
|
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();
|
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())
|
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))
|
if(wrap->filter->run(evt))
|
||||||
{
|
{
|
||||||
|
match = wrap->rule;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,6 +133,7 @@ bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
|||||||
{
|
{
|
||||||
if(wrap->filter->run(evt))
|
if(wrap->filter->run(evt))
|
||||||
{
|
{
|
||||||
|
match = wrap->rule;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +141,7 @@ bool falco_ruleset::ruleset_filters::run(gen_event *evt)
|
|||||||
return false;
|
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();
|
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,
|
void evttype_index_ruleset::add(
|
||||||
string &name,
|
const falco_rule& rule,
|
||||||
set<string> &tags,
|
std::shared_ptr<libsinsp::filter::ast::expr> condition)
|
||||||
set<uint16_t> &evttypes,
|
|
||||||
std::shared_ptr<gen_event_filter> filter)
|
|
||||||
{
|
{
|
||||||
|
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());
|
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
|
||||||
wrap->source = source;
|
filter_evttype_resolver resolver;
|
||||||
wrap->name = name;
|
wrap->rule = rule;
|
||||||
wrap->tags = tags;
|
|
||||||
wrap->filter = filter;
|
wrap->filter = filter;
|
||||||
wrap->evttypes = evttypes;
|
resolver.evttypes(condition, wrap->evttypes);
|
||||||
|
|
||||||
m_filters.insert(wrap);
|
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)
|
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)
|
if(match_exact)
|
||||||
{
|
{
|
||||||
size_t pos = wrap->name.find(substring);
|
size_t pos = wrap->rule.name.find(substring);
|
||||||
|
|
||||||
matches = (substring == "" || (pos == 0 &&
|
matches = (substring == "" || (pos == 0 &&
|
||||||
substring.size() == wrap->name.size()));
|
substring.size() == wrap->rule.name.size()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
matches = (substring == "" || (wrap->name.find(substring) != string::npos));
|
matches = (substring == "" || (wrap->rule.name.find(substring) != string::npos));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(matches)
|
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)
|
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;
|
std::set<string> intersect;
|
||||||
|
|
||||||
set_intersection(tags.begin(), tags.end(),
|
set_intersection(tags.begin(), tags.end(),
|
||||||
wrap->tags.begin(), wrap->tags.end(),
|
wrap->rule.tags.begin(), wrap->rule.tags.end(),
|
||||||
inserter(intersect, intersect.begin()));
|
inserter(intersect, intersect.begin()));
|
||||||
|
|
||||||
if(!intersect.empty())
|
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)
|
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();
|
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)
|
if(m_rulesets.size() < (size_t)ruleset + 1)
|
||||||
{
|
{
|
||||||
return false;
|
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)
|
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
|
struct falco_rule
|
||||||
{
|
{
|
||||||
|
size_t id;
|
||||||
std::string source;
|
std::string source;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
|
Loading…
Reference in New Issue
Block a user