From 5adf991aa6af47b156a994f108bded91af88d40c Mon Sep 17 00:00:00 2001 From: Mark Stemm Date: Wed, 16 Oct 2024 13:45:21 -0700 Subject: [PATCH] When overriding rules, ensure that the sources match In places where a second rule definition might replace, append to, or replace items from a base rule, ensure that the source of the second rule definiton matches the first. This already existed for defines, but for other changes. There was a bug where a second definition might exist for a different source, but the additional rule was used anyway. This now returns the same error for these other changes e.g. "Rule has been re-defined..." as define. Signed-off-by: Mark Stemm --- userspace/engine/rule_loader_collector.cpp | 31 +++++++++++++++++----- userspace/engine/rule_loader_collector.h | 3 +++ 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/userspace/engine/rule_loader_collector.cpp b/userspace/engine/rule_loader_collector.cpp index 18103950db2..ee0fdd83953 100644 --- a/userspace/engine/rule_loader_collector.cpp +++ b/userspace/engine/rule_loader_collector.cpp @@ -182,10 +182,7 @@ void rule_loader::collector::append(configuration& cfg, macro_info& info) { } void rule_loader::collector::define(configuration& cfg, rule_info& info) { - const 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 prev __attribute__((unused)) = find_prev_rule(info); const auto* source = cfg.sources.at(info.source); if(!source) { @@ -205,7 +202,7 @@ void rule_loader::collector::define(configuration& cfg, rule_info& info) { } void rule_loader::collector::append(configuration& cfg, rule_update_info& info) { - auto prev = m_rule_infos.at(info.name); + auto prev = find_prev_rule(info); THROW(!prev, ERROR_NO_PREVIOUS_RULE_APPEND, info.ctx); THROW(!info.has_any_value(), @@ -275,7 +272,7 @@ void rule_loader::collector::append(configuration& cfg, rule_update_info& info) } void rule_loader::collector::selective_replace(configuration& cfg, rule_update_info& info) { - auto prev = m_rule_infos.at(info.name); + auto prev = find_prev_rule(info); THROW(!prev, ERROR_NO_PREVIOUS_RULE_REPLACE, info.ctx); THROW(!info.has_any_value(), @@ -330,6 +327,28 @@ void rule_loader::collector::selective_replace(configuration& cfg, rule_update_i replace_info(prev, info, m_cur_index++); } +template +rule_loader::rule_info* rule_loader::collector::find_prev_rule(ruleInfo& info) { + auto ret = m_rule_infos.at(info.name); + + std::string old_source = (ret ? ret->source : ""); + + if(old_source == "") { + old_source = falco_common::syscall_source; + } + + std::string new_source = info.source; + if(new_source == "") { + new_source = falco_common::syscall_source; + } + + THROW(ret && (old_source != new_source), + "Rule has been re-defined with a different source", + info.ctx); + + return ret; +} + void rule_loader::collector::enable(configuration& cfg, rule_info& info) { auto prev = m_rule_infos.at(info.name); THROW(!prev, "Rule has 'enabled' key but no rule by that name already exists", info.ctx); diff --git a/userspace/engine/rule_loader_collector.h b/userspace/engine/rule_loader_collector.h index 6abf862961c..d995f6c54d0 100644 --- a/userspace/engine/rule_loader_collector.h +++ b/userspace/engine/rule_loader_collector.h @@ -97,6 +97,9 @@ class collector { virtual void selective_replace(configuration& cfg, rule_update_info& info); private: + template + rule_info* find_prev_rule(ruleInfo& info); + uint32_t m_cur_index; indexed_vector m_rule_infos; indexed_vector m_macro_infos;