Compare commits

..

7 Commits

Author SHA1 Message Date
Kris Nóva
404762bd34 feat(release): Updating notes according to PR
Signed-off-by: Kris Nóva <kris@nivenly.com>
2020-09-25 08:18:48 -07:00
Kris Nóva
20f5e5d35a feat(release): Release 0.26
Cutting release for 0.26.0 and starting 0.27.0

Signed-off-by: Kris Nóva <kris@nivenly.com>
2020-09-25 08:18:48 -07:00
Mark Stemm
33793d233b Rule(Disallowed K8s User): quote colons
It turns out if you read this rules file with falco versions 0.24.0 and
earlier, it can't parse the bare string containing colons:

(Ignore the misleading error context, that's a different problem):

```
Thu Sep 10 10:31:23 2020: Falco initialized with configuration file
/etc/falco/falco.yaml
Thu Sep 10 10:31:23 2020: Loading rules from file
/tmp/k8s_audit_rules.yaml:
Thu Sep 10 10:31:23 2020: Runtime error: found unexpected ':'
---
  source: k8s_audit
    tags: [k8s]
    # In a local/user rules file, you could override this macro to
```

I think the change in 0.25.0 to use a bundled libyaml fixed the problem,
as it also upgraded libyaml to a version that fixed
https://github.com/yaml/libyaml/pull/104.

Work around the problem with earlier falco releases by quoting the colon.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2020-09-23 17:48:36 +02:00
Mark Stemm
331b2971be rule(Delete or rename shell history):skip dockerfs
In some cases, when removing a container, dockerd will itself remove the
entire overlay filesystem, including a shell history file:

---
Shell history had been deleted or renamed (user=root type=unlinkat
command=dockerd -H fd://
... name=/var/lib/docker/overlay2/.../root/.bash_history ..
---

To avoid these FPs, skip paths starting with /var/lib/docker.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2020-09-23 17:48:36 +02:00
Leonardo Grasso
558b18ea67 build: update the driver version to 2aa88dc
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2020-09-18 17:27:45 +02:00
Leonardo Grasso
bbfb27777b build: remove macrodefs about time (musl build)
See https://github.com/draios/sysdig/pull/1684

Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2020-09-18 17:27:45 +02:00
Hiroki Suezawa
5b926386a8 rule(macro consider_packet_socket_communication): change a value to always_true
Signed-off-by: Hiroki Suezawa <suezawa@gmail.com>
2020-09-18 09:47:10 +02:00
33 changed files with 116 additions and 1220 deletions

View File

@@ -1,5 +1,40 @@
# Change Log
## v0.26.0
Released on 2020-24-09
### Major Changes
* new: driver updated to 2aa88dcf6243982697811df4c1b484bcbe9488a2 [[#1410](https://github.com/falcosecurity/falco/pull/1410)]
* new(scripts/falco-driver-loader): detect and try to build the Falco kernel module driver using different GCC versions available in the current environment. [[#1408](https://github.com/falcosecurity/falco/pull/1408)]
* new: tgz (tarball) containing the statically-linked (musl) binary of Falco is now automatically built and published on bintray [[#1377](https://github.com/falcosecurity/falco/pull/1377)]
### Minor Changes
* update: bump Falco engine version to 7 [[#1381](https://github.com/falcosecurity/falco/pull/1381)]
* update: the required_engine_version is now on by default [[#1381](https://github.com/falcosecurity/falco/pull/1381)]
* update: falcosecurity/falco-no-driver image now uses the statically-linked Falco [[#1377](https://github.com/falcosecurity/falco/pull/1377)]
* docs(proposals): artifacts storage [[#1375](https://github.com/falcosecurity/falco/pull/1375)]
* docs(proposals): artifacts cleanup [[#1375](https://github.com/falcosecurity/falco/pull/1375)]
### Rule Changes
* rule: Address several sources of FPs, primarily from GKE environments. [[#1372](https://github.com/falcosecurity/falco/pull/1372)]
* rule(macro inbound_outbound): add brackets to disambiguate operator precedence [[#1373](https://github.com/falcosecurity/falco/pull/1373)]
* rule(macro redis_writing_conf): add brackets to disambiguate operator precedence [[#1373](https://github.com/falcosecurity/falco/pull/1373)]
* rule(macro run_by_foreman): add brackets to disambiguate operator precedence [[#1373](https://github.com/falcosecurity/falco/pull/1373)]
* rule(macro consider_packet_socket_communication): enable "Packet socket created in container" rule by default. [[#1402](https://github.com/falcosecurity/falco/pull/1402)]
* rule(Delete or rename shell history): skip docker overlay filesystems when considering bash history [[#1393](https://github.com/falcosecurity/falco/pull/1393)]
* rule(Disallowed K8s User): quote colons in user names [[#1393](https://github.com/falcosecurity/falco/pull/1393)]
* rule(macro falco_sensitive_mount_containers): Adds a trailing slash to avoid repo naming issues [[#1394](https://github.com/falcosecurity/falco/pull/1394)]
* rule: adds user.loginuid to the default Falco rules that also contain user.name [[#1369](https://github.com/falcosecurity/falco/pull/1369)]
This file documents all notable changes to Falco. The release numbering uses [semantic versioning](http://semver.org).
## v0.25.0

View File

@@ -57,7 +57,7 @@ if(MINIMAL_BUILD)
endif()
if(MUSL_OPTIMIZED_BUILD)
set(MUSL_FLAGS "-static -Os -D__NEED_struct_timespec -D__NEED_time_t")
set(MUSL_FLAGS "-static -Os")
endif()
set(CMAKE_COMMON_FLAGS "-Wall -ggdb ${DRAIOS_FEATURE_FLAGS} ${MINIMAL_BUILD_FLAGS} ${MUSL_FLAGS}")

View File

@@ -10,8 +10,10 @@ Finally, on the proposed due date the assignees for the upcoming release proceed
## Pre-Release Checklist
Before cutting a release we need to do some homework in the Falco repository. This should take 5 minutes using the GitHub UI.
### 1. Release notes
- Let `YYYY-MM-DD` the day before of the [latest release](https://github.com/falcosecurity/falco/releases)
- Find the LAST release (-1) and use `YYYY-MM-DD` as the day before of the [latest release](https://github.com/falcosecurity/falco/releases)
- Check the release note block of every PR matching the `is:pr is:merged closed:>YYYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+closed%3A%3EYYYY-MM-DD)
- Ensure the release note block follows the [commit convention](https://github.com/falcosecurity/falco/blob/master/CONTRIBUTING.md#commit-convention), otherwise fix its content
- If the PR has no milestone, assign it to the milestone currently undergoing release
@@ -28,14 +30,15 @@ Finally, on the proposed due date the assignees for the upcoming release proceed
- If any, manually correct it then open an issue to automate version number bumping later
- Versions table in the `README.md` update itself automatically
- Generate the change log https://github.com/leodido/rn2md, or https://fs.fntlnz.wtf/falco/milestones-changelog.txt for the lazy people (it updates every 5 minutes)
- Add the lastest changes on top the previous `CHANGELOG.md`
- If you review timeout errors with `rn2md` try to generate an GitHub Oauth access token and use `-t`
- Add the latest changes on top the previous `CHANGELOG.md`
- Submit a PR with the above modifications
- Await PR approval
- Close the completed milestone as soon PR is merged
- Close the completed milestone as soon as the PR is merged
## Release
Let `x.y.z` the new version.
Now assume `x.y.z` is the new version.
### 1. Create a tag

View File

@@ -29,8 +29,8 @@ file(MAKE_DIRECTORY ${SYSDIG_CMAKE_WORKING_DIR})
# default below In case you want to test against another sysdig version just pass the variable - ie., `cmake
# -DSYSDIG_VERSION=dev ..`
if(NOT SYSDIG_VERSION)
set(SYSDIG_VERSION "73554b9c48b06612eb50494ee6fa5b779c57edc0") # todo(leogr): set the correct version and checksum before merging
set(SYSDIG_CHECKSUM "SHA256=c1c73498a834533dea61c979786a4ac3866743c17829d81aef209ddaa1b31538")
set(SYSDIG_VERSION "2aa88dcf6243982697811df4c1b484bcbe9488a2")
set(SYSDIG_CHECKSUM "SHA256=a737077543a6f3473ab306b424bcf7385d788149829ed1538252661b0f20d0f6")
endif()
set(PROBE_VERSION "${SYSDIG_VERSION}")

View File

@@ -2619,6 +2619,7 @@
desc: Detect shell history deletion
condition: >
(modify and (
not evt.arg.name startswith /var/lib/docker and (
evt.arg.name contains "bash_history" or
evt.arg.name contains "zsh_history" or
evt.arg.name contains "fish_read_history" or
@@ -2630,12 +2631,13 @@
evt.arg.path contains "bash_history" or
evt.arg.path contains "zsh_history" or
evt.arg.path contains "fish_read_history" or
evt.arg.path endswith "fish_history")) or
evt.arg.path endswith "fish_history"))) or
(open_write and (
not fd.name startswith /var/lib/docker and (
fd.name contains "bash_history" or
fd.name contains "zsh_history" or
fd.name contains "fish_read_history" or
fd.name endswith "fish_history") and evt.arg.flags contains "O_TRUNC")
fd.name endswith "fish_history")) and evt.arg.flags contains "O_TRUNC")
output: >
Shell history had been deleted or renamed (user=%user.name user_loginuid=%user.loginuid type=%evt.type command=%proc.cmdline fd.name=%fd.name name=%evt.arg.name path=%evt.arg.path oldpath=%evt.arg.oldpath %container.info)
priority:
@@ -2859,17 +2861,16 @@
tags: [container, mitre_execution]
# This rule is not enabled by default, as there are legitimate use
# cases for raw packet. If you want to enable it, modify the
# following macro.
# This rule is enabled by default.
# If you want to disable it, modify the following macro.
- macro: consider_packet_socket_communication
condition: (never_true)
condition: (always_true)
- list: user_known_packet_socket_binaries
items: []
- rule: Packet socket created in container
desc: Detect new packet socket at the device driver (OSI Layer 2) level in a container. Packet socket could be used to do ARP Spoofing by attacker.
desc: Detect new packet socket at the device driver (OSI Layer 2) level in a container. Packet socket could be used for ARP Spoofing and privilege escalation(CVE-2020-14386) by attacker.
condition: evt.type=socket and evt.arg[0]=AF_PACKET and consider_packet_socket_communication and container and not proc.name in (user_known_packet_socket_binaries)
output: Packet socket was created in a container (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline socket_info=%evt.args container_id=%container.id container_name=%container.name image=%container.image.repository:%container.image.tag)
priority: NOTICE

View File

@@ -49,7 +49,7 @@
"kubernetes-admin",
vertical_pod_autoscaler_users,
cluster-autoscaler,
system:addon-manager
"system:addon-manager"
]
- rule: Disallowed K8s User

View File

@@ -585,8 +585,7 @@ class FalcoTest(Test):
self.check_rules_warnings(res)
if len(self.rules_events) > 0:
self.check_rules_events(res)
if len(self.validate_rules_file) == 0:
self.check_detections(res)
self.check_detections(res)
if len(self.detect_counts) > 0:
self.check_detections_by_rule(res)
self.check_json_output(res)

View File

@@ -262,7 +262,6 @@ trace_files: !mux
invalid_not_yaml:
exit_status: 1
stdout_is: |+
1 errors:
Rules content is not yaml
---
This is not yaml
@@ -274,7 +273,6 @@ trace_files: !mux
invalid_not_array:
exit_status: 1
stdout_is: |+
1 errors:
Rules content is not yaml array of objects
---
foo: bar
@@ -286,7 +284,6 @@ trace_files: !mux
invalid_array_item_not_object:
exit_status: 1
stdout_is: |+
1 errors:
Unexpected element of type string. Each element should be a yaml associative array.
---
- foo
@@ -298,7 +295,6 @@ trace_files: !mux
invalid_unexpected object:
exit_status: 1
stdout_is: |+
1 errors:
Unknown rule object: {foo="bar"}
---
- foo: bar
@@ -310,7 +306,6 @@ trace_files: !mux
invalid_engine_version_not_number:
exit_status: 1
stdout_is: |+
1 errors:
Value of required_engine_version must be a number
---
- required_engine_version: not-a-number
@@ -322,7 +317,6 @@ trace_files: !mux
invalid_yaml_parse_error:
exit_status: 1
stdout_is: |+
1 errors:
mapping values are not allowed in this context
---
this : is : not : yaml
@@ -334,7 +328,6 @@ trace_files: !mux
invalid_list_without_items:
exit_status: 1
stdout_is: |+
1 errors:
List must have property items
---
- list: bad_list
@@ -347,7 +340,6 @@ trace_files: !mux
invalid_macro_without_condition:
exit_status: 1
stdout_is: |+
1 errors:
Macro must have property condition
---
- macro: bad_macro
@@ -360,7 +352,6 @@ trace_files: !mux
invalid_rule_without_output:
exit_status: 1
stdout_is: |+
1 errors:
Rule must have property output
---
- rule: no output rule
@@ -375,7 +366,6 @@ trace_files: !mux
invalid_append_rule_without_condition:
exit_status: 1
stdout_is: |+
1 errors:
Rule must have property condition
---
- rule: no condition rule
@@ -388,7 +378,6 @@ trace_files: !mux
invalid_append_macro_dangling:
exit_status: 1
stdout_is: |+
1 errors:
Macro dangling append has 'append' key but no macro by that name already exists
---
- macro: dangling append
@@ -402,7 +391,6 @@ trace_files: !mux
invalid_list_append_dangling:
exit_status: 1
stdout_is: |+
1 errors:
List my_list has 'append' key but no list by that name already exists
---
- list: my_list
@@ -416,7 +404,6 @@ trace_files: !mux
invalid_rule_append_dangling:
exit_status: 1
stdout_is: |+
1 errors:
Rule my_rule has 'append' key but no rule by that name already exists
---
- rule: my_rule
@@ -463,7 +450,6 @@ trace_files: !mux
invalid_overwrite_macro_multiple_docs:
exit_status: 1
stdout_is: |+
1 errors:
Compilation error when compiling "foo": Undefined macro 'foo' used in filter.
---
- macro: some macro
@@ -477,7 +463,6 @@ trace_files: !mux
invalid_append_macro_multiple_docs:
exit_status: 1
stdout_is: |+
1 errors:
Compilation error when compiling "evt.type=execve foo": 17: syntax error, unexpected 'foo', expecting 'or', 'and'
---
- macro: some macro
@@ -536,7 +521,6 @@ trace_files: !mux
invalid_overwrite_rule_multiple_docs:
exit_status: 1
stdout_is: |+
1 errors:
Undefined macro 'bar' used in filter.
---
- rule: some rule
@@ -575,7 +559,6 @@ trace_files: !mux
invalid_missing_rule_name:
exit_status: 1
stdout_is: |+
1 errors:
Rule name is empty
---
- rule:
@@ -590,7 +573,6 @@ trace_files: !mux
invalid_missing_list_name:
exit_status: 1
stdout_is: |+
1 errors:
List name is empty
---
- list:
@@ -603,7 +585,6 @@ trace_files: !mux
invalid_missing_macro_name:
exit_status: 1
stdout_is: |+
1 errors:
Macro name is empty
---
- macro:

View File

@@ -1,259 +0,0 @@
#
# Copyright (C) 2016-2020 The Falco Authors..
#
# This file is part of falco.
#
# 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.
#
trace_files: !mux
rule_exception_no_fields:
exit_status: 1
stdout_is: |+
1 errors:
Rule exception item ex1: must have fields property with a list of fields
---
- rule: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
priority: error
---
validate_rules_file:
- rules/exceptions/rule_item_no_fields.yaml
trace_file: trace_files/cat_write.scap
exception_no_values:
exit_status: 1
stdout_is: |+
1 errors:
Exception item ex1: must have values property with a list of values
---
- exception: My Rule
items:
- name: ex1
---
validate_rules_file:
- rules/exceptions/exception_item_no_values.yaml
trace_file: trace_files/cat_write.scap
rule_exception_no_name:
exit_status: 1
stdout_is: |+
1 errors:
Rule exception item must have name property
---
- rule: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- fields: [proc.name, fd.filename]
priority: error
---
validate_rules_file:
- rules/exceptions/rule_item_no_name.yaml
trace_file: trace_files/cat_write.scap
exception_no_name:
exit_status: 1
stdout_is: |+
1 errors:
Exception item must have name property
---
- exception: My Rule
items:
- values:
- [nginx, /tmp/foo]
---
validate_rules_file:
- rules/exceptions/exception_item_no_name.yaml
trace_file: trace_files/cat_write.scap
rule_exception_append:
exit_status: 1
stdout_is: |+
1 errors:
Can not append exceptions to existing rule, only conditions
---
- rule: My Rule
condition: and proc.name=apache
exceptions:
- name: ex2
fields: [proc.name, fd.filename]
append: true
---
validate_rules_file:
- rules/exceptions/rule_append_exception.yaml
trace_file: trace_files/cat_write.scap
rule_exception_unknown_fields:
exit_status: 1
stdout_is: |+
1 errors:
Rule exception item ex1: field name not.exist is not a supported filter field
---
- rule: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [not.exist]
priority: error
---
validate_rules_file:
- rules/exceptions/rule_item_unknown_fields.yaml
trace_file: trace_files/cat_write.scap
rule_exception_comps_fields_len_mismatch:
exit_status: 1
stdout_is: |+
1 errors:
Rule exception item ex1: fields and comps lists must have equal length
---
- rule: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
comps: [=]
priority: error
---
validate_rules_file:
- rules/exceptions/rule_item_comps_fields_len_mismatch.yaml
trace_file: trace_files/cat_write.scap
rule_exception_unknown_comp:
exit_status: 1
stdout_is: |+
1 errors:
Rule exception item ex1: comparison operator no-comp is not a supported comparison operator
---
- rule: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
comps: [=, no-comp]
priority: error
---
validate_rules_file:
- rules/exceptions/rule_item_unknown_comp.yaml
trace_file: trace_files/cat_write.scap
exception_fields_values_len_mismatch:
exit_status: 1
stdout_is: |+
1 errors:
Exception item ex1: fields and values lists must have equal length
---
- exception: My Rule
items:
- name: ex1
values:
- [nginx]
---
validate_rules_file:
- rules/exceptions/exception_item_fields_values_len_mismatch.yaml
trace_file: trace_files/cat_write.scap
exception_item_not_in_rule:
exit_status: 0
stderr_contains: |+
1 warnings:
Exception My Rule: no set of fields matching name ex2
validate_rules_file:
- rules/exceptions/exception_item_not_in_rule.yaml
trace_file: trace_files/cat_write.scap
rule_without_exception:
exit_status: 0
stderr_contains: |+
1 warnings:
Rule My Rule: consider adding an exceptions property to define supported exceptions fields
validate_rules_file:
- rules/exceptions/rule_without_exception.yaml
trace_file: trace_files/cat_write.scap
rule_exception_no_values:
detect: True
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_no_values.yaml
trace_file: trace_files/cat_write.scap
rule_exception_one_value:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_one_value.yaml
trace_file: trace_files/cat_write.scap
rule_exception_second_value:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_second_value.yaml
trace_file: trace_files/cat_write.scap
rule_exception_second_item:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_second_item.yaml
trace_file: trace_files/cat_write.scap
rule_exception_third_item:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_third_item.yaml
trace_file: trace_files/cat_write.scap
rule_exception_quoted:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_quoted.yaml
trace_file: trace_files/cat_write.scap
rule_exception_append_values:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_append.yaml
trace_file: trace_files/cat_write.scap
rule_exception_values_before:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_values_before.yaml
trace_file: trace_files/cat_write.scap
rule_exception_comp:
detect: False
detect_level: WARNING
rules_file:
- rules/exceptions/rule_exception_comp.yaml
trace_file: trace_files/cat_write.scap

View File

@@ -1,30 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
priority: error
- exception: My Rule
items:
- name: ex1
values:
- [nginx]

View File

@@ -1,29 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
priority: error
- exception: My Rule
items:
- values:
- [nginx, /tmp/foo]

View File

@@ -1,28 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
priority: error
- exception: My Rule
items:
- name: ex1

View File

@@ -1,30 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
priority: error
- exception: My Rule
items:
- name: ex2
values:
- [apache, /tmp]

View File

@@ -1,31 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
priority: error
- rule: My Rule
condition: and proc.name=apache
exceptions:
- name: ex2
fields: [proc.name, fd.filename]
append: true

View File

@@ -1,40 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name
values:
- [not-cat]
- exception: Open From Cat
items:
- name: proc_name
values:
- [cat]

View File

@@ -1,37 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_contains
fields: [proc.name]
comps: [contains]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name_contains
values:
- [cat]

View File

@@ -1,28 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING

View File

@@ -1,34 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name
values:
- [cat]

View File

@@ -1,35 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name_cmdline
values:
- [not-cat, not-cat]
- [cat, '"cat /dev/null"']

View File

@@ -1,40 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name
values:
- [not-cat]
- name: proc_name_cmdline
values:
- [cat, "cat /dev/null"]
- name: proc_name_cmdline_pname
values:
- [not-cat, "cat /dev/null", bash]

View File

@@ -1,35 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name_cmdline
values:
- [not-cat, not-cat]
- [cat, "cat /dev/null"]

View File

@@ -1,40 +0,0 @@
#
# Copyright (C) 2020 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING
- exception: Open From Cat
items:
- name: proc_name
values:
- [not-cat]
- name: proc_name_cmdline
values:
- [not-cat, "cat /dev/null"]
- name: proc_name_cmdline_pname
values:
- [cat, "cat /dev/null", bash]

View File

@@ -1,36 +0,0 @@
#
# Copyright (C) 2020 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.
#
- exception: Open From Cat
items:
- name: proc_name
values:
- [cat]
- 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_name
fields: [proc.name]
- name: proc_name_cmdline
fields: [proc.name, proc.cmdline]
- name: proc_name_cmdline_pname
fields: [proc.name, proc.cmdline, proc.pname]
priority: WARNING

View File

@@ -1,25 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
comps: [=]
priority: error

View File

@@ -1,23 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
priority: error

View File

@@ -1,23 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- fields: [proc.name, fd.filename]
priority: error

View File

@@ -1,25 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [proc.name, fd.filename]
comps: [=, no-comp]
priority: error

View File

@@ -1,24 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
exceptions:
- name: ex1
fields: [not.exist]
priority: error

View File

@@ -1,21 +0,0 @@
#
# Copyright (C) 2020 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: My Rule
desc: Some desc
condition: evt.type=open and proc.name=cat
output: Some output
priority: error

View File

@@ -98,7 +98,7 @@ function run_tests() {
# as we're watching the return status when running avocado.
set +e
TEST_RC=0
suites=($SCRIPTDIR/falco_traces.yaml $SCRIPTDIR/falco_tests.yaml $SCRIPTDIR/falco_k8s_audit_tests.yaml $SCRIPTDIR/falco_tests_psp.yaml $SCRIPTDIR/falco_tests_exceptions.yaml)
suites=($SCRIPTDIR/falco_traces.yaml $SCRIPTDIR/falco_tests.yaml $SCRIPTDIR/falco_k8s_audit_tests.yaml $SCRIPTDIR/falco_tests_psp.yaml)
if [ "$SKIP_PACKAGES_TESTS" = false ] ; then
suites+=($SCRIPTDIR/falco_tests_package.yaml)

View File

@@ -126,31 +126,11 @@ function set_output(output_format, state)
end
end
-- This should be keep in sync with parser.lua
defined_comp_operators = {
["="]=1,
["=="] = 1,
["!"] = 1,
["<="] = 1,
[">="] = 1,
["<"] = 1,
[">"] = 1,
["contains"] = 1,
["icontains"] = 1,
["glob"] = 1,
["startswith"] = 1,
["endswith"] = 1,
["in"] = 1,
["intersects"] = 1,
["pmatch"] = 1
}
-- Note that the rules_by_name and rules_by_idx refer to the same rule
-- object. The by_name index is used for things like describing rules,
-- and the by_idx index is used to map the relational node index back
-- to a rule.
local state = {macros={}, lists={}, filter_ast=nil, rules_by_name={},
exceptions_by_name={},
skipped_rules_by_name={}, macros_by_name={}, lists_by_name={},
n_rules=0, rules_by_idx={}, ordered_rule_names={}, ordered_macro_names={}, ordered_list_names={}}
@@ -276,18 +256,16 @@ end
function build_error(rules_lines, row, num_lines, err)
local ret = err.."\n---\n"..get_lines(rules_lines, row, num_lines).."---"
return {ret}
return ret
end
function build_error_with_context(ctx, err)
local ret = err.."\n---\n"..ctx.."---"
return {ret}
return ret
end
function load_rules_doc(rules_mgr, doc, load_state)
local warnings = {}
-- Iterate over yaml list. In this pass, all we're doing is
-- populating the set of rules, macros, and lists. We're not
-- expanding/compiling anything yet. All that will happen in a
@@ -301,7 +279,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
load_state.indices[load_state.cur_item_idx])
if (not (type(v) == "table")) then
return false, build_error_with_context(context, "Unexpected element of type " ..type(v)..". Each element should be a yaml associative array."), warnings
return false, build_error_with_context(context, "Unexpected element of type " ..type(v)..". Each element should be a yaml associative array.")
end
v['context'] = context
@@ -313,13 +291,13 @@ function load_rules_doc(rules_mgr, doc, load_state)
end
if falco_rules.engine_version(rules_mgr) < v['required_engine_version'] then
return false, build_error_with_context(v['context'], "Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr)), warnings
return false, build_error_with_context(v['context'], "Rules require engine version "..v['required_engine_version']..", but engine version is "..falco_rules.engine_version(rules_mgr))
end
elseif (v['macro']) then
if (v['macro'] == nil or type(v['macro']) == "table") then
return false, build_error_with_context(v['context'], "Macro name is empty"), warnings
return false, build_error_with_context(v['context'], "Macro name is empty")
end
if v['source'] == nil then
@@ -332,7 +310,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
for j, field in ipairs({'condition'}) do
if (v[field] == nil) then
return false, build_error_with_context(v['context'], "Macro must have property "..field), warnings
return false, build_error_with_context(v['context'], "Macro must have property "..field)
end
end
@@ -345,7 +323,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
if append then
if state.macros_by_name[v['macro']] == nil then
return false, build_error_with_context(v['context'], "Macro " ..v['macro'].. " has 'append' key but no macro by that name already exists"), warnings
return false, build_error_with_context(v['context'], "Macro " ..v['macro'].. " has 'append' key but no macro by that name already exists")
end
state.macros_by_name[v['macro']]['condition'] = state.macros_by_name[v['macro']]['condition'] .. " " .. v['condition']
@@ -360,7 +338,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
elseif (v['list']) then
if (v['list'] == nil or type(v['list']) == "table") then
return false, build_error_with_context(v['context'], "List name is empty"), warnings
return false, build_error_with_context(v['context'], "List name is empty")
end
if state.lists_by_name[v['list']] == nil then
@@ -369,7 +347,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
for j, field in ipairs({'items'}) do
if (v[field] == nil) then
return false, build_error_with_context(v['context'], "List must have property "..field), warnings
return false, build_error_with_context(v['context'], "List must have property "..field)
end
end
@@ -382,7 +360,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
if append then
if state.lists_by_name[v['list']] == nil then
return false, build_error_with_context(v['context'], "List " ..v['list'].. " has 'append' key but no list by that name already exists"), warnings
return false, build_error_with_context(v['context'], "List " ..v['list'].. " has 'append' key but no list by that name already exists")
end
for j, elem in ipairs(v['items']) do
@@ -395,7 +373,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
elseif (v['rule']) then
if (v['rule'] == nil or type(v['rule']) == "table") then
return false, build_error_with_context(v['context'], "Rule name is empty"), warnings
return false, build_error_with_context(v['context'], "Rule name is empty")
end
-- By default, if a rule's condition refers to an unknown
@@ -408,53 +386,6 @@ function load_rules_doc(rules_mgr, doc, load_state)
v['source'] = "syscall"
end
-- Add an empty exceptions property to the rule if not
-- defined, but add a warning about defining one
if v['exceptions'] == nil then
warnings[#warnings + 1] = "Rule "..v['rule']..": consider adding an exceptions property to define supported exceptions fields"
v['exceptions'] = {}
end
-- Validate the contents of the rule exception
if next(v['exceptions']) ~= nil then
for i, eitem in ipairs(v['exceptions']) do
local name = eitem['name']
local fields = eitem['fields']
local comps = eitem['comps']
if name == nil then
return false, build_error_with_context(v['context'], "Rule exception item must have name property"), warnings
end
if fields == nil then
return false, build_error_with_context(v['context'], "Rule exception item "..name..": must have fields property with a list of fields"), warnings
end
if comps == nil then
comps = {}
for c=1,#fields do
table.insert(comps, "=")
end
eitem['comps'] = comps
else
if #fields ~= #comps then
return false, build_error_with_context(v['context'], "Rule exception item "..name..": fields and comps lists must have equal length"), warnings
end
end
for j, fname in ipairs(fields) do
if defined_noarg_filters[fname] == nil then
return false, build_error_with_context(v['context'], "Rule exception item "..name..": field name "..fname.." is not a supported filter field"), warnings
end
end
for j, comp in ipairs(comps) do
if defined_comp_operators[comp] == nil then
return false, build_error_with_context(v['context'], "Rule exception item "..name..": comparison operator "..comp.." is not a supported comparison operator"), warnings
end
end
end
end
-- Possibly append to the condition field of an existing rule
append = false
@@ -467,21 +398,15 @@ function load_rules_doc(rules_mgr, doc, load_state)
-- For append rules, all you need is the condition
for j, field in ipairs({'condition'}) do
if (v[field] == nil) then
return false, build_error_with_context(v['context'], "Rule must have property "..field), warnings
return false, build_error_with_context(v['context'], "Rule must have property "..field)
end
end
if state.rules_by_name[v['rule']] == nil then
if state.skipped_rules_by_name[v['rule']] == nil then
return false, build_error_with_context(v['context'], "Rule " ..v['rule'].. " has 'append' key but no rule by that name already exists"), warnings
return false, build_error_with_context(v['context'], "Rule " ..v['rule'].. " has 'append' key but no rule by that name already exists")
end
else
-- You can't append exceptions to a rule
if v['exceptions'] ~= nil then
return false, build_error_with_context(v['context'], "Can not append exceptions to existing rule, only conditions"), warnings
end
state.rules_by_name[v['rule']]['condition'] = state.rules_by_name[v['rule']]['condition'] .. " " .. v['condition']
-- Add the current object to the context of the base rule
@@ -492,7 +417,7 @@ function load_rules_doc(rules_mgr, doc, load_state)
for j, field in ipairs({'condition', 'output', 'desc', 'priority'}) do
if (v[field] == nil) then
return false, build_error_with_context(v['context'], "Rule must have property "..field), warnings
return false, build_error_with_context(v['context'], "Rule must have property "..field)
end
end
@@ -520,77 +445,17 @@ function load_rules_doc(rules_mgr, doc, load_state)
state.skipped_rules_by_name[v['rule']] = v
end
end
elseif (v['exception']) then
for i, eitem in ipairs(v['items']) do
local name = eitem['name']
local fields = eitem['values']
if name == nil then
return false, build_error_with_context(v['context'], "Exception item must have name property"), warnings
end
if fields == nil then
return false, build_error_with_context(v['context'], "Exception item "..name..": must have values property with a list of values"), warnings
end
end
state.exceptions_by_name[v['exception']] = v
else
-- Remove the context from the table, so the table is exactly what was parsed
local context = v['context']
arr = build_error_with_context(context, "Unknown top level object: "..table.tostring(v))
warnings[#warnings + 1] = arr[1]
v['context'] = nil
return false, build_error_with_context(context, "Unknown rule object: "..table.tostring(v))
end
end
return true, {}, warnings
return true, ""
end
-- cond and not ((proc.name=apk and fd.directory=/usr/lib/alpine) or (proc.name=npm and fd.directory=/usr/node/bin) or (con
function build_exception_condition_string(eitem, rexitems)
local fields = rexitems[eitem['name']]['fields']
local comps = rexitems[eitem['name']]['comps']
local icond = ""
for i, values in ipairs(eitem['values']) do
if #fields ~= #values then
return nil, "Exception item "..eitem['name']..": fields and values lists must have equal length"
end
if icond ~= "" then
icond=icond.." or "
end
icond=icond.."("
for k=1,#fields do
if k > 1 then
icond=icond.." and "
end
-- Quote the value if not already quoted
local ival = values[k]
if string.sub(values[k], 1, 1) ~= "'" and string.sub(values[k], 1, 1) ~= '"' then
ival = "\""..ival.."\""
end
icond = icond..fields[k].." "..comps[k]..ival
end
icond=icond..")"
end
return icond, nil
end
-- Returns:
-- - Load Result: bool
-- - required engine version. will be nil when load result is false
-- - List of Errors
-- - List of Warnings
function load_rules(sinsp_lua_parser,
json_lua_parser,
rules_content,
@@ -601,8 +466,6 @@ function load_rules(sinsp_lua_parser,
replace_container_info,
min_priority)
local warnings = {}
local load_state = {lines={}, indices={}, cur_item_idx=0, min_priority=min_priority, required_engine_version=0}
load_state.lines, load_state.indices = split_lines(rules_content)
@@ -624,42 +487,36 @@ function load_rules(sinsp_lua_parser,
row = tonumber(row)
col = tonumber(col)
return false, nil, build_error(load_state.lines, row, 3, docs), warnings
return false, build_error(load_state.lines, row, 3, docs)
end
if docs == nil then
-- An empty rules file is acceptable
return true, load_state.required_engine_version, {}, warnings
return true, load_state.required_engine_version
end
if type(docs) ~= "table" then
return false, nil, build_error(load_state.lines, 1, 1, "Rules content is not yaml"), warnings
return false, build_error(load_state.lines, 1, 1, "Rules content is not yaml")
end
for docidx, doc in ipairs(docs) do
if type(doc) ~= "table" then
return false, nil, build_error(load_state.lines, 1, 1, "Rules content is not yaml"), warnings
return false, build_error(load_state.lines, 1, 1, "Rules content is not yaml")
end
-- Look for non-numeric indices--implies that document is not array
-- of objects.
for key, val in pairs(doc) do
if type(key) ~= "number" then
return false, nil, build_error(load_state.lines, 1, 1, "Rules content is not yaml array of objects"), warnings
return false, build_error(load_state.lines, 1, 1, "Rules content is not yaml array of objects")
end
end
res, errors, doc_warnings = load_rules_doc(rules_mgr, doc, load_state)
if (doc_warnings ~= nil) then
for idx, warning in pairs(doc_warnings) do
table.insert(warnings, warning)
end
end
res, errstr = load_rules_doc(rules_mgr, doc, load_state)
if not res then
return res, nil, errors, warnings
return res, errstr
end
end
@@ -669,52 +526,6 @@ function load_rules(sinsp_lua_parser,
-- in which they appeared in the file(s).
reset_rules(rules_mgr)
-- Turn exceptions into condition strings and add them to each
-- rule's condition
for ename, exc in pairs(state.exceptions_by_name) do
if state.rules_by_name[ename] == nil then
warnings[#warnings + 1] = "No rule matching exception name "..exc['exception']
else
local rexitems = {}
-- Create a map from item name to object, speeds up matching
for i, iobj in ipairs(state.rules_by_name[ename].exceptions) do
rexitems[iobj['name']] = iobj
end
-- Usep the exception items, combined with any exceptions in
-- the rules, to build condition strings to append to the
-- rule's condition.
local econd = ""
for i, eitem in ipairs(exc['items']) do
if rexitems[eitem['name']] == nil then
warnings[#warnings + 1] = "Exception "..ename..": no set of fields matching name "..eitem['name']
else
icond, err = build_exception_condition_string(eitem, rexitems)
if err ~= nil then
return false, nil, build_error_with_context(exc['context'], err), warnings
end
if econd == "" then
econd = econd.." and not ("..icond
else
econd = econd.." or "..icond
end
end
end
if econd ~= "" then
econd=econd..")"
state.rules_by_name[ename]['condition'] = "("..state.rules_by_name[ename]['condition']..") "..econd
end
end
end
for i, name in ipairs(state.ordered_list_names) do
local v = state.lists_by_name[name]
@@ -745,7 +556,7 @@ function load_rules(sinsp_lua_parser,
local status, ast = compiler.compile_macro(v['condition'], state.macros, state.lists)
if status == false then
return false, nil, build_error_with_context(v['context'], ast), warnings
return false, build_error_with_context(v['context'], ast)
end
if v['source'] == "syscall" then
@@ -770,7 +581,7 @@ function load_rules(sinsp_lua_parser,
state.macros, state.lists)
if status == false then
return false, nil, build_error_with_context(v['context'], filter_ast), warnings
return false, build_error_with_context(v['context'], filter_ast)
end
local evtttypes = {}
@@ -820,10 +631,12 @@ function load_rules(sinsp_lua_parser,
end
if not found then
msg = "rule \""..v['rule'].."\" contains unknown filter "..filter
warnings[#warnings + 1] = msg
if not v['skip-if-unknown-filter'] then
if v['skip-if-unknown-filter'] then
if verbose then
print("Skipping rule \""..v['rule'].."\" that contains unknown filter "..filter)
end
goto next_rule
else
error("Rule \""..v['rule'].."\" contains unknown filter "..filter)
end
end
@@ -906,30 +719,30 @@ function load_rules(sinsp_lua_parser,
formatter = formats.formatter(v['source'], v['output'])
formats.free_formatter(v['source'], formatter)
else
return false, nil, build_error_with_context(v['context'], "Unexpected type in load_rule: "..filter_ast.type), warnings
return false, build_error_with_context(v['context'], "Unexpected type in load_rule: "..filter_ast.type)
end
::next_rule::
end
-- Print info on any dangling lists or macros that were not used anywhere
for name, macro in pairs(state.macros) do
if macro.used == false then
msg = "macro "..name.." not refered to by any rule/macro"
warnings[#warnings + 1] = msg
if verbose then
-- Print info on any dangling lists or macros that were not used anywhere
for name, macro in pairs(state.macros) do
if macro.used == false then
print("Warning: macro "..name.." not refered to by any rule/macro")
end
end
end
for name, list in pairs(state.lists) do
if list.used == false then
msg = "list "..name.." not refered to by any rule/macro/list"
warnings[#warnings + 1] = msg
for name, list in pairs(state.lists) do
if list.used == false then
print("Warning: list "..name.." not refered to by any rule/macro/list")
end
end
end
io.flush()
return true, load_state.required_engine_version, {}, warnings
return true, load_state.required_engine_version
end
local rule_fmt = "%-50s %s"

View File

@@ -14,9 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include <sstream>
#include "rules.h"
#include "logger.h"
extern "C" {
#include "lua.h"
@@ -220,31 +219,6 @@ int falco_rules::engine_version(lua_State *ls)
return 1;
}
static std::list<std::string> get_lua_table_values(lua_State *ls, int idx)
{
std::list<std::string> ret;
if (lua_isnil(ls, idx)) {
return ret;
}
lua_pushnil(ls); /* first key */
while (lua_next(ls, idx-1) != 0) {
// key is at index -2, value is at index
// -1. We want the values.
if (! lua_isstring(ls, -1)) {
std::string err = "Non-string value in table of strings";
throw falco_exception(err);
}
ret.push_back(string(lua_tostring(ls, -1)));
// Remove value, keep key for next iteration
lua_pop(ls, 1);
}
return ret;
}
void falco_rules::load_rules(const string &rules_content,
bool verbose, bool all_events,
string &extra, bool replace_container_info,
@@ -450,7 +424,7 @@ void falco_rules::load_rules(const string &rules_content,
lua_pushstring(m_ls, extra.c_str());
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
lua_pushnumber(m_ls, min_priority);
if(lua_pcall(m_ls, 9, 4, 0) != 0)
if(lua_pcall(m_ls, 9, 2, 0) != 0)
{
const char* lerr = lua_tostring(m_ls, -1);
@@ -459,49 +433,20 @@ void falco_rules::load_rules(const string &rules_content,
throw falco_exception(err);
}
// Returns:
// Load result: bool
// required engine version: will be nil when load result is false
// array of errors
// array of warnings
bool successful = lua_toboolean(m_ls, -4);
required_engine_version = lua_tonumber(m_ls, -3);
std::list<std::string> errors = get_lua_table_values(m_ls, -2);
std::list<std::string> warnings = get_lua_table_values(m_ls, -1);
// Either returns (true, required_engine_version), or (false, error string)
bool successful = lua_toboolean(m_ls, -2);
// Concatenate errors/warnings
std::ostringstream os;
if (errors.size() > 0)
if(successful)
{
os << errors.size() << " errors:" << std::endl;
for(auto err : errors)
{
os << err << std::endl;
}
required_engine_version = lua_tonumber(m_ls, -1);
}
if (warnings.size() > 0)
else
{
os << warnings.size() << " warnings:" << std::endl;
for(auto warn : warnings)
{
os << warn << std::endl;
}
std::string err = lua_tostring(m_ls, -1);
throw falco_exception(err);
}
if(!successful)
{
throw falco_exception(os.str());
}
if (verbose && os.str() != "") {
// We don't really have a logging callback
// from the falco engine, but this would be a
// good place to use it.
fprintf(stderr, "When reading rules content: %s", os.str().c_str());
}
lua_pop(m_ls, 4);
lua_pop(m_ls, 2);
} else {
throw falco_exception("No function " + m_lua_load_rules + " found in lua rule module");

View File

@@ -804,7 +804,7 @@ int falco_init(int argc, char **argv)
}
catch(falco_exception &e)
{
printf("%s%s", prefix.c_str(), e.what());
printf("%s%s\n", prefix.c_str(), e.what());
throw;
}
printf("%sOk\n", prefix.c_str());
@@ -861,15 +861,7 @@ int falco_init(int argc, char **argv)
falco_logger::log(LOG_INFO, "Loading rules from file " + filename + ":\n");
uint64_t required_engine_version;
try {
engine->load_rules_file(filename, verbose, all_events, required_engine_version);
}
catch(falco_exception &e)
{
std::string prefix = "Could not load rules file " + filename + ": ";
throw falco_exception(prefix + e.what());
}
engine->load_rules_file(filename, verbose, all_events, required_engine_version);
required_engine_versions[filename] = required_engine_version;
}
@@ -1179,8 +1171,8 @@ int falco_init(int argc, char **argv)
falco_logger::log(LOG_ERR, "Unable to load the driver.\n");
}
open_f(inspector);
}
else
}
else
{
rethrow_exception(current_exception());
}
@@ -1289,7 +1281,7 @@ int falco_init(int argc, char **argv)
if(!trace_filename.empty() && !trace_is_scap)
{
#ifndef MINIMAL_BUILD
#ifndef MINIMAL_BUILD
read_k8s_audit_trace_file(engine,
outputs,
trace_filename);