update(userspace): optimizations in validation and description steps

Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
Jason Dellaluce
2023-11-20 16:20:26 +00:00
committed by poiana
parent 67542ec88e
commit 390a13bd40
3 changed files with 70 additions and 67 deletions

View File

@@ -508,9 +508,9 @@ std::size_t falco_engine::add_source(const std::string &source,
template <typename T> inline nlohmann::json sequence_to_json_array(const T& seq) template <typename T> inline nlohmann::json sequence_to_json_array(const T& seq)
{ {
nlohmann::json ret = nlohmann::json::array(); nlohmann::json ret = nlohmann::json::array();
for (auto it = seq.begin(); it != seq.end(); it++) for (const auto& v : seq)
{ {
ret.push_back(*it); ret.push_back(v);
} }
return ret; return ret;
} }
@@ -547,13 +547,13 @@ nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<
nlohmann::json alternative; nlohmann::json alternative;
alternative["name"] = req[i].name; alternative["name"] = req[i].name;
alternative["version"] = req[i].version; alternative["version"] = req[i].version;
alternatives.push_back(alternative); alternatives.push_back(std::move(alternative));
} }
r["alternatives"] = alternatives; r["alternatives"] = std::move(alternatives);
plugin_versions.push_back(r); plugin_versions.push_back(std::move(r));
} }
output["required_plugin_versions"] = plugin_versions; output["required_plugin_versions"] = std::move(plugin_versions);
// Store information about rules // Store information about rules
nlohmann::json rules_array = nlohmann::json::array(); nlohmann::json rules_array = nlohmann::json::array();
@@ -562,9 +562,9 @@ nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<
auto info = m_rule_collector.rules().at(r.name); auto info = m_rule_collector.rules().at(r.name);
nlohmann::json rule; nlohmann::json rule;
get_json_details(rule, r, *info, plugins); get_json_details(rule, r, *info, plugins);
rules_array.push_back(rule); rules_array.push_back(std::move(rule));
} }
output["rules"] = rules_array; output["rules"] = std::move(rules_array);
// Store information about macros // Store information about macros
nlohmann::json macros_array = nlohmann::json::array(); nlohmann::json macros_array = nlohmann::json::array();
@@ -573,9 +573,9 @@ nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<
auto info = m_rule_collector.macros().at(m.name); auto info = m_rule_collector.macros().at(m.name);
nlohmann::json macro; nlohmann::json macro;
get_json_details(macro, m, *info, plugins); get_json_details(macro, m, *info, plugins);
macros_array.push_back(macro); macros_array.push_back(std::move(macro));
} }
output["macros"] = macros_array; output["macros"] = std::move(macros_array);
// Store information about lists // Store information about lists
nlohmann::json lists_array = nlohmann::json::array(); nlohmann::json lists_array = nlohmann::json::array();
@@ -584,9 +584,9 @@ nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<
auto info = m_rule_collector.lists().at(l.name); auto info = m_rule_collector.lists().at(l.name);
nlohmann::json list; nlohmann::json list;
get_json_details(list, l, *info, plugins); get_json_details(list, l, *info, plugins);
lists_array.push_back(list); lists_array.push_back(std::move(list));
} }
output["lists"] = lists_array; output["lists"] = std::move(lists_array);
} }
else else
{ {
@@ -601,8 +601,8 @@ nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<
nlohmann::json rule; nlohmann::json rule;
get_json_details(rule, *r, *ri, plugins); get_json_details(rule, *r, *ri, plugins);
nlohmann::json rules_array = nlohmann::json::array(); nlohmann::json rules_array = nlohmann::json::array();
rules_array.push_back(rule); rules_array.push_back(std::move(rule));
output["rules"] = rules_array; output["rules"] = std::move(rules_array);
} }
return output; return output;
@@ -619,13 +619,13 @@ void falco_engine::get_json_details(
// Fill general rule information // Fill general rule information
rule_info["name"] = r.name; rule_info["name"] = r.name;
rule_info["condition"] = info.cond; rule_info["condition"] = info.cond;
rule_info["priority"] = format_priority(r.priority, false); rule_info["priority"] = std::move(format_priority(r.priority, false));
rule_info["output"] = info.output; rule_info["output"] = info.output;
rule_info["description"] = r.description; rule_info["description"] = r.description;
rule_info["enabled"] = info.enabled; rule_info["enabled"] = info.enabled;
rule_info["source"] = r.source; rule_info["source"] = r.source;
rule_info["tags"] = sequence_to_json_array(info.tags); rule_info["tags"] = std::move(sequence_to_json_array(info.tags));
out["info"] = rule_info; out["info"] = std::move(rule_info);
// Parse rule condition and build the non-compiled AST // Parse rule condition and build the non-compiled AST
// Assumption: no error because rules have already been loaded. // Assumption: no error because rules have already been loaded.
@@ -648,19 +648,19 @@ void falco_engine::get_json_details(
filter_details_resolver().run(ast.get(), details); filter_details_resolver().run(ast.get(), details);
filter_details_resolver().run(r.condition.get(), compiled_details); filter_details_resolver().run(r.condition.get(), compiled_details);
out["details"]["macros"] = sequence_to_json_array(details.macros); out["details"]["macros"] = std::move(sequence_to_json_array(details.macros));
out["details"]["lists"] = sequence_to_json_array(details.lists); out["details"]["lists"] = std::move(sequence_to_json_array(details.lists));
out["details"]["condition_operators"] = sequence_to_json_array(compiled_details.operators); out["details"]["condition_operators"] = std::move(sequence_to_json_array(compiled_details.operators));
out["details"]["condition_fields"] = sequence_to_json_array(compiled_details.fields); out["details"]["condition_fields"] = std::move(sequence_to_json_array(compiled_details.fields));
// Get fields from output string // Get fields from output string
auto fmt = create_formatter(r.source, r.output); auto fmt = create_formatter(r.source, r.output);
std::vector<std::string> out_fields; std::vector<std::string> out_fields;
fmt->get_field_names(out_fields); fmt->get_field_names(out_fields);
out["details"]["output_fields"] = sequence_to_json_array(out_fields); out["details"]["output_fields"] = std::move(sequence_to_json_array(out_fields));
// Get fields from exceptions // Get fields from exceptions
out["details"]["exception_fields"] = sequence_to_json_array(r.exception_fields); out["details"]["exception_fields"] = std::move(sequence_to_json_array(r.exception_fields));
// Get names and operators from exceptions // Get names and operators from exceptions
std::unordered_set<std::string> exception_names; std::unordered_set<std::string> exception_names;
@@ -691,16 +691,16 @@ void falco_engine::get_json_details(
exception_operators.insert(e.comps.item); exception_operators.insert(e.comps.item);
} }
} }
out["details"]["exception_names"] = sequence_to_json_array(exception_names); out["details"]["exception_names"] = std::move(sequence_to_json_array(exception_names));
out["details"]["exception_operators"] = sequence_to_json_array(exception_operators); out["details"]["exception_operators"] = std::move(sequence_to_json_array(exception_operators));
// Store event types // Store event types
nlohmann::json events; nlohmann::json events;
get_json_evt_types(events, info.source, r.condition.get()); get_json_evt_types(events, info.source, r.condition.get());
out["details"]["events"] = events; out["details"]["events"] = std::move(events);
// Store compiled condition and output // Store compiled condition and output
out["details"]["condition_compiled"] = libsinsp::filter::ast::as_string(r.condition.get()); out["details"]["condition_compiled"] = std::move(libsinsp::filter::ast::as_string(r.condition.get()));
out["details"]["output_compiled"] = r.output; out["details"]["output_compiled"] = r.output;
// Compute the plugins that are actually used by this rule. This is involves: // Compute the plugins that are actually used by this rule. This is involves:
@@ -713,7 +713,7 @@ void falco_engine::get_json_details(
// note: the condition's AST accounts for all the resolved refs and exceptions // note: the condition's AST accounts for all the resolved refs and exceptions
compiled_details.fields.insert(out_fields.begin(), out_fields.end()); compiled_details.fields.insert(out_fields.begin(), out_fields.end());
get_json_used_plugins(used_plugins, info.source, compiled_details.evtnames, compiled_details.fields, plugins); get_json_used_plugins(used_plugins, info.source, compiled_details.evtnames, compiled_details.fields, plugins);
out["details"]["plugins"] = used_plugins; out["details"]["plugins"] = std::move(used_plugins);
} }
void falco_engine::get_json_details( void falco_engine::get_json_details(
@@ -726,7 +726,7 @@ void falco_engine::get_json_details(
macro_info["name"] = m.name; macro_info["name"] = m.name;
macro_info["condition"] = info.cond; macro_info["condition"] = info.cond;
out["info"] = macro_info; out["info"] = std::move(macro_info);
// Parse the macro condition and build the non-compiled AST // Parse the macro condition and build the non-compiled AST
// Assumption: no exception because rules have already been loaded. // Assumption: no exception because rules have already been loaded.
@@ -750,18 +750,18 @@ void falco_engine::get_json_details(
filter_details_resolver().run(m.condition.get(), compiled_details); filter_details_resolver().run(m.condition.get(), compiled_details);
out["details"]["used"] = m.used; out["details"]["used"] = m.used;
out["details"]["macros"] = sequence_to_json_array(details.macros); out["details"]["macros"] = std::move(sequence_to_json_array(details.macros));
out["details"]["lists"] = sequence_to_json_array(details.lists); out["details"]["lists"] = std::move(sequence_to_json_array(details.lists));
out["details"]["condition_operators"] = sequence_to_json_array(compiled_details.operators); out["details"]["condition_operators"] = std::move(sequence_to_json_array(compiled_details.operators));
out["details"]["condition_fields"] = sequence_to_json_array(compiled_details.fields); out["details"]["condition_fields"] = std::move(sequence_to_json_array(compiled_details.fields));
// Store event types // Store event types
nlohmann::json events; nlohmann::json events;
get_json_evt_types(events, "", m.condition.get()); get_json_evt_types(events, "", m.condition.get());
out["details"]["events"] = events; out["details"]["events"] = std::move(events);
// Store compiled condition // Store compiled condition
out["details"]["condition_compiled"] = libsinsp::filter::ast::as_string(m.condition.get()); out["details"]["condition_compiled"] = std::move(libsinsp::filter::ast::as_string(m.condition.get()));
// Compute the plugins that are actually used by this macro. // Compute the plugins that are actually used by this macro.
// Note: macros have no specific source, we need to set an empty list of used // Note: macros have no specific source, we need to set an empty list of used
@@ -769,7 +769,7 @@ void falco_engine::get_json_details(
// if a macro uses a plugin's field, we can't be sure which plugin actually // if a macro uses a plugin's field, we can't be sure which plugin actually
// is used until we resolve the macro ref in a rule providing a source for // is used until we resolve the macro ref in a rule providing a source for
// disambiguation. // disambiguation.
out["details"]["plugins"] = nlohmann::json::array(); out["details"]["plugins"] = std::move(nlohmann::json::array());
} }
void falco_engine::get_json_details( void falco_engine::get_json_details(
@@ -794,15 +794,15 @@ void falco_engine::get_json_details(
lists.insert(i); lists.insert(i);
continue; continue;
} }
items.push_back(i); items.push_back(std::move(i));
} }
list_info["items"] = items; list_info["items"] = std::move(items);
out["info"] = list_info; out["info"] = std::move(list_info);
out["details"]["used"] = l.used; out["details"]["used"] = l.used;
out["details"]["lists"] = sequence_to_json_array(lists); out["details"]["lists"] = std::move(sequence_to_json_array(lists));
out["details"]["items_compiled"] = sequence_to_json_array(l.items); out["details"]["items_compiled"] = std::move(sequence_to_json_array(l.items));
out["details"]["plugins"] = nlohmann::json::array(); // always empty out["details"]["plugins"] = std::move(nlohmann::json::array()); // always empty
} }
void falco_engine::get_json_evt_types( void falco_engine::get_json_evt_types(
@@ -838,14 +838,17 @@ void falco_engine::get_json_used_plugins(
// note: condition and output fields may have an argument, so // note: condition and output fields may have an argument, so
// we need to isolate the field names // we need to isolate the field names
std::unordered_set<std::string> fieldnames; std::unordered_set<std::string> fieldnames;
for (auto f: fields) for (const auto &f: fields)
{ {
auto argpos = f.find('['); auto argpos = f.find('[');
if (argpos != std::string::npos) if (argpos != std::string::npos)
{ {
f = f.substr(0, argpos); fieldnames.insert(f.substr(0, argpos));
}
else
{
fieldnames.insert(f);
} }
fieldnames.insert(f);
} }
std::unordered_set<std::string> used_plugins; std::unordered_set<std::string> used_plugins;

View File

@@ -83,12 +83,12 @@ static void build_rule_exception_infos(
std::string& condition) std::string& condition)
{ {
std::string tmp; std::string tmp;
for (auto &ex : exceptions) for (const auto &ex : exceptions)
{ {
std::string icond; std::string icond;
if(!ex.fields.is_list) if(!ex.fields.is_list)
{ {
for (auto &val : ex.values) for (const auto &val : ex.values)
{ {
THROW(val.is_list, THROW(val.is_list,
"Expected values array to contain a list of strings", "Expected values array to contain a list of strings",
@@ -107,7 +107,7 @@ static void build_rule_exception_infos(
else else
{ {
icond = "("; icond = "(";
for (auto &values : ex.values) for (const auto &values : ex.values)
{ {
THROW(ex.fields.items.size() != values.items.size(), THROW(ex.fields.items.size() != values.items.size(),
"Fields and values lists must have equal length", "Fields and values lists must have equal length",
@@ -116,13 +116,13 @@ static void build_rule_exception_infos(
icond += "("; icond += "(";
uint32_t k = 0; uint32_t k = 0;
std::string istr; std::string istr;
for (auto &field : ex.fields.items) for (const auto &field : ex.fields.items)
{ {
icond += k == 0 ? "" : " and "; icond += k == 0 ? "" : " and ";
if (values.items[k].is_list) if (values.items[k].is_list)
{ {
istr = "("; istr = "(";
for (auto &v : values.items[k].items) for (const auto &v : values.items[k].items)
{ {
tmp = v.item; tmp = v.item;
quote_item(tmp); quote_item(tmp);
@@ -212,7 +212,7 @@ static bool resolve_list(std::string& cnd, const falco_list& list)
} }
// create substitution string by concatenating all values // create substitution string by concatenating all values
std::string sub = ""; std::string sub = "";
for (auto &v : list.items) for (const auto &v : list.items)
{ {
if (!sub.empty()) if (!sub.empty())
{ {
@@ -262,7 +262,7 @@ static void resolve_macros(
const rule_loader::context &ctx) const rule_loader::context &ctx)
{ {
filter_macro_resolver macro_resolver; filter_macro_resolver macro_resolver;
for (auto &m : infos) for (const auto &m : infos)
{ {
if (m.index < visibility) if (m.index < visibility)
{ {
@@ -287,7 +287,7 @@ static void resolve_macros(
THROW(true, errmsg, cond_ctx); THROW(true, errmsg, cond_ctx);
} }
for (auto &it : macro_resolver.get_resolved_macros()) for (const auto &it : macro_resolver.get_resolved_macros())
{ {
macros.at(it.first)->used = true; macros.at(it.first)->used = true;
} }
@@ -346,13 +346,13 @@ void rule_loader::compiler::compile_list_infos(
indexed_vector<falco_list>& out) const indexed_vector<falco_list>& out) const
{ {
std::string tmp; std::string tmp;
std::vector<std::string> used; std::list<std::string> used;
for (auto &list : col.lists()) falco_list v;
for (const auto &list : col.lists())
{ {
falco_list v;
v.name = list.name; v.name = list.name;
v.items.clear(); v.items.clear();
for (auto &item : list.items) for (const auto &item : list.items)
{ {
const auto ref = col.lists().at(item); const auto ref = col.lists().at(item);
if (ref && ref->index < list.visibility) if (ref && ref->index < list.visibility)
@@ -375,7 +375,7 @@ void rule_loader::compiler::compile_list_infos(
auto list_id = out.insert(v, v.name); auto list_id = out.insert(v, v.name);
out.at(list_id)->id = list_id; out.at(list_id)->id = list_id;
} }
for (auto &v : used) for (const auto &v : used)
{ {
out.at(v)->used = true; out.at(v)->used = true;
} }
@@ -388,7 +388,7 @@ void rule_loader::compiler::compile_macros_infos(
indexed_vector<falco_list>& lists, indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& out) const indexed_vector<falco_macro>& out) const
{ {
for (auto &m : col.macros()) for (const auto &m : col.macros())
{ {
falco_macro entry; falco_macro entry;
entry.name = m.name; entry.name = m.name;
@@ -422,7 +422,7 @@ void rule_loader::compiler::compile_rule_infos(
std::string err, condition; std::string err, condition;
std::set<falco::load_result::load_result::warning_code> warn_codes; std::set<falco::load_result::load_result::warning_code> warn_codes;
filter_warning_resolver warn_resolver; filter_warning_resolver warn_resolver;
for (auto &r : col.rules()) for (const auto &r : col.rules())
{ {
// skip the rule if it has an unknown source // skip the rule if it has an unknown source
if (r.unknown_source) if (r.unknown_source)
@@ -453,7 +453,7 @@ void rule_loader::compiler::compile_rule_infos(
warn_codes.clear(); warn_codes.clear();
if (warn_resolver.run(rule.condition.get(), warn_codes)) if (warn_resolver.run(rule.condition.get(), warn_codes))
{ {
for (auto &w : warn_codes) for (const auto &w : warn_codes)
{ {
cfg.res->add_warning(w, "", r.ctx); cfg.res->add_warning(w, "", r.ctx);
} }
@@ -555,7 +555,7 @@ void rule_loader::compiler::compile(
} }
// print info on any dangling lists or macros that were not used anywhere // print info on any dangling lists or macros that were not used anywhere
for (auto &m : out.macros) for (const auto &m : out.macros)
{ {
if (!m.used) if (!m.used)
{ {
@@ -565,7 +565,7 @@ void rule_loader::compiler::compile(
macro_info_from_name(col, m.name)->ctx); macro_info_from_name(col, m.name)->ctx);
} }
} }
for (auto &l : out.lists) for (const auto &l : out.lists)
{ {
if (!l.used) if (!l.used)
{ {

View File

@@ -125,7 +125,7 @@ falco::app::run_result falco::app::actions::validate_rules_files(falco::app::sta
// printout of `-L` option // printout of `-L` option
nlohmann::json describe_res; nlohmann::json describe_res;
if (s.options.describe_all_rules || !s.options.describe_rule.empty()) if (successful && (s.options.describe_all_rules || !s.options.describe_rule.empty()))
{ {
std::string* rptr = !s.options.describe_rule.empty() ? &(s.options.describe_rule) : nullptr; std::string* rptr = !s.options.describe_rule.empty() ? &(s.options.describe_rule) : nullptr;
const auto& plugins = s.offline_inspector->get_plugin_manager()->plugins(); const auto& plugins = s.offline_inspector->get_plugin_manager()->plugins();
@@ -136,16 +136,16 @@ falco::app::run_result falco::app::actions::validate_rules_files(falco::app::sta
{ {
nlohmann::json res; nlohmann::json res;
res["falco_load_results"] = results; res["falco_load_results"] = results;
if (!describe_res.empty()) if (!describe_res.empty() && successful)
{ {
res["falco_describe_results"] = describe_res; res["falco_describe_results"] = std::move(describe_res);
} }
std::cout << res.dump() << std::endl; std::cout << res.dump() << std::endl;
} }
else else
{ {
std::cout << summary << std::endl; std::cout << summary << std::endl;
if (!describe_res.empty()) if (!describe_res.empty() && successful)
{ {
std::cout << std::endl; std::cout << std::endl;
format_described_rules_as_text(describe_res, std::cout); format_described_rules_as_text(describe_res, std::cout);