mirror of
https://github.com/falcosecurity/falco.git
synced 2026-04-01 01:22:14 +00:00
Compare commits
19 Commits
fix/dev_ve
...
enable_mai
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9763809cd9 | ||
|
|
5552bcab76 | ||
|
|
cb58ea9c57 | ||
|
|
0a6db28783 | ||
|
|
25ddc3c6a2 | ||
|
|
35dd0fc153 | ||
|
|
0c39776557 | ||
|
|
4696948754 | ||
|
|
ec04b758e6 | ||
|
|
52ee61b800 | ||
|
|
70dfdb2e75 | ||
|
|
1b227cf90b | ||
|
|
ff3a38415d | ||
|
|
94ed56df95 | ||
|
|
6a972272c0 | ||
|
|
55deb452d8 | ||
|
|
87371492c5 | ||
|
|
17dfe4f55d | ||
|
|
928ad6625b |
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@@ -3,7 +3,9 @@ on:
|
||||
pull_request:
|
||||
branches: [master]
|
||||
push:
|
||||
branches: [master]
|
||||
branches:
|
||||
- master
|
||||
- 'maintainers/**'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
@@ -14,6 +16,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Update base image
|
||||
run: sudo apt update -y
|
||||
@@ -47,6 +50,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Update base image
|
||||
run: sudo apt update -y
|
||||
@@ -80,6 +84,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Update base image
|
||||
run: sudo apt update -y
|
||||
@@ -113,6 +118,7 @@ jobs:
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Update base image
|
||||
run: sudo apt update -y
|
||||
@@ -151,6 +157,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
path: falco
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
- name: Link falco repo to /source/falco
|
||||
run: |
|
||||
@@ -167,4 +174,4 @@ jobs:
|
||||
run: /usr/bin/entrypoint tests
|
||||
|
||||
- name: Build packages
|
||||
run: /usr/bin/entrypoint package
|
||||
run: /usr/bin/entrypoint package
|
||||
|
||||
@@ -16,18 +16,32 @@ include(GetGitRevisionDescription)
|
||||
|
||||
# Create the falco version variable according to git index
|
||||
if(NOT FALCO_VERSION)
|
||||
string(STRIP "${FALCO_HASH}" FALCO_HASH)
|
||||
# Try to obtain the exact git tag
|
||||
git_get_exact_tag(FALCO_TAG)
|
||||
if(NOT FALCO_TAG)
|
||||
# Obtain the closest tag
|
||||
git_describe(FALCO_VERSION "--always" "--tags" "--abbrev=7")
|
||||
# Fallback version
|
||||
if(FALCO_VERSION MATCHES "NOTFOUND$")
|
||||
set(FALCO_VERSION "0.0.0")
|
||||
endif()
|
||||
# Format FALCO_VERSION to be semver with prerelease and build part
|
||||
string(REPLACE "-g" "+" FALCO_VERSION "${FALCO_VERSION}")
|
||||
# Fetch current hash
|
||||
get_git_head_revision(refspec FALCO_HASH)
|
||||
if(NOT FALCO_HASH OR FALCO_HASH MATCHES "NOTFOUND$")
|
||||
set(FALCO_VERSION "0.0.0")
|
||||
else()
|
||||
# Obtain the closest tag
|
||||
git_get_latest_tag(FALCO_LATEST_TAG)
|
||||
if(NOT FALCO_LATEST_TAG OR FALCO_LATEST_TAG MATCHES "NOTFOUND$")
|
||||
set(FALCO_VERSION "0.0.0")
|
||||
else()
|
||||
# Compute commit delta since tag
|
||||
git_get_delta_from_tag(FALCO_DELTA ${FALCO_LATEST_TAG} ${FALCO_HASH})
|
||||
if(NOT FALCO_DELTA OR FALCO_DELTA MATCHES "NOTFOUND$")
|
||||
set(FALCO_VERSION "0.0.0")
|
||||
else()
|
||||
# Cut hash to 7 bytes
|
||||
string(SUBSTRING ${FALCO_HASH} 0 7 FALCO_HASH)
|
||||
# Format FALCO_VERSION to be semver with prerelease and build part
|
||||
set(FALCO_VERSION
|
||||
"${FALCO_LATEST_TAG}-${FALCO_DELTA}+${FALCO_HASH}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
# A tag has been found: use it as the Falco version
|
||||
set(FALCO_VERSION "${FALCO_TAG}")
|
||||
|
||||
@@ -86,29 +86,36 @@ function(get_git_head_revision _refspecvar _hashvar)
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
function(git_get_latest_tag _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var}
|
||||
"HEAD-HASH-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
|
||||
# We use git describe --tags `git rev-list --tags --max-count=1`
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
rev-list
|
||||
--tags
|
||||
--max-count=1
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
COMMAND tail -n1
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
tag_hash
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${tag_hash}-${res}-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
describe
|
||||
${hash}
|
||||
${ARGN}
|
||||
--tags
|
||||
${tag_hash}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
@@ -120,10 +127,108 @@ function(git_describe _var)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
set(${_var} "${out}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_delta_from_tag _var tag hash)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
|
||||
# Count commits in HEAD
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
rev-list
|
||||
--count
|
||||
${hash}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out_counter_head
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(${_var} "HEADCOUNT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Count commits in latest tag
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
rev-list
|
||||
--count
|
||||
${tag}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out_counter_tag
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(${_var} "TAGCOUNT-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
expr
|
||||
${out_counter_head} - ${out_counter_tag}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out_delta
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(${_var} "DELTA-NOTFOUND" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
set(${_var} "${out_delta}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_describe _var)
|
||||
if(NOT GIT_FOUND)
|
||||
find_package(Git QUIET)
|
||||
endif()
|
||||
get_git_head_revision(refspec hash)
|
||||
if(NOT GIT_FOUND)
|
||||
set(${_var}
|
||||
"GIT-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
if(NOT hash)
|
||||
set(${_var}
|
||||
"HEAD-HASH-NOTFOUND"
|
||||
PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(COMMAND
|
||||
"${GIT_EXECUTABLE}"
|
||||
describe
|
||||
${hash}
|
||||
${ARGN}
|
||||
WORKING_DIRECTORY
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
RESULT_VARIABLE
|
||||
res
|
||||
OUTPUT_VARIABLE
|
||||
out
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if(NOT res EQUAL 0)
|
||||
set(out "${out}-${res}-NOTFOUND")
|
||||
endif()
|
||||
|
||||
set(${_var}
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
"${out}"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(git_get_exact_tag _var)
|
||||
|
||||
@@ -26,8 +26,8 @@ else()
|
||||
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DDRIVER_VERSION=dev ..`
|
||||
if(NOT DRIVER_VERSION)
|
||||
set(DRIVER_VERSION "dd443b67c6b04464cb8ee2771af8ada8777e7fac")
|
||||
set(DRIVER_CHECKSUM "SHA256=df373099d0f4cd4417a0103bb57f26c7412ffa86cde2bb2d579c6feba841626d")
|
||||
set(DRIVER_VERSION "4.0.0-rc1+driver")
|
||||
set(DRIVER_CHECKSUM "SHA256=82d18ca00d245e5b7195c420b00a4c895190b6de77be0feb13b98861d749f257")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
|
||||
@@ -27,8 +27,8 @@ else()
|
||||
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
|
||||
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
|
||||
if(NOT FALCOSECURITY_LIBS_VERSION)
|
||||
set(FALCOSECURITY_LIBS_VERSION "dd443b67c6b04464cb8ee2771af8ada8777e7fac")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=df373099d0f4cd4417a0103bb57f26c7412ffa86cde2bb2d579c6feba841626d")
|
||||
set(FALCOSECURITY_LIBS_VERSION "0.10.0-rc1")
|
||||
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=af2fcd9017d1611d3c5068405632eb3aa5cd578514ed8f06cb02ebca5556fd1d")
|
||||
endif()
|
||||
|
||||
# cd /path/to/build && cmake /path/to/source
|
||||
|
||||
@@ -113,6 +113,9 @@ get_target_id() {
|
||||
elif [ -f "${HOST_ROOT}/etc/centos-release" ]; then
|
||||
# Older CentOS distros
|
||||
OS_ID=centos
|
||||
elif [ -f "${HOST_ROOT}/etc/redhat-release" ]; then
|
||||
# Older RHEL distros
|
||||
OS_ID=rhel
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -358,6 +358,16 @@ trace_files: !mux
|
||||
validate_rules_file:
|
||||
- rules/invalid_macro_without_condition.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_macro_loop:
|
||||
exit_status: 1
|
||||
validate_errors:
|
||||
- item_type: macro
|
||||
item_name: macro_a
|
||||
code: LOAD_ERR_VALIDATE
|
||||
message_contains: "reference loop in macro"
|
||||
validate_rules_file:
|
||||
- rules/invalid_macro_loop.yaml
|
||||
|
||||
invalid_rule_without_output:
|
||||
exit_status: 1
|
||||
@@ -403,6 +413,16 @@ trace_files: !mux
|
||||
- rules/list_append_failure.yaml
|
||||
trace_file: trace_files/cat_write.scap
|
||||
|
||||
invalid_list_loop:
|
||||
exit_status: 1
|
||||
validate_errors:
|
||||
- item_type: rule
|
||||
item_name: sample rule
|
||||
code: LOAD_ERR_COMPILE_CONDITION
|
||||
message: "unknown event type list_a"
|
||||
validate_rules_file:
|
||||
- rules/invalid_list_loop.yaml
|
||||
|
||||
invalid_rule_append_dangling:
|
||||
exit_status: 1
|
||||
validate_errors:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
avocado-framework==69.0
|
||||
avocado-framework-plugin-varianter-yaml-to-mux==69.0
|
||||
certifi==2020.4.5.1
|
||||
certifi==2022.12.7
|
||||
chardet==3.0.4
|
||||
idna==2.9
|
||||
pathtools==0.1.2
|
||||
|
||||
17
test/rules/invalid_list_loop.yaml
Normal file
17
test/rules/invalid_list_loop.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
- list: list_a
|
||||
items: [open]
|
||||
|
||||
- list: list_b
|
||||
items: [list_a]
|
||||
|
||||
- list: list_a
|
||||
items: [list_b]
|
||||
|
||||
- macro: macro_a
|
||||
condition: evt.type in (list_a)
|
||||
|
||||
- rule: sample rule
|
||||
priority: WARNING
|
||||
output: test
|
||||
desc: testdesc
|
||||
condition: macro_a
|
||||
8
test/rules/invalid_macro_loop.yaml
Normal file
8
test/rules/invalid_macro_loop.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
- macro: macro_a
|
||||
condition: evt.type=open
|
||||
|
||||
- macro: macro_b
|
||||
condition: macro_a
|
||||
|
||||
- macro: macro_a
|
||||
condition: macro_b
|
||||
@@ -20,27 +20,20 @@ limitations under the License.
|
||||
using namespace std;
|
||||
using namespace libsinsp::filter::ast;
|
||||
|
||||
static pos_info create_pos(uint32_t idx, uint32_t line, uint32_t col)
|
||||
static std::vector<filter_macro_resolver::value_info>::const_iterator find_value(
|
||||
const std::vector<filter_macro_resolver::value_info>& values,
|
||||
const std::string& ref)
|
||||
{
|
||||
pos_info ret;
|
||||
ret.idx = idx;
|
||||
ret.line = line;
|
||||
ret.col = col;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool operator==(const pos_info& p1, const pos_info& p2)
|
||||
{
|
||||
return (p1.idx == p2.idx) &&
|
||||
(p1.line == p2.line) &&
|
||||
(p1.col == p2.col);
|
||||
return std::find_if(
|
||||
values.begin(),
|
||||
values.end(),
|
||||
[&ref](const filter_macro_resolver::value_info& v) { return v.first == ref; });
|
||||
}
|
||||
|
||||
TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
|
||||
{
|
||||
string macro_name = "test_macro";
|
||||
pos_info macro_pos = create_pos(12, 85, 27);
|
||||
pos_info macro_pos(12, 85, 27);
|
||||
|
||||
SECTION("in the general case")
|
||||
{
|
||||
@@ -109,8 +102,8 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
|
||||
string a_macro_name = macro_name + "_1";
|
||||
string b_macro_name = macro_name + "_2";
|
||||
|
||||
pos_info a_macro_pos = create_pos(11, 75, 43);
|
||||
pos_info b_macro_pos = create_pos(91, 21, 9);
|
||||
pos_info a_macro_pos(11, 75, 43);
|
||||
pos_info b_macro_pos(91, 21, 9);
|
||||
|
||||
std::shared_ptr<expr> a_macro = std::move(
|
||||
unary_check_expr::create("one.field", "", "exists"));
|
||||
@@ -134,12 +127,12 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
|
||||
// first run
|
||||
REQUIRE(resolver.run(filter) == true);
|
||||
REQUIRE(resolver.get_resolved_macros().size() == 2);
|
||||
auto a_resolved_itr = resolver.get_resolved_macros().find(a_macro_name);
|
||||
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), a_macro_name);
|
||||
REQUIRE(a_resolved_itr != resolver.get_resolved_macros().end());
|
||||
REQUIRE(a_resolved_itr->first == a_macro_name);
|
||||
REQUIRE(a_resolved_itr->second == a_macro_pos);
|
||||
|
||||
auto b_resolved_itr = resolver.get_resolved_macros().find(b_macro_name);
|
||||
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), b_macro_name);
|
||||
REQUIRE(b_resolved_itr != resolver.get_resolved_macros().end());
|
||||
REQUIRE(resolver.get_unknown_macros().empty());
|
||||
REQUIRE(b_resolved_itr->first == b_macro_name);
|
||||
@@ -158,8 +151,8 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
|
||||
string a_macro_name = macro_name + "_1";
|
||||
string b_macro_name = macro_name + "_2";
|
||||
|
||||
pos_info a_macro_pos = create_pos(47, 1, 76);
|
||||
pos_info b_macro_pos = create_pos(111, 65, 2);
|
||||
pos_info a_macro_pos(47, 1, 76);
|
||||
pos_info b_macro_pos(111, 65, 2);
|
||||
|
||||
std::vector<std::unique_ptr<expr>> a_macro_and;
|
||||
a_macro_and.push_back(unary_check_expr::create("one.field", "", "exists"));
|
||||
@@ -183,12 +176,12 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
|
||||
// first run
|
||||
REQUIRE(resolver.run(filter) == true);
|
||||
REQUIRE(resolver.get_resolved_macros().size() == 2);
|
||||
auto a_resolved_itr = resolver.get_resolved_macros().find(a_macro_name);
|
||||
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), a_macro_name);
|
||||
REQUIRE(a_resolved_itr != resolver.get_resolved_macros().end());
|
||||
REQUIRE(a_resolved_itr->first == a_macro_name);
|
||||
REQUIRE(a_resolved_itr->second == a_macro_pos);
|
||||
|
||||
auto b_resolved_itr = resolver.get_resolved_macros().find(b_macro_name);
|
||||
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), b_macro_name);
|
||||
REQUIRE(b_resolved_itr != resolver.get_resolved_macros().end());
|
||||
REQUIRE(resolver.get_unknown_macros().empty());
|
||||
REQUIRE(b_resolved_itr->first == b_macro_name);
|
||||
@@ -208,7 +201,7 @@ TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
|
||||
TEST_CASE("Should find unknown macros", "[rule_loader]")
|
||||
{
|
||||
string macro_name = "test_macro";
|
||||
pos_info macro_pos = create_pos(9, 4, 2);
|
||||
pos_info macro_pos(9, 4, 2);
|
||||
|
||||
SECTION("in the general case")
|
||||
{
|
||||
@@ -230,8 +223,8 @@ TEST_CASE("Should find unknown macros", "[rule_loader]")
|
||||
string a_macro_name = macro_name + "_1";
|
||||
string b_macro_name = macro_name + "_2";
|
||||
|
||||
pos_info a_macro_pos = create_pos(32, 84, 9);
|
||||
pos_info b_macro_pos = create_pos(1, 0, 5);
|
||||
pos_info a_macro_pos(32, 84, 9);
|
||||
pos_info b_macro_pos(1, 0, 5);
|
||||
|
||||
std::vector<std::unique_ptr<expr>> a_macro_and;
|
||||
a_macro_and.push_back(unary_check_expr::create("one.field", "", "exists"));
|
||||
@@ -259,8 +252,8 @@ TEST_CASE("Should find unknown macros", "[rule_loader]")
|
||||
TEST_CASE("Should undefine macro", "[rule_loader]")
|
||||
{
|
||||
string macro_name = "test_macro";
|
||||
pos_info macro_pos_1 = create_pos(12, 9, 3);
|
||||
pos_info macro_pos_2 = create_pos(9, 6, 3);
|
||||
pos_info macro_pos_1(12, 9, 3);
|
||||
pos_info macro_pos_2(9, 6, 3);
|
||||
|
||||
std::shared_ptr<expr> macro = std::move(unary_check_expr::create("test.field", "", "exists"));
|
||||
std::shared_ptr<expr> a_filter = std::move(value_expr::create(macro_name, macro_pos_1));
|
||||
@@ -287,7 +280,7 @@ TEST_CASE("Should undefine macro", "[rule_loader]")
|
||||
TEST_CASE("Should clone macro AST", "[rule_loader]")
|
||||
{
|
||||
string macro_name = "test_macro";
|
||||
pos_info macro_pos = create_pos(5, 2, 8888);
|
||||
pos_info macro_pos(5, 2, 8888);
|
||||
std::shared_ptr<unary_check_expr> macro = std::move(unary_check_expr::create("test.field", "", "exists"));
|
||||
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name, macro_pos));
|
||||
filter_macro_resolver resolver;
|
||||
|
||||
@@ -30,7 +30,7 @@ set(FALCO_ENGINE_SOURCE_FILES
|
||||
add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES})
|
||||
|
||||
if(USE_BUNDLED_DEPS)
|
||||
add_dependencies(falco_engine yamlcpp)
|
||||
add_dependencies(falco_engine yamlcpp njson)
|
||||
endif()
|
||||
|
||||
if(MINIMAL_BUILD)
|
||||
|
||||
@@ -21,4 +21,4 @@ limitations under the License.
|
||||
// This is the result of running "falco --list -N | sha256sum" and
|
||||
// represents the fields supported by this version of Falco. It's used
|
||||
// at build time to detect a changed set of fields.
|
||||
#define FALCO_FIELDS_CHECKSUM "674c6cf2bc1c105038c8676f018fa3d1431d86597df428453441f5d859cad284"
|
||||
#define FALCO_FIELDS_CHECKSUM "cc9d32916c719ce5aea164cdadb56207cbeff20033e278b99101964be7aa77a1"
|
||||
|
||||
@@ -15,6 +15,7 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
#include "filter_macro_resolver.h"
|
||||
#include "falco_common.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace libsinsp::filter;
|
||||
@@ -23,8 +24,9 @@ bool filter_macro_resolver::run(libsinsp::filter::ast::expr*& filter)
|
||||
{
|
||||
m_unknown_macros.clear();
|
||||
m_resolved_macros.clear();
|
||||
m_errors.clear();
|
||||
|
||||
visitor v(m_unknown_macros, m_resolved_macros, m_macros);
|
||||
visitor v(m_errors, m_unknown_macros, m_resolved_macros, m_macros);
|
||||
v.m_node_substitute = nullptr;
|
||||
filter->accept(&v);
|
||||
if (v.m_node_substitute)
|
||||
@@ -39,8 +41,9 @@ bool filter_macro_resolver::run(std::shared_ptr<libsinsp::filter::ast::expr>& fi
|
||||
{
|
||||
m_unknown_macros.clear();
|
||||
m_resolved_macros.clear();
|
||||
m_errors.clear();
|
||||
|
||||
visitor v(m_unknown_macros, m_resolved_macros, m_macros);
|
||||
visitor v(m_errors, m_unknown_macros, m_resolved_macros, m_macros);
|
||||
v.m_node_substitute = nullptr;
|
||||
filter->accept(&v);
|
||||
if (v.m_node_substitute)
|
||||
@@ -57,12 +60,17 @@ void filter_macro_resolver::set_macro(
|
||||
m_macros[name] = macro;
|
||||
}
|
||||
|
||||
const filter_macro_resolver::macro_info_map& filter_macro_resolver::get_unknown_macros() const
|
||||
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_unknown_macros() const
|
||||
{
|
||||
return m_unknown_macros;
|
||||
}
|
||||
|
||||
const filter_macro_resolver::macro_info_map& filter_macro_resolver::get_resolved_macros() const
|
||||
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_errors() const
|
||||
{
|
||||
return m_errors;
|
||||
}
|
||||
|
||||
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_resolved_macros() const
|
||||
{
|
||||
return m_resolved_macros;
|
||||
}
|
||||
@@ -125,9 +133,21 @@ void filter_macro_resolver::visitor::visit(ast::value_expr* e)
|
||||
// we are supposed to get here only in case
|
||||
// of identier-only children from either a 'not',
|
||||
// an 'and' or an 'or'.
|
||||
auto macro = m_macros.find(e->value);
|
||||
const auto& macro = m_macros.find(e->value);
|
||||
if (macro != m_macros.end() && macro->second) // skip null-ptr macros
|
||||
{
|
||||
// note: checks for loop detection
|
||||
const auto& prevref = std::find(m_macros_path.begin(), m_macros_path.end(), macro->first);
|
||||
if (prevref != m_macros_path.end())
|
||||
{
|
||||
auto msg = "reference loop in macro '" + macro->first + "'";
|
||||
m_errors.push_back({msg, e->get_pos()});
|
||||
m_node_substitute = nullptr;
|
||||
m_unknown_macros.push_back({e->value, e->get_pos()});
|
||||
return;
|
||||
}
|
||||
|
||||
m_macros_path.push_back(macro->first);
|
||||
m_node_substitute = nullptr;
|
||||
auto new_node = ast::clone(macro->second.get());
|
||||
new_node->accept(this);
|
||||
@@ -137,11 +157,12 @@ void filter_macro_resolver::visitor::visit(ast::value_expr* e)
|
||||
{
|
||||
m_node_substitute = std::move(new_node);
|
||||
}
|
||||
m_resolved_macros[e->value] = e->get_pos();
|
||||
m_resolved_macros.push_back({e->value, e->get_pos()});
|
||||
m_macros_path.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_node_substitute = nullptr;
|
||||
m_unknown_macros[e->value] = e->get_pos();
|
||||
m_unknown_macros.push_back({e->value, e->get_pos()});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,16 +59,17 @@ class filter_macro_resolver
|
||||
std::shared_ptr<libsinsp::filter::ast::expr> macro);
|
||||
|
||||
/*!
|
||||
\brief used in get_{resolved,unknown}_macros
|
||||
\brief used in get_{resolved,unknown}_macros and get_errors
|
||||
to represent an identifier/string value along with an AST position.
|
||||
*/
|
||||
typedef std::unordered_map<std::string,libsinsp::filter::ast::pos_info> macro_info_map;
|
||||
typedef std::pair<std::string,libsinsp::filter::ast::pos_info> value_info;
|
||||
|
||||
/*!
|
||||
\brief Returns a set containing the names of all the macros
|
||||
substituted during the last invocation of run(). Should be
|
||||
non-empty if the last invocation of run() returned true.
|
||||
*/
|
||||
const macro_info_map& get_resolved_macros() const;
|
||||
const std::vector<value_info>& get_resolved_macros() const;
|
||||
|
||||
/*!
|
||||
\brief Returns a set containing the names of all the macros
|
||||
@@ -76,7 +77,13 @@ class filter_macro_resolver
|
||||
A macro remains unresolved if it is found inside the processed
|
||||
filter but it was not defined with set_macro();
|
||||
*/
|
||||
const macro_info_map& get_unknown_macros() const;
|
||||
const std::vector<value_info>& get_unknown_macros() const;
|
||||
|
||||
/*!
|
||||
\brief Returns a list of errors occurred during
|
||||
the latest invocation of run().
|
||||
*/
|
||||
const std::vector<value_info>& get_errors() const;
|
||||
|
||||
private:
|
||||
typedef std::unordered_map<
|
||||
@@ -86,17 +93,25 @@ class filter_macro_resolver
|
||||
|
||||
struct visitor : public libsinsp::filter::ast::expr_visitor
|
||||
{
|
||||
visitor(macro_info_map& unknown_macros, macro_info_map& resolved_macros, macro_defs& macros)
|
||||
: m_unknown_macros(unknown_macros), m_resolved_macros(resolved_macros), m_macros(macros) {}
|
||||
visitor(
|
||||
std::vector<value_info>& errors,
|
||||
std::vector<value_info>& unknown_macros,
|
||||
std::vector<value_info>& resolved_macros,
|
||||
macro_defs& macros):
|
||||
m_errors(errors),
|
||||
m_unknown_macros(unknown_macros),
|
||||
m_resolved_macros(resolved_macros),
|
||||
m_macros(macros) {}
|
||||
visitor(visitor&&) = default;
|
||||
visitor& operator = (visitor&&) = default;
|
||||
visitor(const visitor&) = delete;
|
||||
visitor& operator = (const visitor&) = delete;
|
||||
|
||||
std::vector<std::string> m_macros_path;
|
||||
std::unique_ptr<libsinsp::filter::ast::expr> m_node_substitute;
|
||||
macro_info_map& m_unknown_macros;
|
||||
macro_info_map& m_resolved_macros;
|
||||
|
||||
std::vector<value_info>& m_errors;
|
||||
std::vector<value_info>& m_unknown_macros;
|
||||
std::vector<value_info>& m_resolved_macros;
|
||||
macro_defs& m_macros;
|
||||
|
||||
void visit(libsinsp::filter::ast::and_expr* e) override;
|
||||
@@ -108,7 +123,8 @@ class filter_macro_resolver
|
||||
void visit(libsinsp::filter::ast::binary_check_expr* e) override;
|
||||
};
|
||||
|
||||
macro_info_map m_unknown_macros;
|
||||
macro_info_map m_resolved_macros;
|
||||
std::vector<value_info> m_errors;
|
||||
std::vector<value_info> m_unknown_macros;
|
||||
std::vector<value_info> m_resolved_macros;
|
||||
macro_defs m_macros;
|
||||
};
|
||||
|
||||
@@ -248,18 +248,19 @@ static void resolve_macros(
|
||||
}
|
||||
macro_resolver.run(ast);
|
||||
|
||||
// Note: only complaining about the first unknown macro
|
||||
const filter_macro_resolver::macro_info_map& unresolved_macros = macro_resolver.get_unknown_macros();
|
||||
if(!unresolved_macros.empty())
|
||||
// Note: only complaining about the first error or unknown macro
|
||||
const auto& errors_macros = macro_resolver.get_errors();
|
||||
const auto& unresolved_macros = macro_resolver.get_unknown_macros();
|
||||
if(!errors_macros.empty() || !unresolved_macros.empty())
|
||||
{
|
||||
auto it = unresolved_macros.begin();
|
||||
const rule_loader::context cond_ctx(it->second, condition, ctx);
|
||||
|
||||
THROW(true,
|
||||
std::string("Undefined macro '")
|
||||
+ it->first
|
||||
+ "' used in filter.",
|
||||
cond_ctx);
|
||||
auto errpos = !errors_macros.empty()
|
||||
? errors_macros.begin()->second
|
||||
: unresolved_macros.begin()->second;
|
||||
std::string errmsg = !errors_macros.empty()
|
||||
? errors_macros.begin()->first
|
||||
: ("Undefined macro '" + unresolved_macros.begin()->first + "' used in filter.");
|
||||
const rule_loader::context cond_ctx(errpos, condition, ctx);
|
||||
THROW(true, errmsg, cond_ctx);
|
||||
}
|
||||
|
||||
for (auto &it : macro_resolver.get_resolved_macros())
|
||||
|
||||
@@ -50,8 +50,8 @@ application::run_result application::do_inspect(
|
||||
uint64_t duration_to_tot_ns,
|
||||
uint64_t &num_evts)
|
||||
{
|
||||
int32_t rc;
|
||||
sinsp_evt* ev;
|
||||
int32_t rc = 0;
|
||||
sinsp_evt* ev = NULL;
|
||||
stats_writer::collector stats_collector(statsw);
|
||||
uint64_t duration_start = 0;
|
||||
uint32_t timeouts_since_last_success_or_msg = 0;
|
||||
@@ -91,6 +91,11 @@ application::run_result application::do_inspect(
|
||||
m_state->config->m_syscall_evt_simulate_drops);
|
||||
}
|
||||
|
||||
//
|
||||
// Start capture
|
||||
//
|
||||
inspector->start_capture();
|
||||
|
||||
//
|
||||
// Loop through the events
|
||||
//
|
||||
|
||||
@@ -16,8 +16,6 @@ limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#define FALCO_BRANCH "@FALCO_REF@"
|
||||
#define FALCO_HASH "@FALCO_HASH@"
|
||||
#define FALCO_VERSION "@FALCO_VERSION@"
|
||||
#define FALCO_VERSION_MAJOR @FALCO_VERSION_MAJOR@
|
||||
#define FALCO_VERSION_MINOR @FALCO_VERSION_MINOR@
|
||||
|
||||
Reference in New Issue
Block a user