Don't track event "tags" i.e. event types in rulesets

Modify rulesets to not keep track of the event types for a given set
filter. Instead, using the changes in
https://github.com/falcosecurity/libs/pull/74 event types are returned
directly by the filter.

Within each ruleset, there's a vector that maps from event number to
set of filters that are related to that event number. There's also a
general set of filters for all event types.

run() both indexes into the per-event vector as well as iterate over
the all event types set.

Also, used shared_ptr instead of direct pointers, which matches the
updated interface used by lua_parser. This simplifies the bookkeeping
a bit (no more delete when removing rulesets).

Given these changes, there's no need for a separate
falco_sinsp_ruleset class any longer, so remove it.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
Mark Stemm 2021-08-25 16:03:24 -07:00 committed by poiana
parent a0f7d7cf85
commit 044a7c153e
3 changed files with 156 additions and 331 deletions

View File

@ -25,15 +25,14 @@ static uint16_t default_ruleset = 0;
static uint16_t non_default_ruleset = 3;
static uint16_t other_non_default_ruleset = 2;
static std::set<std::string> tags = {"some_tag", "some_other_tag"};
static std::set<uint32_t> event_tags = {1};
TEST_CASE("Should enable/disable for exact match w/ default ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("one_rule", exact_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -45,10 +44,10 @@ TEST_CASE("Should enable/disable for exact match w/ default ruleset", "[rulesets
TEST_CASE("Should enable/disable for exact match w/ specific ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("one_rule", exact_match, enabled, non_default_ruleset);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
@ -64,10 +63,10 @@ TEST_CASE("Should enable/disable for exact match w/ specific ruleset", "[ruleset
TEST_CASE("Should not enable for exact match different rule name", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("some_other_rule", exact_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0);
@ -76,10 +75,10 @@ TEST_CASE("Should not enable for exact match different rule name", "[rulesets]")
TEST_CASE("Should enable/disable for exact match w/ substring and default ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("one_rule", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -91,10 +90,10 @@ TEST_CASE("Should enable/disable for exact match w/ substring and default rulese
TEST_CASE("Should not enable for substring w/ exact_match", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("one_", exact_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 0);
@ -103,10 +102,10 @@ TEST_CASE("Should not enable for substring w/ exact_match", "[rulesets]")
TEST_CASE("Should enable/disable for prefix match w/ default ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("one_", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -118,10 +117,10 @@ TEST_CASE("Should enable/disable for prefix match w/ default ruleset", "[ruleset
TEST_CASE("Should enable/disable for suffix match w/ default ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("_rule", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -133,10 +132,10 @@ TEST_CASE("Should enable/disable for suffix match w/ default ruleset", "[ruleset
TEST_CASE("Should enable/disable for substring match w/ default ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("ne_ru", substring_match, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -148,10 +147,10 @@ TEST_CASE("Should enable/disable for substring match w/ default ruleset", "[rule
TEST_CASE("Should enable/disable for substring match w/ specific ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable("ne_ru", substring_match, enabled, non_default_ruleset);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
@ -167,11 +166,11 @@ TEST_CASE("Should enable/disable for substring match w/ specific ruleset", "[rul
TEST_CASE("Should enable/disable for tags w/ default ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
std::set<std::string> want_tags = {"some_tag"};
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -183,11 +182,11 @@ TEST_CASE("Should enable/disable for tags w/ default ruleset", "[rulesets]")
TEST_CASE("Should enable/disable for tags w/ specific ruleset", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
std::set<std::string> want_tags = {"some_tag"};
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled, non_default_ruleset);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 1);
@ -203,11 +202,11 @@ TEST_CASE("Should enable/disable for tags w/ specific ruleset", "[rulesets]")
TEST_CASE("Should not enable for different tags", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
std::set<std::string> want_tags = {"some_different_tag"};
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled);
REQUIRE(r.num_rules_for_ruleset(non_default_ruleset) == 0);
@ -216,11 +215,11 @@ TEST_CASE("Should not enable for different tags", "[rulesets]")
TEST_CASE("Should enable/disable for overlapping tags", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> filter(new gen_event_filter());
string rule_name = "one_rule";
std::set<std::string> want_tags = {"some_tag", "some_different_tag"};
r.add(rule_name, tags, event_tags, filter);
r.add(rule_name, tags, filter);
r.enable_tags(want_tags, enabled);
REQUIRE(r.num_rules_for_ruleset(default_ruleset) == 1);
@ -232,15 +231,15 @@ TEST_CASE("Should enable/disable for overlapping tags", "[rulesets]")
TEST_CASE("Should enable/disable for incremental adding tags", "[rulesets]")
{
falco_ruleset r;
gen_event_filter *rule1_filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> rule1_filter(new gen_event_filter());
string rule1_name = "one_rule";
std::set<std::string> rule1_tags = {"rule1_tag"};
r.add(rule1_name, rule1_tags, event_tags, rule1_filter);
r.add(rule1_name, rule1_tags, rule1_filter);
gen_event_filter *rule2_filter = new gen_event_filter();
std::shared_ptr<gen_event_filter> rule2_filter(new gen_event_filter());
string rule2_name = "two_rule";
std::set<std::string> rule2_tags = {"rule2_tag"};
r.add(rule2_name, rule2_tags, event_tags, rule2_filter);
r.add(rule2_name, rule2_tags, rule2_filter);
std::set<std::string> want_tags;

View File

@ -17,6 +17,8 @@ limitations under the License.
#include "ruleset.h"
#include "banned.h" // This raises a compilation error when certain functions are used
#include <algorithm>
using namespace std;
falco_ruleset::falco_ruleset()
@ -25,127 +27,112 @@ falco_ruleset::falco_ruleset()
falco_ruleset::~falco_ruleset()
{
for(const auto &val : m_filters)
{
delete val.second->filter;
delete val.second;
}
for(auto &ruleset : m_rulesets)
{
delete ruleset;
}
m_filters.clear();
}
falco_ruleset::ruleset_filters::ruleset_filters():
m_num_filters(0)
falco_ruleset::ruleset_filters::ruleset_filters()
{
}
falco_ruleset::ruleset_filters::~ruleset_filters()
{
for(uint32_t i = 0; i < m_filter_by_event_tag.size(); i++)
}
void falco_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).
auto pos = std::find(wrappers.begin(),
wrappers.end(),
wrap);
if(pos == wrappers.end())
{
if(m_filter_by_event_tag[i])
{
delete m_filter_by_event_tag[i];
m_filter_by_event_tag[i] = NULL;
}
wrappers.push_back(wrap);
}
}
void falco_ruleset::ruleset_filters::add_filter(filter_wrapper *wrap)
void falco_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap)
{
bool added = false;
for(uint32_t etag = 0; etag < wrap->event_tags.size(); etag++)
// This is O(n) but it's also uncommon
// (when loading rules only).
auto pos = std::find(wrappers.begin(),
wrappers.end(),
wrap);
if(pos != wrappers.end())
{
if(wrap->event_tags[etag])
{
added = true;
if(m_filter_by_event_tag.size() <= etag)
{
m_filter_by_event_tag.resize(etag + 1);
}
if(!m_filter_by_event_tag[etag])
{
m_filter_by_event_tag[etag] = new list<filter_wrapper *>();
}
m_filter_by_event_tag[etag]->push_back(wrap);
}
}
if(added)
{
m_num_filters++;
wrappers.erase(pos);
}
}
void falco_ruleset::ruleset_filters::remove_filter(filter_wrapper *wrap)
void falco_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap)
{
bool removed = false;
std::set<uint16_t> fevttypes = wrap->filter->evttypes();
for(uint32_t etag = 0; etag < wrap->event_tags.size(); etag++)
if(fevttypes.empty())
{
if(wrap->event_tags[etag])
// Should run for all event types
add_wrapper_to_list(m_filter_all_event_types, wrap);
}
else
{
for(auto &etype : fevttypes)
{
if(etag < m_filter_by_event_tag.size())
if(m_filter_by_event_type.size() <= etype)
{
list<filter_wrapper *> *l = m_filter_by_event_tag[etag];
if(l)
{
auto it = remove(l->begin(),
l->end(),
wrap);
m_filter_by_event_type.resize(etype + 1);
}
if(it != l->end())
{
removed = true;
add_wrapper_to_list(m_filter_by_event_type[etype], wrap);
}
}
l->erase(it,
l->end());
m_filters.insert(wrap);
}
if(l->size() == 0)
{
delete l;
m_filter_by_event_tag[etag] = NULL;
}
}
}
void falco_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap)
{
std::set<uint16_t> fevttypes = wrap->filter->evttypes();
if(fevttypes.empty())
{
remove_wrapper_from_list(m_filter_all_event_types, wrap);
}
else
{
for(auto &etype : fevttypes)
{
if( etype < m_filter_by_event_type.size() )
{
remove_wrapper_from_list(m_filter_by_event_type[etype], wrap);
}
}
}
if(removed)
{
m_num_filters--;
}
m_filters.erase(wrap);
}
uint64_t falco_ruleset::ruleset_filters::num_filters()
{
return m_num_filters;
return m_filters.size();
}
bool falco_ruleset::ruleset_filters::run(gen_event *evt, uint32_t etag)
bool falco_ruleset::ruleset_filters::run(gen_event *evt)
{
if(etag >= m_filter_by_event_tag.size())
if(evt->get_type() >= m_filter_by_event_type.size())
{
return false;
}
list<filter_wrapper *> *filters = m_filter_by_event_tag[etag];
if(!filters)
for(auto &wrap : m_filter_by_event_type[evt->get_type()])
{
return false;
if(wrap->filter->run(evt))
{
return true;
}
}
for(auto &wrap : *filters)
// Finally, try filters that are not specific to an event type.
for(auto &wrap : m_filter_all_event_types)
{
if(wrap->filter->run(evt))
{
@ -156,83 +143,61 @@ bool falco_ruleset::ruleset_filters::run(gen_event *evt, uint32_t etag)
return false;
}
void falco_ruleset::ruleset_filters::event_tags_for_ruleset(vector<bool> &event_tags)
void falco_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &evttypes)
{
event_tags.assign(m_filter_by_event_tag.size(), false);
evttypes.clear();
for(uint32_t etag = 0; etag < m_filter_by_event_tag.size(); etag++)
for(auto &wrap : m_filters)
{
list<filter_wrapper *> *filters = m_filter_by_event_tag[etag];
if(filters)
{
event_tags[etag] = true;
}
auto fevttypes = wrap->filter->evttypes();
evttypes.insert(fevttypes.begin(), fevttypes.end());
}
}
void falco_ruleset::add(string &name,
set<string> &tags,
set<uint32_t> &event_tags,
gen_event_filter *filter)
std::shared_ptr<gen_event_filter> filter)
{
filter_wrapper *wrap = new filter_wrapper();
std::shared_ptr<filter_wrapper> wrap(new filter_wrapper());
wrap->name = name;
wrap->tags = tags;
wrap->filter = filter;
for(auto &etag : event_tags)
{
wrap->event_tags.resize(etag + 1);
wrap->event_tags[etag] = true;
}
m_filters.insert(pair<string, filter_wrapper *>(name, wrap));
for(const auto &tag : tags)
{
auto it = m_filter_by_event_tag.lower_bound(tag);
if(it == m_filter_by_event_tag.end() ||
it->first != tag)
{
it = m_filter_by_event_tag.emplace_hint(it,
make_pair(tag, list<filter_wrapper *>()));
}
it->second.push_back(wrap);
}
m_filters.insert(wrap);
}
void falco_ruleset::enable(const string &substring, bool match_exact, bool enabled, uint16_t ruleset)
{
while(m_rulesets.size() < (size_t)ruleset + 1)
{
m_rulesets.push_back(new ruleset_filters());
m_rulesets.emplace_back(new ruleset_filters());
}
for(const auto &val : m_filters)
for(const auto &wrap : m_filters)
{
bool matches;
if(match_exact)
{
size_t pos = val.first.find(substring);
size_t pos = wrap->name.find(substring);
matches = (substring == "" || (pos == 0 &&
substring.size() == val.first.size()));
substring.size() == wrap->name.size()));
}
else
{
matches = (substring == "" || (val.first.find(substring) != string::npos));
matches = (substring == "" || (wrap->name.find(substring) != string::npos));
}
if(matches)
{
if(enabled)
{
m_rulesets[ruleset]->add_filter(val.second);
m_rulesets[ruleset]->add_filter(wrap);
}
else
{
m_rulesets[ruleset]->remove_filter(val.second);
m_rulesets[ruleset]->remove_filter(wrap);
}
}
}
@ -242,12 +207,18 @@ void falco_ruleset::enable_tags(const set<string> &tags, bool enabled, uint16_t
{
while(m_rulesets.size() < (size_t)ruleset + 1)
{
m_rulesets.push_back(new ruleset_filters());
m_rulesets.emplace_back(new ruleset_filters());
}
for(const auto &tag : tags)
for(const auto &wrap : m_filters)
{
for(const auto &wrap : m_filter_by_event_tag[tag])
std::set<string> intersect;
set_intersection(tags.begin(), tags.end(),
wrap->tags.begin(), wrap->tags.end(),
inserter(intersect, intersect.begin()));
if(!intersect.empty())
{
if(enabled)
{
@ -265,141 +236,28 @@ uint64_t falco_ruleset::num_rules_for_ruleset(uint16_t ruleset)
{
while(m_rulesets.size() < (size_t)ruleset + 1)
{
m_rulesets.push_back(new ruleset_filters());
m_rulesets.emplace_back(new ruleset_filters());
}
return m_rulesets[ruleset]->num_filters();
}
bool falco_ruleset::run(gen_event *evt, uint32_t etag, uint16_t ruleset)
bool falco_ruleset::run(gen_event *evt, uint16_t ruleset)
{
if(m_rulesets.size() < (size_t)ruleset + 1)
{
return false;
}
return m_rulesets[ruleset]->run(evt, etag);
return m_rulesets[ruleset]->run(evt);
}
void falco_ruleset::event_tags_for_ruleset(vector<bool> &evttypes, uint16_t ruleset)
void falco_ruleset::evttypes_for_ruleset(set<uint16_t> &evttypes, uint16_t ruleset)
{
if(m_rulesets.size() < (size_t)ruleset + 1)
{
return;
}
return m_rulesets[ruleset]->event_tags_for_ruleset(evttypes);
}
falco_sinsp_ruleset::falco_sinsp_ruleset()
{
}
falco_sinsp_ruleset::~falco_sinsp_ruleset()
{
}
void falco_sinsp_ruleset::add(string &name,
set<uint32_t> &evttypes,
set<uint32_t> &syscalls,
set<string> &tags,
sinsp_filter *filter)
{
set<uint32_t> event_tags;
if(evttypes.size() + syscalls.size() == 0)
{
// If no evttypes or syscalls are specified, the filter is
// enabled for all evttypes/syscalls.
for(uint32_t i = 0; i < PPM_EVENT_MAX; i++)
{
evttypes.insert(i);
}
for(uint32_t i = 0; i < PPM_SC_MAX; i++)
{
syscalls.insert(i);
}
}
for(auto evttype : evttypes)
{
event_tags.insert(evttype_to_event_tag(evttype));
}
for(auto syscallid : syscalls)
{
event_tags.insert(syscall_to_event_tag(syscallid));
}
falco_ruleset::add(name, tags, event_tags, (gen_event_filter *)filter);
}
bool falco_sinsp_ruleset::run(sinsp_evt *evt, uint16_t ruleset)
{
uint32_t etag;
uint16_t etype = evt->get_type();
if(etype == PPME_GENERIC_E || etype == PPME_GENERIC_X)
{
sinsp_evt_param *parinfo = evt->get_param(0);
uint16_t syscallid = *(uint16_t *)parinfo->m_val;
etag = syscall_to_event_tag(syscallid);
}
else
{
etag = evttype_to_event_tag(etype);
}
return falco_ruleset::run((gen_event *)evt, etag, ruleset);
}
void falco_sinsp_ruleset::evttypes_for_ruleset(vector<bool> &evttypes, uint16_t ruleset)
{
vector<bool> event_tags;
event_tags_for_ruleset(event_tags, ruleset);
evttypes.assign(PPM_EVENT_MAX + 1, false);
for(uint32_t etype = 0; etype < PPM_EVENT_MAX; etype++)
{
uint32_t etag = evttype_to_event_tag(etype);
if(etag < event_tags.size() && event_tags[etag])
{
evttypes[etype] = true;
}
}
}
void falco_sinsp_ruleset::syscalls_for_ruleset(vector<bool> &syscalls, uint16_t ruleset)
{
vector<bool> event_tags;
event_tags_for_ruleset(event_tags, ruleset);
syscalls.assign(PPM_EVENT_MAX + 1, false);
for(uint32_t syscallid = 0; syscallid < PPM_SC_MAX; syscallid++)
{
uint32_t etag = evttype_to_event_tag(syscallid);
if(etag < event_tags.size() && event_tags[etag])
{
syscalls[syscallid] = true;
}
}
}
uint32_t falco_sinsp_ruleset::evttype_to_event_tag(uint32_t evttype)
{
return evttype;
}
uint32_t falco_sinsp_ruleset::syscall_to_event_tag(uint32_t syscallid)
{
return PPM_EVENT_MAX + 1 + syscallid;
return m_rulesets[ruleset]->evttypes_for_ruleset(evttypes);
}

View File

@ -36,8 +36,7 @@ public:
void add(std::string &name,
std::set<std::string> &tags,
std::set<uint32_t> &event_tags,
gen_event_filter* filter);
std::shared_ptr<gen_event_filter> filter);
// rulesets are arbitrary numbers and should be managed by the caller.
// Note that rulesets are used to index into a std::vector so
@ -65,23 +64,22 @@ public:
uint64_t num_rules_for_ruleset(uint16_t ruleset = 0);
// Match all filters against the provided event.
bool run(gen_event *evt, uint32_t etag, uint16_t ruleset = 0);
bool run(gen_event *evt, uint16_t ruleset = 0);
// Populate the provided vector, indexed by event tag, of the
// event tags associated with the given ruleset id. For
// example, event_tags[10] = true would mean that this ruleset
// relates to event tag 10.
void event_tags_for_ruleset(std::vector<bool> &event_tags, uint16_t ruleset);
// Populate the provided set of event types used by this ruleset.
void evttypes_for_ruleset(std::set<uint16_t> &evttypes, uint16_t ruleset);
private:
struct filter_wrapper {
gen_event_filter *filter;
// Indexes from event tag to enabled/disabled.
std::vector<bool> event_tags;
class filter_wrapper {
public:
std::string name;
std::set<std::string> tags;
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:
@ -89,63 +87,33 @@ private:
virtual ~ruleset_filters();
void add_filter(filter_wrapper *wrap);
void remove_filter(filter_wrapper *wrap);
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, uint32_t etag);
bool run(gen_event *evt);
void event_tags_for_ruleset(std::vector<bool> &event_tags);
void evttypes_for_ruleset(std::set<uint16_t> &evttypes);
private:
uint64_t m_num_filters;
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);
// Maps from event tag to a list of filters. There can
// be multiple filters for a given event tag.
std::vector<std::list<filter_wrapper *> *> m_filter_by_event_tag;
// 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;
};
std::vector<ruleset_filters *> m_rulesets;
// Vector indexes from ruleset id to set of rules.
std::vector<std::shared_ptr<ruleset_filters>> m_rulesets;
// Maps from tag to list of filters having that tag.
std::map<std::string, std::list<filter_wrapper *>> m_filter_by_event_tag;
// This holds all the filters passed to add(), so they can
// be cleaned up.
std::map<std::string,filter_wrapper *> m_filters;
};
// falco_sinsp_ruleset is a specialization of falco_ruleset that
// maps sinsp evttypes/syscalls to event tags.
class falco_sinsp_ruleset : public falco_ruleset
{
public:
falco_sinsp_ruleset();
virtual ~falco_sinsp_ruleset();
void add(std::string &name,
std::set<uint32_t> &evttypes,
std::set<uint32_t> &syscalls,
std::set<std::string> &tags,
sinsp_filter* filter);
bool run(sinsp_evt *evt, uint16_t ruleset = 0);
// Populate the provided vector, indexed by event type, of the
// event types associated with the given ruleset id. For
// example, evttypes[10] = true would mean that this ruleset
// relates to event type 10.
void evttypes_for_ruleset(std::vector<bool> &evttypes, uint16_t ruleset);
// Populate the provided vector, indexed by syscall code, of the
// syscall codes associated with the given ruleset id. For
// example, syscalls[10] = true would mean that this ruleset
// relates to syscall code 10.
void syscalls_for_ruleset(std::vector<bool> &syscalls, uint16_t ruleset);
private:
uint32_t evttype_to_event_tag(uint32_t evttype);
uint32_t syscall_to_event_tag(uint32_t syscallid);
// All filters added. The set of enabled filters is held in m_rulesets
std::set<std::shared_ptr<filter_wrapper>> m_filters;
};