mirror of
https://github.com/falcosecurity/falco.git
synced 2025-08-13 11:55:50 +00:00
Add a source to rule_update_info
It's possible that someone might want to override a property for a non-syscall rule source. To assist in this, decode any source property for rules with append/override and save it in the rule_update_info object. For the source property only, the value for source can be empty e.g. 'source: ' or an empty string e.g. 'source: ""'. Both of those are considered valid but result in an empty source. A later change will ensure that the sources match up when appending/redefining/overriding/enabling. Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
parent
24f824dfb5
commit
a44b311333
@ -488,6 +488,7 @@ struct rule_update_info {
|
|||||||
context cond_ctx;
|
context cond_ctx;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::optional<std::string> cond;
|
std::optional<std::string> cond;
|
||||||
|
std::string source;
|
||||||
std::optional<std::string> output;
|
std::optional<std::string> output;
|
||||||
std::optional<std::string> desc;
|
std::optional<std::string> desc;
|
||||||
std::optional<std::set<std::string>> tags;
|
std::optional<std::set<std::string>> tags;
|
||||||
|
@ -53,7 +53,8 @@ static void decode_val_generic(const YAML::Node& item,
|
|||||||
const char* key,
|
const char* key,
|
||||||
T& out,
|
T& out,
|
||||||
const rule_loader::context& ctx,
|
const rule_loader::context& ctx,
|
||||||
bool optional) {
|
bool optional,
|
||||||
|
bool can_be_empty) {
|
||||||
const YAML::Node& val = item[key];
|
const YAML::Node& val = item[key];
|
||||||
|
|
||||||
if(!val.IsDefined() && optional) {
|
if(!val.IsDefined() && optional) {
|
||||||
@ -61,10 +62,19 @@ static void decode_val_generic(const YAML::Node& item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
THROW(!val.IsDefined(), std::string("Item has no mapping for key '") + key + "'", ctx);
|
THROW(!val.IsDefined(), std::string("Item has no mapping for key '") + key + "'", ctx);
|
||||||
|
if(val.IsNull() && can_be_empty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
THROW(val.IsNull(), std::string("Mapping for key '") + key + "' is empty", ctx);
|
THROW(val.IsNull(), std::string("Mapping for key '") + key + "' is empty", ctx);
|
||||||
|
|
||||||
rule_loader::context valctx(val, rule_loader::context::VALUE_FOR, key, ctx);
|
rule_loader::context valctx(val, rule_loader::context::VALUE_FOR, key, ctx);
|
||||||
THROW(!val.IsScalar(), "Value is not a scalar value", valctx);
|
THROW(!val.IsScalar(), "Value is not a scalar value", valctx);
|
||||||
|
|
||||||
|
if(val.Scalar().empty() && can_be_empty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
THROW(val.Scalar().empty(), "Value must be non-empty", valctx);
|
THROW(val.Scalar().empty(), "Value must be non-empty", valctx);
|
||||||
|
|
||||||
THROW(!YAML::convert<T>::decode(val, out), "Can't decode YAML scalar value", valctx);
|
THROW(!YAML::convert<T>::decode(val, out), "Can't decode YAML scalar value", valctx);
|
||||||
@ -75,9 +85,10 @@ static void decode_val_generic(const YAML::Node& item,
|
|||||||
const char* key,
|
const char* key,
|
||||||
std::optional<T>& out,
|
std::optional<T>& out,
|
||||||
const rule_loader::context& ctx,
|
const rule_loader::context& ctx,
|
||||||
bool optional) {
|
bool optional,
|
||||||
|
bool can_be_empty) {
|
||||||
T decoded;
|
T decoded;
|
||||||
decode_val_generic(item, key, decoded, ctx, optional);
|
decode_val_generic(item, key, decoded, ctx, optional, can_be_empty);
|
||||||
out = decoded;
|
out = decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,8 +98,9 @@ void rule_loader::reader::decode_val(const YAML::Node& item,
|
|||||||
T& out,
|
T& out,
|
||||||
const rule_loader::context& ctx) {
|
const rule_loader::context& ctx) {
|
||||||
bool optional = false;
|
bool optional = false;
|
||||||
|
bool can_be_empty = false;
|
||||||
|
|
||||||
decode_val_generic(item, key, out, ctx, optional);
|
decode_val_generic(item, key, out, ctx, optional, can_be_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
template void rule_loader::reader::decode_val<std::string>(const YAML::Node& item,
|
template void rule_loader::reader::decode_val<std::string>(const YAML::Node& item,
|
||||||
@ -102,8 +114,20 @@ void rule_loader::reader::decode_optional_val(const YAML::Node& item,
|
|||||||
T& out,
|
T& out,
|
||||||
const rule_loader::context& ctx) {
|
const rule_loader::context& ctx) {
|
||||||
bool optional = true;
|
bool optional = true;
|
||||||
|
bool can_be_empty = false;
|
||||||
|
|
||||||
decode_val_generic(item, key, out, ctx, optional);
|
decode_val_generic(item, key, out, ctx, optional, can_be_empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void rule_loader::reader::decode_optional_empty_val(const YAML::Node& item,
|
||||||
|
const char* key,
|
||||||
|
T& out,
|
||||||
|
const rule_loader::context& ctx) {
|
||||||
|
bool optional = true;
|
||||||
|
bool can_be_empty = true;
|
||||||
|
|
||||||
|
decode_val_generic(item, key, out, ctx, optional, can_be_empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
template void rule_loader::reader::decode_optional_val<std::string>(
|
template void rule_loader::reader::decode_optional_val<std::string>(
|
||||||
@ -591,6 +615,9 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
|
|||||||
|
|
||||||
rule_loader::context ctx(item, rule_loader::context::RULE, name, parent);
|
rule_loader::context ctx(item, rule_loader::context::RULE, name, parent);
|
||||||
|
|
||||||
|
std::string source = "";
|
||||||
|
decode_optional_empty_val(item, "source", source, ctx);
|
||||||
|
|
||||||
bool has_append_flag = false;
|
bool has_append_flag = false;
|
||||||
decode_optional_val(item, "append", has_append_flag, ctx);
|
decode_optional_val(item, "append", has_append_flag, ctx);
|
||||||
if(has_append_flag) {
|
if(has_append_flag) {
|
||||||
@ -648,6 +675,7 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
|
|||||||
"append",
|
"append",
|
||||||
"condition",
|
"condition",
|
||||||
ctx)) {
|
ctx)) {
|
||||||
|
v.source = source;
|
||||||
decode_val(item, "condition", v.cond, ctx);
|
decode_val(item, "condition", v.cond, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,6 +710,7 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
|
|||||||
"replace",
|
"replace",
|
||||||
"condition",
|
"condition",
|
||||||
ctx)) {
|
ctx)) {
|
||||||
|
v.source = source;
|
||||||
decode_val(item, "condition", v.cond, ctx);
|
decode_val(item, "condition", v.cond, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -765,6 +794,7 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
|
|||||||
} else if(has_append_flag) {
|
} else if(has_append_flag) {
|
||||||
rule_loader::rule_update_info v(ctx);
|
rule_loader::rule_update_info v(ctx);
|
||||||
v.name = name;
|
v.name = name;
|
||||||
|
v.source = source;
|
||||||
|
|
||||||
if(item["condition"].IsDefined()) {
|
if(item["condition"].IsDefined()) {
|
||||||
v.cond_ctx = rule_loader::context(item["condition"],
|
v.cond_ctx = rule_loader::context(item["condition"],
|
||||||
|
@ -66,6 +66,11 @@ public:
|
|||||||
const char* key,
|
const char* key,
|
||||||
T& out,
|
T& out,
|
||||||
const rule_loader::context& ctx);
|
const rule_loader::context& ctx);
|
||||||
|
template<typename T>
|
||||||
|
static void decode_optional_empty_val(const YAML::Node& item,
|
||||||
|
const char* key,
|
||||||
|
T& out,
|
||||||
|
const rule_loader::context& ctx);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void read_item(rule_loader::configuration& cfg,
|
virtual void read_item(rule_loader::configuration& cfg,
|
||||||
|
Loading…
Reference in New Issue
Block a user