mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-28 07:37:32 +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
|
ruleset.cpp
|
||||||
formats.cpp
|
formats.cpp
|
||||||
filter_macro_resolver.cpp
|
filter_macro_resolver.cpp
|
||||||
|
filter_evttype_resolver.cpp
|
||||||
rule_loader.cpp
|
rule_loader.cpp
|
||||||
rule_reader.cpp
|
rule_reader.cpp
|
||||||
stats_manager.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