mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-08 18:19:30 +00:00
update(engine): create a lua helper for rule filter manipulation
The lua_filter_helper class is a simple Lua wrapper that can be used in the Lua rule loader to parse/compile rule filters, and manipulate them to resolve/replace list and macro references. Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
@@ -19,7 +19,9 @@ set(FALCO_ENGINE_SOURCE_FILES
|
||||
falco_utils.cpp
|
||||
json_evt.cpp
|
||||
ruleset.cpp
|
||||
formats.cpp)
|
||||
formats.cpp
|
||||
filter_macro_resolver.cpp
|
||||
lua_filter_helper.cpp)
|
||||
|
||||
add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES})
|
||||
add_dependencies(falco_engine njson lyaml string-view-lite)
|
||||
|
@@ -28,8 +28,8 @@ limitations under the License.
|
||||
|
||||
#include "formats.h"
|
||||
|
||||
#include "lua_filter_helper.h"
|
||||
extern "C" {
|
||||
#include "lpeg.h"
|
||||
#include "lyaml.h"
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ falco_engine::falco_engine(bool seed_rng)
|
||||
|
||||
falco_common::init();
|
||||
falco_rules::init(m_ls);
|
||||
lua_filter_helper::init(m_ls);
|
||||
|
||||
m_required_plugin_versions.clear();
|
||||
|
||||
|
@@ -1418,7 +1418,7 @@ json_event_filter_check *k8s_audit_filter_check::allocate_new()
|
||||
return (json_event_filter_check *)chk;
|
||||
}
|
||||
|
||||
json_event_filter::json_event_filter()
|
||||
json_event_filter::json_event_filter(): sinsp_filter(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,7 @@ limitations under the License.
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "prefix_search.h"
|
||||
#include "gen_filter.h"
|
||||
#include <sinsp.h>
|
||||
|
||||
class json_event : public gen_event
|
||||
{
|
||||
@@ -383,7 +383,8 @@ public:
|
||||
json_event_filter_check &jchk);
|
||||
};
|
||||
|
||||
class json_event_filter : public gen_event_filter
|
||||
|
||||
class json_event_filter : public sinsp_filter
|
||||
{
|
||||
public:
|
||||
json_event_filter();
|
||||
|
217
userspace/engine/lua_filter_helper.cpp
Normal file
217
userspace/engine/lua_filter_helper.cpp
Normal file
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sinsp.h>
|
||||
#include "lua_filter_helper.h"
|
||||
#include "filter_macro_resolver.h"
|
||||
#include "filter_list_resolver.h"
|
||||
#include "rules.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace libsinsp::filter;
|
||||
|
||||
// The code below implements the Lua wrapper.
|
||||
// todo(jasondellaluce): remove this once Lua is removed from Falco
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
const static struct luaL_Reg ll_filter_helper[] =
|
||||
{
|
||||
{"compile_filter", &lua_filter_helper::compile_filter},
|
||||
{"parse_filter", &lua_filter_helper::parse_filter},
|
||||
{"expand_list", &lua_filter_helper::expand_list},
|
||||
{"expand_macro", &lua_filter_helper::expand_macro},
|
||||
{"find_unknown_macro", &lua_filter_helper::find_unknown_macro},
|
||||
{"clone_ast", &lua_filter_helper::clone_ast},
|
||||
{"delete_ast", &lua_filter_helper::delete_ast},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void lua_filter_helper::init(lua_State *ls)
|
||||
{
|
||||
luaL_openlib(ls, "filter_helper", ll_filter_helper, 0);
|
||||
}
|
||||
|
||||
int lua_filter_helper::parse_filter(lua_State *ls)
|
||||
{
|
||||
if (! lua_isstring(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "invalid argument passed to parse_filter()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
string filter_str = lua_tostring(ls, -1);
|
||||
|
||||
parser p(filter_str);
|
||||
p.set_max_depth(1000);
|
||||
try
|
||||
{
|
||||
auto filter = p.parse();
|
||||
lua_pushboolean(ls, true);
|
||||
lua_pushlightuserdata(ls, filter);
|
||||
}
|
||||
catch (const sinsp_exception& e)
|
||||
{
|
||||
string err = to_string(p.get_pos().col) + ": " + e.what();
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, err.c_str());
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::compile_filter(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -4) ||
|
||||
! lua_islightuserdata(ls, -3) ||
|
||||
! lua_isstring(ls, -2) ||
|
||||
! lua_isnumber(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "invalid argument passed to compile_filter()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -4);
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -3);
|
||||
std::string source = lua_tostring(ls, -2);
|
||||
int32_t check_id = (int32_t) luaL_checkinteger(ls, -1);
|
||||
|
||||
try
|
||||
{
|
||||
sinsp_filter_compiler compiler(rules->get_filter_factory(source), ast);
|
||||
compiler.set_check_id(check_id);
|
||||
gen_event_filter* filter = compiler.compile();
|
||||
lua_pushboolean(ls, true);
|
||||
lua_pushlightuserdata(ls, filter);
|
||||
}
|
||||
catch (const sinsp_exception& e)
|
||||
{
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, e.what());
|
||||
}
|
||||
catch (const falco_exception& e)
|
||||
{
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, e.what());
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::expand_list(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -3) || // ast
|
||||
! lua_isstring(ls, -2) || // name
|
||||
! lua_istable(ls, -1)) // values
|
||||
{
|
||||
lua_pushstring(ls, "invalid arguments passed to expand_list()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -3);
|
||||
std::string name = lua_tostring(ls, -2);
|
||||
vector<string> values;
|
||||
// first key
|
||||
lua_pushnil(ls);
|
||||
while (lua_next(ls, -2) != 0) {
|
||||
// key is at index -2, value is at index
|
||||
// -1. We want the values.
|
||||
values.push_back(lua_tostring(ls, -1));
|
||||
// Remove value, keep key for next iteration
|
||||
lua_pop(ls, 1);
|
||||
}
|
||||
|
||||
filter_list_resolver resolver;
|
||||
resolver.define_list(name, values);
|
||||
resolver.process(ast);
|
||||
lua_pushboolean(ls, !resolver.get_resolved_lists().empty());
|
||||
lua_pushlightuserdata(ls, ast);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::expand_macro(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -3) || // ast
|
||||
! lua_isstring(ls, -2) || // name
|
||||
! lua_islightuserdata(ls, -1)) // macro
|
||||
{
|
||||
lua_pushstring(ls, "invalid arguments passed to expand_macro()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -3);
|
||||
std::string name = lua_tostring(ls, -2);
|
||||
ast::expr* macro = (ast::expr*) lua_topointer(ls, -1);
|
||||
|
||||
filter_macro_resolver resolver;
|
||||
resolver.define_macro(name, macro);
|
||||
resolver.process(ast);
|
||||
lua_pushboolean(ls, !resolver.get_resolved_macros().empty());
|
||||
lua_pushlightuserdata(ls, ast);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::find_unknown_macro(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1)) // ast
|
||||
{
|
||||
lua_pushstring(ls, "invalid arguments passed to find_unknown_macro()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -1);
|
||||
|
||||
filter_macro_resolver resolver;
|
||||
resolver.process(ast);
|
||||
if (!resolver.get_unknown_macros().empty())
|
||||
{
|
||||
lua_pushboolean(ls, true);
|
||||
lua_pushstring(ls, resolver.get_unknown_macros().begin()->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, "");
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::clone_ast(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1)) // ast
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to clone_ast()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -1);
|
||||
ast::expr* cloned_ast = ast::clone(ast);
|
||||
lua_pushlightuserdata(ls, cloned_ast);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_filter_helper::delete_ast(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1)) // ptr
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to delete_ast()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
delete (ast::expr*) lua_topointer(ls, -1);
|
||||
return 0;
|
||||
}
|
37
userspace/engine/lua_filter_helper.h
Normal file
37
userspace/engine/lua_filter_helper.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// todo(jasondellaluce): remove this once Lua is removed from Falco
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
/*!
|
||||
\brief This is a Lua helper for filter-related operations
|
||||
todo(jasondellaluce): remove this once Lua is removed from Falco
|
||||
*/
|
||||
class lua_filter_helper
|
||||
{
|
||||
public:
|
||||
static void init(lua_State *ls);
|
||||
static int compile_filter(lua_State *ls);
|
||||
static int parse_filter(lua_State *ls);
|
||||
static int expand_list(lua_State *ls);
|
||||
static int expand_macro(lua_State *ls);
|
||||
static int find_unknown_macro(lua_State *ls);
|
||||
static int clone_ast(lua_State *ls);
|
||||
static int delete_ast(lua_State *ls);
|
||||
};
|
Reference in New Issue
Block a user