Skip to content

Commit

Permalink
Also include all exception fields in rule_result
Browse files Browse the repository at this point in the history
When returning a rule_result struct, also include a set of field names
used by all exceptions for this rule. This may make building exception
values a bit easier.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
  • Loading branch information
mstemm authored and poiana committed Jan 19, 2021
1 parent 49b8f87 commit 8c4040b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 38 deletions.
61 changes: 28 additions & 33 deletions userspace/engine/falco_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,31 +302,9 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_sinsp_event(sinsp_ev
}

unique_ptr<struct rule_result> res(new rule_result());
res->source = "syscall";

std::lock_guard<std::mutex> guard(m_ls_semaphore);
lua_getglobal(m_ls, lua_on_event.c_str());
if(lua_isfunction(m_ls, -1))
{
lua_pushnumber(m_ls, ev->get_check_id());

if(lua_pcall(m_ls, 1, 3, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
string err = "Error invoking function output: " + string(lerr);
throw falco_exception(err);
}
res->evt = ev;
const char *p = lua_tostring(m_ls, -3);
res->rule = p;
res->source = "syscall";
res->priority_num = (falco_common::priority_type) lua_tonumber(m_ls, -2);
res->format = lua_tostring(m_ls, -1);
lua_pop(m_ls, 3);
}
else
{
throw falco_exception("No function " + lua_on_event + " found in lua compiler module");
}
populate_rule_result(res, ev);

return res;
}
Expand All @@ -350,33 +328,50 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_k8s_audit_event(json
}

unique_ptr<struct rule_result> res(new rule_result());
res->source = "k8s_audit";

populate_rule_result(res, ev);

return res;
}

void falco_engine::populate_rule_result(unique_ptr<struct rule_result> &res, gen_event *ev)
{
std::lock_guard<std::mutex> guard(m_ls_semaphore);
lua_getglobal(m_ls, lua_on_event.c_str());
if(lua_isfunction(m_ls, -1))
{
lua_pushnumber(m_ls, ev->get_check_id());

if(lua_pcall(m_ls, 1, 3, 0) != 0)
if(lua_pcall(m_ls, 1, 4, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
string err = "Error invoking function output: " + string(lerr);
throw falco_exception(err);
}
res->evt = ev;
const char *p = lua_tostring(m_ls, -3);
const char *p = lua_tostring(m_ls, -4);
res->rule = p;
res->source = "k8s_audit";
res->priority_num = (falco_common::priority_type) lua_tonumber(m_ls, -2);
res->format = lua_tostring(m_ls, -1);
lua_pop(m_ls, 3);
res->evt = ev;
res->priority_num = (falco_common::priority_type) lua_tonumber(m_ls, -3);
res->format = lua_tostring(m_ls, -2);

// Exception fields are passed back as a table
lua_pushnil(m_ls); /* first key */
while (lua_next(m_ls, -2) != 0) {
// key is at index -2, value is at index
// -1. We want the keys.
res->exception_fields.insert(luaL_checkstring(m_ls, -2));

// Remove value, keep key for next iteration
lua_pop(m_ls, 1);
}

lua_pop(m_ls, 4);
}
else
{
throw falco_exception("No function " + lua_on_event + " found in lua compiler module");
}

return res;
}

bool falco_engine::parse_k8s_audit_json(nlohmann::json &j, std::list<json_event> &evts, bool top)
Expand Down
3 changes: 3 additions & 0 deletions userspace/engine/falco_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ class falco_engine : public falco_common
std::string source;
falco_common::priority_type priority_num;
std::string format;
std::set<std::string> exception_fields;
};

//
Expand Down Expand Up @@ -262,6 +263,8 @@ class falco_engine : public falco_common
std::unique_ptr<falco_sinsp_ruleset> m_sinsp_rules;
std::unique_ptr<falco_ruleset> m_k8s_audit_rules;

void populate_rule_result(unique_ptr<struct rule_result> &res, gen_event *ev);

//
// Here's how the sampling ratio and multiplier influence
// whether or not an event is dropped in
Expand Down
25 changes: 20 additions & 5 deletions userspace/engine/lua/rule_loader.lua
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,8 @@ function load_rules_doc(rules_mgr, doc, load_state)
end

-- cond and not ((proc.name=apk and fd.directory=/usr/lib/alpine) or (proc.name=npm and fd.directory=/usr/node/bin) or ...)
function build_exception_condition_string_multi_fields(eitem)
-- Populates exfields with all fields used
function build_exception_condition_string_multi_fields(eitem, exfields)

local fields = eitem['fields']
local comps = eitem['comps']
Expand Down Expand Up @@ -721,6 +722,7 @@ function build_exception_condition_string_multi_fields(eitem)
end

icond = icond..fields[k].." "..comps[k].." "..istr
exfields[fields[k]] = true
end

icond=icond..")"
Expand All @@ -737,7 +739,7 @@ function build_exception_condition_string_multi_fields(eitem)

end

function build_exception_condition_string_single_field(eitem)
function build_exception_condition_string_single_field(eitem, exfields)

local icond = ""

Expand All @@ -753,6 +755,8 @@ function build_exception_condition_string_single_field(eitem)
icond = icond..", "
end

exfields[eitem['fields']] = true

icond = icond..quote_item(value)
end

Expand Down Expand Up @@ -896,15 +900,17 @@ function load_rules(sinsp_lua_parser,

local econd = ""

local exfields = {}

-- Turn exceptions into condition strings and add them to each
-- rule's condition
for _, eitem in ipairs(v['exceptions']) do

local icond, err
if type(eitem['fields']) == "table" then
icond, err = build_exception_condition_string_multi_fields(eitem)
icond, err = build_exception_condition_string_multi_fields(eitem, exfields)
else
icond, err = build_exception_condition_string_single_field(eitem)
icond, err = build_exception_condition_string_single_field(eitem, exfields)
end

if err ~= nil then
Expand All @@ -916,6 +922,8 @@ function load_rules(sinsp_lua_parser,
end
end

state.rules_by_name[name]['exception_fields'] = exfields

if econd ~= "" then
state.rules_by_name[name]['compile_condition'] = "("..state.rules_by_name[name]['condition']..") "..econd
else
Expand Down Expand Up @@ -1143,7 +1151,14 @@ function on_event(rule_id)
-- Prefix output with '*' so formatting is permissive
output = "*"..rule.output

return rule.rule, rule.priority_num, output
-- Also return all fields from all exceptions
combined_rule = state.rules_by_name[rule.rule]

if combined_rule == nil then
error ("rule_loader.on_event(): could not find rule by name: ", rule.rule)
end

return rule.rule, rule.priority_num, output, combined_rule.exception_fields
end

function print_stats()
Expand Down

0 comments on commit 8c4040b

Please sign in to comment.