mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-07 01:30:13 +00:00
fix(userspace/engine): support appending to unknown sources
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
@@ -573,7 +573,7 @@ void falco_engine::describe_rule(std::string *rule, bool json) const
|
||||
{
|
||||
// build json information for just the specified rule
|
||||
auto ri = m_rule_collector.rules().at(*rule);
|
||||
if(ri == nullptr)
|
||||
if(ri == nullptr || ri->unknown_source)
|
||||
{
|
||||
throw falco_exception("Rule \"" + *rule + "\" is not loaded");
|
||||
}
|
||||
|
@@ -547,8 +547,8 @@ rule_loader::rule_exception_info::rule_exception_info(context &ctx)
|
||||
|
||||
rule_loader::rule_info::rule_info(context &ctx)
|
||||
: ctx(ctx), cond_ctx(ctx), output_ctx(ctx), index(0), visibility(0),
|
||||
priority(falco_common::PRIORITY_DEBUG), enabled(true),
|
||||
warn_evttypes(true), skip_if_unknown_filter(false)
|
||||
unknown_source(false), priority(falco_common::PRIORITY_DEBUG),
|
||||
enabled(true), warn_evttypes(true), skip_if_unknown_filter(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -449,6 +449,7 @@ namespace rule_loader
|
||||
context output_ctx;
|
||||
size_t index;
|
||||
size_t visibility;
|
||||
bool unknown_source;
|
||||
std::string name;
|
||||
std::string cond;
|
||||
std::string source;
|
||||
|
@@ -54,7 +54,7 @@ static inline void append_info(T* prev, T& info, uint32_t id)
|
||||
}
|
||||
|
||||
static void validate_exception_info(
|
||||
const falco_source& source,
|
||||
const falco_source* source,
|
||||
rule_loader::rule_exception_info &ex)
|
||||
{
|
||||
if (ex.fields.is_list)
|
||||
@@ -76,13 +76,16 @@ static void validate_exception_info(
|
||||
std::string("'") + v.item + "' is not a supported comparison operator",
|
||||
ex.ctx);
|
||||
}
|
||||
if (source)
|
||||
{
|
||||
for (auto &v : ex.fields.items)
|
||||
{
|
||||
THROW(!source.is_field_defined(v.item),
|
||||
THROW(!source->is_field_defined(v.item),
|
||||
std::string("'") + v.item + "' is not a supported filter field",
|
||||
ex.ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ex.comps.is_valid())
|
||||
@@ -96,11 +99,14 @@ static void validate_exception_info(
|
||||
THROW((ex.comps.item != "in" && ex.comps.item != "pmatch" && ex.comps.item != "intersects"),
|
||||
"When fields is a single value, comps must be one of (in, pmatch, intersects)",
|
||||
ex.ctx);
|
||||
THROW(!source.is_field_defined(ex.fields.item),
|
||||
if (source)
|
||||
{
|
||||
THROW(!source->is_field_defined(ex.fields.item),
|
||||
std::string("'") + ex.fields.item + "' is not a supported filter field",
|
||||
ex.ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rule_loader::collector::clear()
|
||||
{
|
||||
@@ -200,26 +206,25 @@ void rule_loader::collector::append(configuration& cfg, macro_info& info)
|
||||
|
||||
void rule_loader::collector::define(configuration& cfg, rule_info& info)
|
||||
{
|
||||
auto source = cfg.sources.at(info.source);
|
||||
if (!source)
|
||||
{
|
||||
cfg.res->add_warning(falco::load_result::LOAD_UNKNOWN_SOURCE,
|
||||
"Unknown source " + info.source + ", skipping",
|
||||
info.ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
auto prev = m_rule_infos.at(info.name);
|
||||
THROW(prev && prev->source != info.source,
|
||||
"Rule has been re-defined with a different source",
|
||||
info.ctx);
|
||||
|
||||
auto source = cfg.sources.at(info.source);
|
||||
if (!source)
|
||||
{
|
||||
info.unknown_source = true;
|
||||
cfg.res->add_warning(falco::load_result::LOAD_UNKNOWN_SOURCE,
|
||||
"Unknown source " + info.source + ", skipping",
|
||||
info.ctx);
|
||||
}
|
||||
for (auto &ex : info.exceptions)
|
||||
{
|
||||
THROW(!ex.fields.is_valid(),
|
||||
"Rule exception item must have fields property with a list of fields",
|
||||
ex.ctx);
|
||||
validate_exception_info(*source, ex);
|
||||
validate_exception_info(source, ex);
|
||||
}
|
||||
|
||||
define_info(m_rule_infos, info, m_cur_index++);
|
||||
@@ -236,11 +241,17 @@ void rule_loader::collector::append(configuration& cfg, rule_info& info)
|
||||
"Appended rule must have exceptions or condition property",
|
||||
info.ctx);
|
||||
|
||||
auto source = cfg.sources.at(prev->source);
|
||||
// note: this is not supposed to happen
|
||||
// note: source can be nullptr in case we've collected a
|
||||
// rule for which the source is unknown
|
||||
falco_source* source = nullptr;
|
||||
if (!prev->unknown_source)
|
||||
{
|
||||
// note: if the source is not unknown, this should not return nullptr
|
||||
source = cfg.sources.at(prev->source);
|
||||
THROW(!source,
|
||||
std::string("Unknown source ") + prev->source,
|
||||
info.ctx);
|
||||
}
|
||||
|
||||
if (!info.cond.empty())
|
||||
{
|
||||
@@ -261,7 +272,7 @@ void rule_loader::collector::append(configuration& cfg, rule_info& info)
|
||||
THROW(ex.values.empty(),
|
||||
"Rule exception must have values property with a list of values",
|
||||
ex.ctx);
|
||||
validate_exception_info(*source, ex);
|
||||
validate_exception_info(source, ex);
|
||||
prev->exceptions.push_back(ex);
|
||||
}
|
||||
else
|
||||
|
@@ -394,17 +394,22 @@ void rule_loader::compiler::compile_rule_infos(
|
||||
filter_warning_resolver warn_resolver;
|
||||
for (auto &r : col.rules())
|
||||
{
|
||||
// skip the rule if it has an unknown source
|
||||
if (r.unknown_source)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip the rule if below the minimum priority
|
||||
if (r.priority > cfg.min_priority)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// note: this should not be nullptr if the source is not unknown
|
||||
auto source = cfg.sources.at(r.source);
|
||||
// note: this is not supposed to happen
|
||||
|
||||
THROW(!source,
|
||||
std::string("Unknown source ") + r.source,
|
||||
std::string("Unknown source at compile-time") + r.source,
|
||||
r.ctx);
|
||||
|
||||
// build filter AST by parsing the condition, building exceptions,
|
||||
|
Reference in New Issue
Block a user