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:
Mark Stemm 2019-06-27 16:38:09 -07:00 committed by Mark Stemm
parent c1035ce4de
commit 047f12d0f6
3 changed files with 78 additions and 29 deletions

View File

@ -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

View File

@ -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);

View File

@ -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";