mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-27 23:27:20 +00:00
new(userspace/engine): add a resolver class to search evttypes from filters and event names
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
parent
f638706ba3
commit
b5870a8656
@ -18,6 +18,7 @@ set(FALCO_ENGINE_SOURCE_FILES
|
||||
ruleset.cpp
|
||||
formats.cpp
|
||||
filter_macro_resolver.cpp
|
||||
filter_evttype_resolver.cpp
|
||||
rule_loader.cpp
|
||||
rule_reader.cpp
|
||||
stats_manager.cpp)
|
||||
|
168
userspace/engine/filter_evttype_resolver.cpp
Normal file
168
userspace/engine/filter_evttype_resolver.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
Copyright (C) 2022 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.
|
||||
*/
|
||||
|
||||
#include "filter_evttype_resolver.h"
|
||||
#include <sinsp.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace libsinsp::filter;
|
||||
|
||||
extern sinsp_evttables g_infotables;
|
||||
|
||||
static bool is_evttype_operator(const string& op)
|
||||
{
|
||||
return op == "==" || op == "=" || op == "!=" || op == "in";
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::evttypes(string evtname, set<uint16_t>& out)
|
||||
{
|
||||
// Fill in from 2 to PPM_EVENT_MAX-1. 0 and 1 are excluded as
|
||||
// those are PPM_GENERIC_E/PPME_GENERIC_X.
|
||||
const struct ppm_event_info* etable = g_infotables.m_event_info;
|
||||
for(uint16_t i = 2; i < PPM_EVENT_MAX; i++)
|
||||
{
|
||||
// Skip "old" event versions that have been replaced
|
||||
// by newer event versions, or events that are unused.
|
||||
if(!(etable[i].flags & (EF_OLD_VERSION | EF_UNUSED))
|
||||
&& (evtname.empty() || string(etable[i].name) == evtname))
|
||||
{
|
||||
out.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::evttypes(ast::expr* filter, set<uint16_t>& out)
|
||||
{
|
||||
m_expect_value = false;
|
||||
m_last_node_evttypes.clear();
|
||||
filter->accept(this);
|
||||
copy(m_last_node_evttypes.begin(),
|
||||
m_last_node_evttypes.end(),
|
||||
inserter(out, out.begin()));
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::evttypes(
|
||||
shared_ptr<ast::expr> filter, set<uint16_t>& out)
|
||||
{
|
||||
m_expect_value = false;
|
||||
m_last_node_evttypes.clear();
|
||||
filter.get()->accept(this);
|
||||
copy(m_last_node_evttypes.begin(),
|
||||
m_last_node_evttypes.end(),
|
||||
inserter(out, out.begin()));
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::and_expr* e)
|
||||
{
|
||||
set<uint16_t> nodetypes;
|
||||
evttypes("", nodetypes);
|
||||
m_last_node_evttypes.clear();
|
||||
for (auto &c : e->children)
|
||||
{
|
||||
set<uint16_t> inters;
|
||||
c->accept(this);
|
||||
set_intersection(
|
||||
nodetypes.begin(), nodetypes.end(),
|
||||
m_last_node_evttypes.begin(), m_last_node_evttypes.end(),
|
||||
std::inserter(inters, inters.begin()));
|
||||
nodetypes = inters;
|
||||
}
|
||||
m_last_node_evttypes = nodetypes;
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::or_expr* e)
|
||||
{
|
||||
set<uint16_t> nodetypes;
|
||||
m_last_node_evttypes.clear();
|
||||
for (auto &c : e->children)
|
||||
{
|
||||
c->accept(this);
|
||||
copy(m_last_node_evttypes.begin(),
|
||||
m_last_node_evttypes.end(),
|
||||
inserter(nodetypes, nodetypes.begin()));
|
||||
}
|
||||
m_last_node_evttypes = nodetypes;
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::not_expr* e)
|
||||
{
|
||||
set<uint16_t> diff, all_types;
|
||||
m_last_node_evttypes.clear();
|
||||
e->child->accept(this);
|
||||
evttypes("", all_types);
|
||||
if (all_types != m_last_node_evttypes)
|
||||
{
|
||||
diff = m_last_node_evttypes;
|
||||
m_last_node_evttypes.clear();
|
||||
set_difference(
|
||||
all_types.begin(), all_types.end(), diff.begin(), diff.end(),
|
||||
inserter(m_last_node_evttypes, m_last_node_evttypes.begin()));
|
||||
}
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::binary_check_expr* e)
|
||||
{
|
||||
m_last_node_evttypes.clear();
|
||||
if (e->field == "evt.type" && is_evttype_operator(e->op))
|
||||
{
|
||||
m_expect_value = true;
|
||||
e->value->accept(this);
|
||||
m_expect_value = false;
|
||||
if (e->op == "!=")
|
||||
{
|
||||
set<uint16_t> all_types;
|
||||
set<uint16_t> diff = m_last_node_evttypes;
|
||||
m_last_node_evttypes.clear();
|
||||
evttypes("", all_types);
|
||||
set_difference(
|
||||
all_types.begin(), all_types.end(), diff.begin(), diff.end(),
|
||||
inserter(m_last_node_evttypes, m_last_node_evttypes.begin()));
|
||||
}
|
||||
return;
|
||||
}
|
||||
evttypes("", m_last_node_evttypes);
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::unary_check_expr* e)
|
||||
{
|
||||
m_last_node_evttypes.clear();
|
||||
evttypes("", m_last_node_evttypes);
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::value_expr* e)
|
||||
{
|
||||
m_last_node_evttypes.clear();
|
||||
if (m_expect_value)
|
||||
{
|
||||
evttypes(e->value, m_last_node_evttypes);
|
||||
return;
|
||||
}
|
||||
evttypes("", m_last_node_evttypes);
|
||||
}
|
||||
|
||||
void filter_evttype_resolver::visit(ast::list_expr* e)
|
||||
{
|
||||
m_last_node_evttypes.clear();
|
||||
if (m_expect_value)
|
||||
{
|
||||
for (auto &v : e->values)
|
||||
{
|
||||
evttypes(v, m_last_node_evttypes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
evttypes("", m_last_node_evttypes);
|
||||
}
|
68
userspace/engine/filter_evttype_resolver.h
Normal file
68
userspace/engine/filter_evttype_resolver.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (C) 2022 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 <filter/parser.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
/*!
|
||||
\brief Helper class for finding event types
|
||||
*/
|
||||
class filter_evttype_resolver: private libsinsp::filter::ast::expr_visitor
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
\brief Collects the evttypes related to the provided event name.
|
||||
The event types are inserted in the set provided as parameter.
|
||||
The set is not cleared before inserting the elements.
|
||||
\param evtname The event name used to search event types. If an empty
|
||||
string is passed, all the available evttypes are collected
|
||||
\param out The set to be filled with the evttypes
|
||||
*/
|
||||
void evttypes(std::string evtname, std::set<uint16_t>& out);
|
||||
|
||||
/*!
|
||||
\brief Visits a filter AST and collects all the evttypes for which
|
||||
the filter expression can be evaluated as true. The event types are
|
||||
inserted in the set provided as parameter. The set is not cleared before
|
||||
inserting the elements.
|
||||
\param filter The filter AST to be explored
|
||||
\param out The set to be filled with the evttypes
|
||||
*/
|
||||
void evttypes(libsinsp::filter::ast::expr* filter, std::set<uint16_t>& out);
|
||||
|
||||
/*!
|
||||
\brief Overloaded version of evttypes() that supports filters wrapped
|
||||
in shared pointers
|
||||
*/
|
||||
void evttypes(std::shared_ptr<libsinsp::filter::ast::expr> filter,
|
||||
std::set<uint16_t>& out);
|
||||
|
||||
private:
|
||||
void visit(libsinsp::filter::ast::and_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::or_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::not_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::value_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::list_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::unary_check_expr* e) override;
|
||||
void visit(libsinsp::filter::ast::binary_check_expr* e) override;
|
||||
|
||||
bool m_expect_value;
|
||||
std::set<uint16_t> m_last_node_evttypes;
|
||||
};
|
Loading…
Reference in New Issue
Block a user