Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(userspace/engine): support appending to unknown sources #2753

Merged
merged 1 commit into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions userspace/engine/falco_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -568,12 +568,12 @@ void falco_engine::describe_rule(std::string *rule, bool json) const
output["lists"] = lists_array;

json_str = writer.write(output);
}
}
else
{
// 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");
}
Expand Down
4 changes: 2 additions & 2 deletions userspace/engine/rule_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
}

Expand Down
1 change: 1 addition & 0 deletions userspace/engine/rule_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
59 changes: 35 additions & 24 deletions userspace/engine/rule_loader_collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -76,11 +76,14 @@ static void validate_exception_info(
std::string("'") + v.item + "' is not a supported comparison operator",
ex.ctx);
}
for (auto &v : ex.fields.items)
if (source)
{
THROW(!source.is_field_defined(v.item),
std::string("'") + v.item + "' is not a supported filter field",
ex.ctx);
for (auto &v : ex.fields.items)
{
THROW(!source->is_field_defined(v.item),
std::string("'") + v.item + "' is not a supported filter field",
ex.ctx);
}
}
}
else
Expand All @@ -96,9 +99,12 @@ 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),
std::string("'") + ex.fields.item + "' is not a supported filter field",
ex.ctx);
if (source)
{
THROW(!source->is_field_defined(ex.fields.item),
std::string("'") + ex.fields.item + "' is not a supported filter field",
ex.ctx);
}
}
}

Expand Down Expand Up @@ -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 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);
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);

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);
"Rule exception item must have fields property with a list of fields",
ex.ctx);
validate_exception_info(source, ex);
}

define_info(m_rule_infos, info, m_cur_index++);
Expand All @@ -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
THROW(!source,
std::string("Unknown source ") + prev->source,
info.ctx);
// 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())
{
Expand All @@ -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
Expand Down
11 changes: 8 additions & 3 deletions userspace/engine/rule_loader_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,17 +388,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,
Expand Down
Loading