mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-17 16:21:31 +00:00
More efficient searches for defined filters
Instead of iterating over the entire list of filters and doing pattern matches against each defined filter, perform table lookups. For filters that take arguments e.g. proc.aname[3] or evt.arg.xxx, split the filtercheck string on bracket/dot and check the values against a table. There are now two tables of defined filters: defined_arg_filters and defined_noarg_filters. Each filter is put into a table depending on whether the filter takes an argument or not. Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
parent
c1035ce4de
commit
047f12d0f6
@ -433,10 +433,32 @@ function load_rules(sinsp_lua_parser,
|
||||
for filter, _ in pairs(filters) do
|
||||
found = false
|
||||
|
||||
for pat, _ in pairs(defined_filters) do
|
||||
if string.match(filter, pat) ~= nil then
|
||||
found = true
|
||||
break
|
||||
if defined_noarg_filters[filter] ~= nil then
|
||||
found = true
|
||||
else
|
||||
bracket_idx = string.find(filter, "[", 1, true)
|
||||
|
||||
if bracket_idx ~= nil then
|
||||
subfilter = string.sub(filter, 1, bracket_idx-1)
|
||||
|
||||
if defined_arg_filters[subfilter] ~= nil then
|
||||
found = true
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
dot_idx = string.find(filter, ".", 1, true)
|
||||
|
||||
while dot_idx ~= nil do
|
||||
subfilter = string.sub(filter, 1, dot_idx-1)
|
||||
|
||||
if defined_arg_filters[subfilter] ~= nil then
|
||||
found = true
|
||||
break
|
||||
end
|
||||
|
||||
dot_idx = string.find(filter, ".", dot_idx+1, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -323,12 +323,12 @@ void falco_rules::load_rules(const string &rules_content,
|
||||
|
||||
lua_setglobal(m_ls, m_lua_ignored_syscalls.c_str());
|
||||
|
||||
// Create a table containing all filtercheck names.
|
||||
lua_newtable(m_ls);
|
||||
|
||||
vector<const filter_check_info*> fc_plugins;
|
||||
sinsp::get_filtercheck_fields_info(&fc_plugins);
|
||||
|
||||
set<string> no_argument_filters;
|
||||
set<string> argument_filters;
|
||||
|
||||
for(uint32_t j = 0; j < fc_plugins.size(); j++)
|
||||
{
|
||||
const filter_check_info* fci = fc_plugins[j];
|
||||
@ -350,45 +350,71 @@ void falco_rules::load_rules(const string &rules_content,
|
||||
|
||||
// Some filters can work with or without an argument
|
||||
std::set<string> flexible_filters = {
|
||||
"^proc.aname",
|
||||
"^proc.apid"
|
||||
"proc.aname",
|
||||
"proc.apid"
|
||||
};
|
||||
|
||||
std::list<string> fields;
|
||||
std::string field_base = string("^") + fld->m_name;
|
||||
|
||||
if(fld->m_flags & EPF_REQUIRES_ARGUMENT ||
|
||||
flexible_filters.find(field_base) != flexible_filters.end())
|
||||
flexible_filters.find(fld->m_name) != flexible_filters.end())
|
||||
{
|
||||
fields.push_back(field_base + "[%[%.]");
|
||||
argument_filters.insert(fld->m_name);
|
||||
}
|
||||
|
||||
if(!(fld->m_flags & EPF_REQUIRES_ARGUMENT) ||
|
||||
flexible_filters.find(field_base) != flexible_filters.end())
|
||||
flexible_filters.find(fld->m_name) != flexible_filters.end())
|
||||
{
|
||||
fields.push_back(field_base + "$");
|
||||
}
|
||||
|
||||
for(auto &field : fields)
|
||||
{
|
||||
lua_pushstring(m_ls, field.c_str());
|
||||
lua_pushnumber(m_ls, 1);
|
||||
lua_settable(m_ls, -3);
|
||||
no_argument_filters.insert(fld->m_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &chk_field : m_engine->json_factory().get_fields())
|
||||
{
|
||||
for(auto &field : chk_field.fields)
|
||||
for(auto &field : chk_field.m_fields)
|
||||
{
|
||||
lua_pushstring(m_ls, field.name.c_str());
|
||||
lua_pushnumber(m_ls, 1);
|
||||
lua_settable(m_ls, -3);
|
||||
switch(field.m_idx_mode)
|
||||
{
|
||||
case json_event_filter_check::IDX_REQUIRED:
|
||||
argument_filters.insert(field.m_name);
|
||||
break;
|
||||
case json_event_filter_check::IDX_ALLOWED:
|
||||
argument_filters.insert(field.m_name);
|
||||
no_argument_filters.insert(field.m_name);
|
||||
break;
|
||||
case json_event_filter_check::IDX_NONE:
|
||||
no_argument_filters.insert(field.m_name);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lua_setglobal(m_ls, m_lua_defined_filters.c_str());
|
||||
// Create tables containing all filtercheck
|
||||
// names. They are split into names that require
|
||||
// arguments and ones that do not.
|
||||
|
||||
lua_newtable(m_ls);
|
||||
|
||||
for(auto &field : argument_filters)
|
||||
{
|
||||
lua_pushstring(m_ls, field.c_str());
|
||||
lua_pushnumber(m_ls, 1);
|
||||
lua_settable(m_ls, -3);
|
||||
}
|
||||
|
||||
lua_setglobal(m_ls, m_lua_defined_arg_filters.c_str());
|
||||
|
||||
lua_newtable(m_ls);
|
||||
|
||||
for(auto &field : no_argument_filters)
|
||||
{
|
||||
lua_pushstring(m_ls, field.c_str());
|
||||
lua_pushnumber(m_ls, 1);
|
||||
lua_settable(m_ls, -3);
|
||||
}
|
||||
|
||||
lua_setglobal(m_ls, m_lua_defined_noarg_filters.c_str());
|
||||
|
||||
lua_pushlightuserdata(m_ls, m_sinsp_lua_parser);
|
||||
lua_pushlightuserdata(m_ls, m_json_lua_parser);
|
||||
|
@ -67,7 +67,8 @@ class falco_rules
|
||||
string m_lua_load_rules = "load_rules";
|
||||
string m_lua_ignored_syscalls = "ignored_syscalls";
|
||||
string m_lua_ignored_events = "ignored_events";
|
||||
string m_lua_defined_filters = "defined_filters";
|
||||
string m_lua_defined_arg_filters = "defined_arg_filters";
|
||||
string m_lua_defined_noarg_filters = "defined_noarg_filters";
|
||||
string m_lua_events = "events";
|
||||
string m_lua_syscalls = "syscalls";
|
||||
string m_lua_describe_rule = "describe_rule";
|
||||
|
Loading…
Reference in New Issue
Block a user