diff --git a/test/falco_tests_exceptions.yaml b/test/falco_tests_exceptions.yaml index 5b7d45cb227..188d478e2b7 100644 --- a/test/falco_tests_exceptions.yaml +++ b/test/falco_tests_exceptions.yaml @@ -177,10 +177,18 @@ trace_files: !mux trace_file: trace_files/cat_write.scap rule_exception_append_item_not_in_rule: - exit_status: 0 - stderr_contains: |+ - 1 warnings: - Rule My Rule with append=true: no set of fields matching name ex2 + exit_status: 1 + stdout_is: |+ + 1 errors: + Rule exception new item ex2: must have fields property with a list of fields + --- + - rule: My Rule + exceptions: + - name: ex2 + values: + - [apache, /tmp] + append: true + --- validate_rules_file: - rules/exceptions/append_item_not_in_rule.yaml trace_file: trace_files/cat_write.scap @@ -311,4 +319,35 @@ trace_files: !mux - rules/exceptions/rule_exception_single_field_append.yaml trace_file: trace_files/cat_write.scap + rule_exception_new_single_field_append: + detect: False + detect_level: WARNING + rules_file: + - rules/exceptions/rule_exception_new_single_field_append.yaml + trace_file: trace_files/cat_write.scap + + rule_exception_new_second_field_append: + detect: False + detect_level: WARNING + rules_file: + - rules/exceptions/rule_exception_new_second_field_append.yaml + trace_file: trace_files/cat_write.scap + + rule_exception_new_append_no_field: + exit_status: 1 + stdout_is: |+ + 1 errors: + Rule exception new item proc_cmdline: must have fields property with a list of fields + --- + - rule: Open From Cat + exceptions: + - name: proc_cmdline + comps: in + values: + - "cat /dev/null" + append: true + --- + validate_rules_file: + - rules/exceptions/rule_exception_new_no_field_append.yaml + trace_file: trace_files/cat_write.scap diff --git a/test/rules/exceptions/rule_exception_new_no_field_append.yaml b/test/rules/exceptions/rule_exception_new_no_field_append.yaml new file mode 100644 index 00000000000..da2a89bf225 --- /dev/null +++ b/test/rules/exceptions/rule_exception_new_no_field_append.yaml @@ -0,0 +1,31 @@ +# +# Copyright (C) 2021 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. +# + +- rule: Open From Cat + desc: A process named cat does an open + condition: evt.type=open and proc.name=cat + output: "An open was seen (command=%proc.cmdline)" + priority: WARNING + +- rule: Open From Cat + exceptions: + - name: proc_cmdline + comps: in + values: + - "cat /dev/null" + append: true + diff --git a/test/rules/exceptions/rule_exception_new_second_field_append.yaml b/test/rules/exceptions/rule_exception_new_second_field_append.yaml new file mode 100644 index 00000000000..7aa23f002b7 --- /dev/null +++ b/test/rules/exceptions/rule_exception_new_second_field_append.yaml @@ -0,0 +1,39 @@ +# +# Copyright (C) 2021 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. +# + +- rule: Open From Cat + desc: A process named cat does an open + condition: evt.type=open and proc.name=cat + output: "An open was seen (command=%proc.cmdline)" + exceptions: + - name: proc_cmdline + fields: proc.cmdline + comps: in + values: + - cat /dev/zero + priority: WARNING + +- rule: Open From Cat + exceptions: + - name: proc_cmdline_2 + fields: proc.cmdline + comps: in + values: + - "cat /dev/null" + append: true + + diff --git a/test/rules/exceptions/rule_exception_new_single_field_append.yaml b/test/rules/exceptions/rule_exception_new_single_field_append.yaml new file mode 100644 index 00000000000..857f8208930 --- /dev/null +++ b/test/rules/exceptions/rule_exception_new_single_field_append.yaml @@ -0,0 +1,33 @@ +# +# Copyright (C) 2021 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. +# + +- rule: Open From Cat + desc: A process named cat does an open + condition: evt.type=open and proc.name=cat + output: "An open was seen (command=%proc.cmdline)" + priority: WARNING + +- rule: Open From Cat + exceptions: + - name: proc_cmdline + fields: proc.cmdline + comps: in + values: + - "cat /dev/null" + append: true + + diff --git a/userspace/engine/lua/rule_loader.lua b/userspace/engine/lua/rule_loader.lua index 67b979d8884..2db1e96b762 100644 --- a/userspace/engine/lua/rule_loader.lua +++ b/userspace/engine/lua/rule_loader.lua @@ -592,41 +592,78 @@ function load_rules_doc(rules_mgr, doc, load_state) if next(v['exceptions']) ~= nil then for _, eitem in ipairs(v['exceptions']) do - local name = eitem['name'] - local fields = eitem['fields'] - local comps = eitem['comps'] - if name == nil then + if eitem['name'] == nil then return false, build_error_with_context(v['context'], "Rule exception item must have name property"), warnings end - -- You can't append exception fields or comps to a rule - if fields ~= nil then - return false, build_error_with_context(v['context'], "Can not append exception fields to existing rule, only values"), warnings - end + -- Seperate case when a exception name is not found + -- This means that a new exception is being appended - if comps ~= nil then - return false, build_error_with_context(v['context'], "Can not append exception comps to existing rule, only values"), warnings + local new_exception = true + for _, rex_item in ipairs(state.rules_by_name[v['rule']]['exceptions']) do + if rex_item['name'] == eitem['name'] then + new_exception = false + break + end end - -- You can append values. They are added to the - -- corresponding name, if it exists. If no - -- exception with that name exists, add a - -- warning. - if eitem['values'] ~= nil then - local found=false - for _, reitem in ipairs(state.rules_by_name[v['rule']]['exceptions']) do - if reitem['name'] == eitem['name'] then - found=true - for _, values in ipairs(eitem['values']) do - reitem['values'][#reitem['values'] + 1] = values + if new_exception then + local exceptions = state.rules_by_name[v['rule']]['exceptions'] + if exceptions == nil then + exceptions = {} + end + + if eitem['fields'] == nil then + return false, build_error_with_context(v['context'], "Rule exception new item "..eitem['name']..": must have fields property with a list of fields"), warnings + end + if eitem['values'] == nil then + return false, build_error_with_context(v['context'], "Rule exception new item "..eitem['name']..": must have values property with a list of values"), warnings + end + + local valid, err + if type(eitem['fields']) == "table" then + valid, err = validate_exception_item_multi_fields(rules_mgr, v['source'], eitem, v['context']) + else + valid, err = validate_exception_item_single_field(rules_mgr, v['source'], eitem, v['context']) + end + + if valid == false then + return valid, err + end + + -- Insert the complete exception object + exceptions[#exceptions+1] = eitem + else + -- Appends to existing exception here + -- You can't append exception fields or comps to an existing rule exception + if eitem['fields'] ~= nil then + return false, build_error_with_context(v['context'], "Can not append exception fields to existing rule, only values"), warnings + end + + if eitem['comps'] ~= nil then + return false, build_error_with_context(v['context'], "Can not append exception comps to existing rule, only values"), warnings + end + + -- You can append values. They are added to the + -- corresponding name, if it exists. If no + -- exception with that name exists, add a + -- warning. + if eitem['values'] ~= nil then + local found=false + for _, reitem in ipairs(state.rules_by_name[v['rule']]['exceptions']) do + if reitem['name'] == eitem['name'] then + found=true + for _, values in ipairs(eitem['values']) do + reitem['values'][#reitem['values'] + 1] = values + end end end - end - if found == false then - warnings[#warnings + 1] = "Rule "..v['rule'].." with append=true: no set of fields matching name "..eitem['name'] - end + if found == false then + warnings[#warnings + 1] = "Rule "..v['rule'].." with append=true: no set of fields matching name "..eitem['name'] + end + end end end end