diff --git a/test/falco_test.py b/test/falco_test.py index 19956591..41d83912 100644 --- a/test/falco_test.py +++ b/test/falco_test.py @@ -213,7 +213,7 @@ class FalcoTest(Test): triggered_rules = match.group(1) for rule, count in self.detect_counts.iteritems(): - expected = '{}: (\d+)'.format(rule) + expected = '\s{}: (\d+)'.format(rule) match = re.search(expected, triggered_rules) if match is None: diff --git a/test/falco_tests.yaml b/test/falco_tests.yaml index 6b7641b7..74ca66fd 100644 --- a/test/falco_tests.yaml +++ b/test/falco_tests.yaml @@ -699,3 +699,13 @@ trace_files: !mux - detect_madvise: 2 - detect_open: 2 trace_file: trace_files/syscall.scap + + catchall_order: + detect: True + detect_level: INFO + rules_file: + - rules/catchall_order.yaml + detect_counts: + - open_dev_null: 1 + dev_null: 0 + trace_file: trace_files/cat_write.scap diff --git a/test/rules/catchall_order.yaml b/test/rules/catchall_order.yaml new file mode 100644 index 00000000..a79b0862 --- /dev/null +++ b/test/rules/catchall_order.yaml @@ -0,0 +1,12 @@ +- rule: open_dev_null + desc: Any open of the file /dev/null + condition: evt.type=open and fd.name=/dev/null + output: An open of /dev/null was seen (command=%proc.cmdline evt=%evt.type %evt.args) + priority: INFO + +- rule: dev_null + desc: Anything related to /dev/null + condition: fd.name=/dev/null + output: Something related to /dev/null was seen (command=%proc.cmdline evt=%evt.type %evt.args) + priority: INFO + warn_evttypes: false diff --git a/userspace/engine/lua/compiler.lua b/userspace/engine/lua/compiler.lua index 58b527bd..0ce49ef2 100644 --- a/userspace/engine/lua/compiler.lua +++ b/userspace/engine/lua/compiler.lua @@ -201,7 +201,7 @@ end -- run for all event types/syscalls. (Also, a warning is printed). -- -function get_evttypes_syscalls(name, ast, source) +function get_evttypes_syscalls(name, ast, source, warn_evttypes) local evttypes = {} local syscallnums = {} @@ -276,23 +276,27 @@ function get_evttypes_syscalls(name, ast, source) parser.traverse_ast(ast.filter.value, {BinaryRelOp=1, UnaryBoolOp=1} , cb) if not found_event then - io.stderr:write("Rule "..name..": warning (no-evttype):\n") - io.stderr:write(source.."\n") - io.stderr:write(" did not contain any evt.type restriction, meaning it will run for all event types.\n") - io.stderr:write(" This has a significant performance penalty. Consider adding an evt.type restriction if possible.\n") + if warn_evttypes == true then + io.stderr:write("Rule "..name..": warning (no-evttype):\n") + io.stderr:write(source.."\n") + io.stderr:write(" did not contain any evt.type restriction, meaning it will run for all event types.\n") + io.stderr:write(" This has a significant performance penalty. Consider adding an evt.type restriction if possible.\n") + end evttypes = {} syscallnums = {} evtnames = {} end if found_event_after_not then - io.stderr:write("Rule "..name..": warning (trailing-evttype):\n") - io.stderr:write(source.."\n") - io.stderr:write(" does not have all evt.type restrictions at the beginning of the condition,\n") - io.stderr:write(" or uses a negative match (i.e. \"not\"/\"!=\") for some evt.type restriction.\n") - io.stderr:write(" This has a performance penalty, as the rule can not be limited to specific event types.\n") - io.stderr:write(" Consider moving all evt.type restrictions to the beginning of the rule and/or\n") - io.stderr:write(" replacing negative matches with positive matches if possible.\n") + if warn_evttypes == true then + io.stderr:write("Rule "..name..": warning (trailing-evttype):\n") + io.stderr:write(source.."\n") + io.stderr:write(" does not have all evt.type restrictions at the beginning of the condition,\n") + io.stderr:write(" or uses a negative match (i.e. \"not\"/\"!=\") for some evt.type restriction.\n") + io.stderr:write(" This has a performance penalty, as the rule can not be limited to specific event types.\n") + io.stderr:write(" Consider moving all evt.type restrictions to the beginning of the rule and/or\n") + io.stderr:write(" replacing negative matches with positive matches if possible.\n") + end evttypes = {} syscallnums = {} evtnames = {} @@ -375,7 +379,7 @@ end --[[ Parses a single filter, then expands macros using passed-in table of definitions. Returns resulting AST. --]] -function compiler.compile_filter(name, source, macro_defs, list_defs) +function compiler.compile_filter(name, source, macro_defs, list_defs, warn_evttypes) source = compiler.expand_lists_in(source, list_defs) @@ -402,7 +406,7 @@ function compiler.compile_filter(name, source, macro_defs, list_defs) error("Unexpected top-level AST type: "..ast.type) end - evttypes, syscallnums = get_evttypes_syscalls(name, ast, source) + evttypes, syscallnums = get_evttypes_syscalls(name, ast, source, warn_evttypes) return ast, evttypes, syscallnums end diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index 376fd0e1..292e32cd 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -373,8 +373,14 @@ function load_rules(rules_content, rules_mgr, verbose, all_events, extra, replac local v = state.rules_by_name[name] + warn_evttypes = true + if v['warn_evttypes'] ~= nil then + warn_evttypes = v['warn_evttypes'] + end + local filter_ast, evttypes, syscallnums = compiler.compile_filter(v['rule'], v['condition'], - state.macros, state.lists) + state.macros, state.lists, + warn_evttypes) if (filter_ast.type == "Rule") then state.n_rules = state.n_rules + 1