Compare commits

...

122 Commits

Author SHA1 Message Date
Aldo Lacuku
ce4b440898 update(cmake): bump falcoctl to v0.11.0
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2025-01-27 14:25:32 +01:00
Aldo Lacuku
ac24707d03 chore(falco.yaml): remove comments about cri cli arguments
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2025-01-22 10:00:02 +01:00
Federico Di Pierro
151bc87c2f fix(ci): fixed reusable_build/publish_docker workflows.
`upload-artifact` action since v4 does not allow to upload same artifact name multiple times.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-22 10:00:02 +01:00
Federico Di Pierro
36797b0cda update(cmake): bump libs to 0.20.0 and driver to 8.0.0+driver.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-21 09:53:53 +01:00
poiana
0077a4bcb5 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-01-20 10:15:48 +01:00
zayaanshahm
77b83557ea fix(userspace/falco): use container_engines.cri.sockets in load_yaml
Signed-off-by: Zayaan Moez <zayaanmoez@outlook.com>
2025-01-17 17:07:34 +01:00
Federico Di Pierro
c9e7047d1f chore(ci): enable test-drivers for arm64 too.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-17 10:01:32 +01:00
Federico Di Pierro
ed4f330a2c chore(ci:) switch to github provided arm runners.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-17 10:01:32 +01:00
Federico Di Pierro
b66814fdd0 chore(ci): bumped actions/upload-download-artifact.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-17 10:01:32 +01:00
Federico Di Pierro
437ec7633c fix(ci): fixed Falco release debug symbols names.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-16 16:20:27 +01:00
Federico Di Pierro
5664e8715c chore(ci): build Falco in RelWithDebInfo, and upload Falco debug symbols as github artifacts.
Then, upload these artifacts as release assets.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-16 16:20:27 +01:00
Leonardo Grasso
3aa3039149 chore(docker): drop unused libelf dep from container images
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-01-16 10:41:27 +01:00
Federico Di Pierro
7339363d1a update: update falco.yaml
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-16 10:33:27 +01:00
Federico Di Pierro
5977f708bd chore: update plugins_hostinfo description with a link to the chart template.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-16 10:33:27 +01:00
Federico Di Pierro
9f9199bd69 chore(docs): update plugins_hostinfo config file comment.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-16 10:33:27 +01:00
Shane Lawrence
f23e44fcab Add TODO comment for win32.
Signed-off-by: Shane Lawrence <shane@lawrence.dev>
2025-01-16 10:05:56 +01:00
Shane Lawrence
6bf33ffd76 Add RelWithDebInfo target to produce release binary with separate debug symbols file.
Signed-off-by: Shane Lawrence <shane@lawrence.dev>
2025-01-16 10:05:56 +01:00
John Thiltges
6235e05919 update(build): relax dkms requirements to suggestions
Running in modern_ebpf mode does not require kernel build dependencies

Signed-off-by: John Thiltges <jthiltges2@unl.edu>
2025-01-16 10:04:56 +01:00
dependabot[bot]
ec9954d62d chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `283a62f` to `abf6637`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](283a62f464...abf6637e0a)

---
updated-dependencies:
- dependency-name: submodules/falcosecurity-rules
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-01-16 09:29:55 +01:00
Luca Guerra
1e455f30a6 update(ci): use 4cpu-16gb runners
Signed-off-by: Luca Guerra <luca@guerra.sh>
2025-01-16 09:27:55 +01:00
Federico Di Pierro
0bdc5909ee chore(ci): use another arm64 runner to enable back arm64 jobs.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-15 14:49:50 +01:00
Federico Di Pierro
aa312096d0 chore(userspace/engine): bump engine version and checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-15 14:49:50 +01:00
Federico Di Pierro
913e1b91ef chore(unit_tests/falco): fix test.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-15 14:49:50 +01:00
FedeDP
d44e17bb60 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-01-15 14:49:50 +01:00
Federico Aponte
ec2c2e801e chore: avoid deprecated funcs to calculate sha256
Signed-off-by: Federico Aponte <federico.aponte@sysdig.com>
2025-01-13 13:22:39 +01:00
Federico Di Pierro
3277d6e00b chore(ci): enable jemalloc in musl build.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-20 13:17:54 +01:00
Shane Lawrence
d88d6685f8 Fix accidental whitespace.
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Shane Lawrence <shane@lawrence.dev>
2024-12-19 18:25:50 +01:00
Shane Lawrence
06818263b6 Check if path exists before linking.
Signed-off-by: Shane Lawrence <shane@lawrence.dev>
2024-12-19 18:25:50 +01:00
Luca Guerra
02f3db9835 cleanup(build): remove libelf dependency
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
1239566467 fix(falco): prevent use-after-return in webserver
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
129087a08b fix(ci): consolidate sanitizers/not sanitizers jobs
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
3bc27afc14 fix(ci): use ubuntu 22.04 to build wasm due to a regression (undefined _main)
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
f2a983298e fix(build): remove zlib requirement from cpp-httplib
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
42de47a488 fix(ci): upgrade bpftool for static build
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
092b54cab6 update(build): link (BSD) libelf statically by default
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
e652d7fc85 Revert "update(build): disable musl builds"
This reverts commit 30df5738a5.

Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Luca Guerra
d7792acdf3 update(falco): update libs to latest master
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-12-19 10:31:48 +01:00
Leonardo Grasso
a975e4cbc4 docs(falco.yaml): correct buffered_outputs description
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-12-16 09:33:32 +01:00
Federico Di Pierro
fa862b57e8 update(cmake): bump jemalloc asan warning message
Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch>
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-10 15:11:03 +01:00
Federico Di Pierro
ac191b746c chore(cmake): add a warning when using both jemalloc and asan.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch>
2024-12-10 15:11:03 +01:00
Federico Di Pierro
72f4715688 chore(ci): drop jemalloc from ASAN builds.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-10 15:11:03 +01:00
Federico Di Pierro
5044f3aa7e fix(cmake): fixed jemalloc from system.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-10 15:11:03 +01:00
Federico Di Pierro
1c71777dbd new(cmake,userspace): expose jemalloc stats in stats writer and prometheus metircs.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-10 15:11:03 +01:00
Federico Di Pierro
d007418fd3 new(cmake,ci): added support for using jemalloc allocator instead of glibc one.
The jemalloc allocator is enabled by default for published packages.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-10 15:11:03 +01:00
Federico Di Pierro
f8feea63ad fix(userspace/falco): use correct filtercheck_field_info.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-06 13:33:46 +01:00
cpanato
257ae9a8c0 add attestation
Signed-off-by: cpanato <ctadeu@gmail.com>
2024-12-05 17:34:41 +01:00
Federico Di Pierro
35d8618373 chore(userspace/falco): add new suggested_output option to append_output configuration.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-05 15:34:40 +01:00
Federico Di Pierro
70ee5f4107 chore(userspace): update config schema.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-05 15:34:40 +01:00
Federico Di Pierro
114757d215 new(userspace,cmake): honor new plugins exposed suggested output formats.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-05 15:34:40 +01:00
Federico Di Pierro
9b35c0d5e0 update(userspace/falco): use ternary operator
Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch>
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-05 10:15:39 +01:00
Federico Di Pierro
211eea6abb new(userspace/falco): allow entirely disabling plugin hostinfo support.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-12-05 10:15:39 +01:00
FedeDP
9f29444b17 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-12-03 10:01:26 +01:00
Thomas Labarussias
242f25ae25 fix: update the url for the docs about the concurrent queue classes
Signed-off-by: Thomas Labarussias <issif+github@gadz.org>
2024-11-26 18:29:48 +01:00
Federico Di Pierro
ee4c9f9d4b update(changelog): updated changelog for 0.39.2.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-21 18:03:22 +01:00
poiana
563291f8d8 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-11-21 11:03:21 +01:00
Federico Di Pierro
4efbd44354 update(cmake): bumped falcoctl to v0.10.1.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-21 09:56:21 +01:00
Federico Di Pierro
0a8526dd7b fix(cmake,docker): avoid cpp-httplib requiring brotli.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-07 08:58:23 +01:00
Luca Guerra
edf36c0724 fix(docker): add brotli to the Falco image
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-11-06 16:10:18 +01:00
Leonardo Grasso
3fa8bc9bc7 fix(docker/falco-debian): usage label
Co-authored-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-11-05 17:38:11 +01:00
Leonardo Grasso
a212262194 docs(docker): update images description
Co-authored-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-11-05 17:38:11 +01:00
Leonardo Grasso
cfaf260b08 update(docker): no CMD for falco-driver-loader images
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>

Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
f4dd0b9c07 fix(docker): fix docker-compose with correct image name for Falco.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
c44d323b4b chore(ci,docker): more fixes.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
57446c38f7 chore(docker): apply some review suggestions.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
77695ace72 fix(docker): fixed small issues in the new images.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
01ab1661c0 cleanup(ci): drop -slim tag.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
58930ea8c0 new(ci,docker): renamed driver-loader-legacy to driver-loader-buster.
Moreover, ported docker images CI to new images.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
56c061f37a chore(docker): updated README.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 17:38:11 +01:00
Federico Di Pierro
1307061554 new(docker): initial work towards new docker images.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 17:38:11 +01:00
Luca Guerra
e4107c05a4 update(ci): replace aarch64 actuated runners with oracle
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-11-05 10:59:09 +01:00
Federico Di Pierro
729bf9562b update(cmake): bump yaml-cpp to latest master.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-11-05 09:29:09 +01:00
dependabot[bot]
b50903e498 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `407e997` to `283a62f`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](407e99721f...283a62f464)

---
updated-dependencies:
- dependency-name: submodules/falcosecurity-rules
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-24 10:11:12 +02:00
Mark Stemm
09a9fd4c26 Add tests for mismatched sources and append
Add additional unit tests to verify that rule loading fails when a
second rules object has a different source but the name of an existing
rules object.

Also add tests for additional rules having an empty source.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-24 08:45:12 +02:00
Mark Stemm
4a73ef8824 When overriding rules, ensure that the sources match
In places where a second rule definition might replace, append to, or
replace items from a base rule, ensure that the source of the second
rule definiton matches the first.

This already existed for defines, but for other changes. There was a
bug where a second definition might exist for a different source, but
the additional rule was used anyway.

This now returns the same error for these other changes e.g. "Rule has
been re-defined..." as define.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-24 08:45:12 +02:00
Mark Stemm
a44b311333 Add a source to rule_update_info
It's possible that someone might want to override a property for a
non-syscall rule source. To assist in this, decode any source property
for rules with append/override and save it in the rule_update_info
object. For the source property only, the value for source can be
empty e.g. 'source: ' or an empty string e.g. 'source: ""'. Both of
those are considered valid but result in an empty source.

A later change will ensure that the sources match up when
appending/redefining/overriding/enabling.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-24 08:45:12 +02:00
Federico Di Pierro
24f824dfb5 update(cmake): bump libs to latest master.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-22 14:59:04 +02:00
Federico Di Pierro
e4cbffc35b update(userpsace/engine): update engine checksum and version.
See https://github.com/falcosecurity/libs/pull/2047.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-21 16:01:59 +02:00
poiana
5749517c4e update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-21 16:01:59 +02:00
Mark Stemm
e99b11e793 Make enable()/disable() virtual so they can be overridden
Subclasses might want to also see when rules are enabled/disabled.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-16 12:01:37 +02:00
Federico Di Pierro
c19b637e36 fix(ci): fixed shasum computation for bump-libs CI.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-15 16:16:37 +02:00
Luca Guerra
fb01b6d927 cleanup(falco): deprecate -b --print-base64
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-10 17:37:18 +02:00
Luca Guerra
4501b64b9d new(falco): add buffer_format_base64
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-10 17:37:18 +02:00
dependabot[bot]
e04deeabe5 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `e38fb3f` to `407e997`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](e38fb3f6a7...407e99721f)

---
updated-dependencies:
- dependency-name: submodules/falcosecurity-rules
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-10 10:35:17 +02:00
Luca Guerra
dfa6b9b88e chore(falco): deprecated -A
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-10 10:26:16 +02:00
Luca Guerra
3b28450171 new(falco): add base_syscalls.all option to falco.yaml
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-10 10:26:16 +02:00
Federico Di Pierro
b242f90510 chore(ci): use redhat advised method to check rpmsign success.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-10 10:17:17 +02:00
Mark Stemm
80b7de6d90 Add a test for compile_output::clone() for derived type
Add a test for checking that compile_output::clone() returns equal
values, specifically in the case of derived values.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-10 09:20:17 +02:00
Mark Stemm
5f13a9be08 Add equality operators for indexed_vector/falco_{list,macro,rule}
Add an equality operator for indexed_vector.

As indexed_vectors commonly hold falco lists/macros/rules, also add
equality operators for those structs. For condition/sinsp_filter
shared_ptrs, the operator checks that the shared_ptrs point to the
same underlying memory.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-10 09:20:17 +02:00
Mark Stemm
093d9234a5 Add a compile_output::clone() method that can be overridden
Add a clone() method that can be overridden by subclasses. This allows
copying compile state when needed in a way that preserves
polymorphism.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2024-10-10 09:20:17 +02:00
Federico Di Pierro
c55adf38b4 chore(userspace/engine): fix build warning.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-09 16:26:14 +02:00
Federico Di Pierro
3e24606c11 new(ci): use zig compiler instead of relying on centos7.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-09 16:26:14 +02:00
Federico Di Pierro
93e5292f2f update(changelog): updated changelog for 0.39.1.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-09 10:54:14 +02:00
Luca Guerra
a754601cb6 update(tests): add tests for plugin init_config
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-08 12:06:08 +02:00
Luca Guerra
6721a6b9cf fix(engine): allow null init_config for plugin info
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-08 12:06:08 +02:00
Federico Di Pierro
7b2feb1f73 fix(ci): fixed bump-libs workflow syntax.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-07 17:49:04 +02:00
Luca Guerra
c7c0246ca8 fix(engine): disable comma separated vectors in cxxopts
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-07 13:24:04 +02:00
Federico Di Pierro
5141bddedd new(ci): add a workflow to automatically bump libs on each monday.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-07 11:35:03 +02:00
Luca Guerra
478514940f update(falco): deprecated -S --snaplen option
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-07 11:33:03 +02:00
Luca Guerra
ef79648037 new(falco): add falco_libs.snaplen option
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-10-07 11:33:03 +02:00
Federico Di Pierro
f72e6a59ad fix(userspace/falco): fix event set selection for plugin with parsing capability.
In live mode we need to use the source_info inspectors instead of the offline inspector.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-07 09:56:02 +02:00
dependabot[bot]
257938291d chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `b6ad373` to `e38fb3f`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](b6ad373719...e38fb3f6a7)

---
updated-dependencies:
- dependency-name: submodules/falcosecurity-rules
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-03 10:22:43 +02:00
Federico Di Pierro
41f20fd07a cleanup(userspac/falco): drop deprecated options.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-10-02 14:49:40 +02:00
Aldo Lacuku
6997c96306 update(changelog): add changelog for falco 0.39.0
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2024-10-01 12:00:35 +02:00
Luca Guerra
17e61450db cleanup(falco): reformat options::define
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-30 17:50:32 +02:00
Luca Guerra
683df327ac fix(falco): allow disable_cri_async from both CLI and config
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-30 15:33:32 +02:00
Luca Guerra
262aa9a003 cleanup(falco): ignore lint commit
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-30 13:59:32 +02:00
Poiana
50b98b30e5 chore(falco): apply code formatting
Signed-off-by: Poiana <poiana.bot@gmail.com>
2024-09-30 13:25:31 +02:00
Andrea Terzolo
11bac9dbd2 update: ignore_some_files
Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
2024-09-30 11:10:32 +02:00
Luca Guerra
c235f5b576 chore(build): update libs to 0.18.1 (master branch)
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-27 12:25:21 +02:00
Leonardo Di Giovanna
3a6d1c8c5d feat(stats): add host_netinfo networking information stats family
Introduce host_netinfo stats family to hold information regarding host
networking. At the moment, it only provides ipv4 and ipv6 addresses
list for each interface available on the host. The naming schema for
the introduced stats is
falco.host_netinfo.interfaces.<ifname>.protocols.<ipv4|ipv6>.addresses.

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2024-09-26 15:50:16 +02:00
Luca Guerra
70c10ee7e0 fix(engine): sync outputs before printing stats at shutdown
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-23 16:58:01 +02:00
Leonardo Di Giovanna
d3a67c10bd cleanup(falco_metrics): remove unused falco_utils import
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2024-09-23 15:38:01 +02:00
Leonardo Di Giovanna
5ba94a36bd fix(falco_metrics): remove ifinfo_json stat/metric
Using JSON as value prevents any meaningful aggregation for the stats.
Splitting these information into multiple labels can drastically
increase the number of dimensions, as the number of interfaces and
addresses can be high in some environment. Moreover, these information
are not currently refreshed, even if they can frequently change. Given
these reasons, remove ifinfo_json from stats and metrics.

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2024-09-23 15:38:01 +02:00
Leonardo Di Giovanna
00b35cfd81 fix(falco_metrics)!: use full name for configs and rules files
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2024-09-23 15:38:01 +02:00
Leonardo Di Giovanna
d77f768692 fix(falco_metrics)!: split tags label into multiple tag_ labels
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2024-09-23 15:38:01 +02:00
Luca Guerra
50f4bc172d update(tests): add test for plugin init_config map
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-20 09:55:49 +02:00
Luca Guerra
1a4a29348f fix(falco): allow plugin init_config map in json schema
Signed-off-by: Luca Guerra <luca@guerra.sh>
2024-09-20 09:55:49 +02:00
Federico Di Pierro
78f56190b4 fix(userspace/falco): properly account for plugin with CAP_PARSING when computing interesting sc set.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-09-19 17:40:48 +02:00
Leonardo Di Giovanna
d66c4ceb23 update(systemd): add falco.service alias to all systemd units
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2024-09-18 15:44:53 +02:00
Federico Di Pierro
ad13cb6014 update(cmake): bump libs to 0.18.0 and driver to 7.3.0+driver.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-09-18 10:28:52 +02:00
Federico Di Pierro
6f1a741c7e chore(userspace/falco): deprecate cri related CLI options.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-09-18 09:35:52 +02:00
Federico Di Pierro
fa701dd52f fix(userspace/engine): improve rule json schema to account for source and required_plugin_versions.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2024-09-17 17:34:51 +02:00
205 changed files with 9949 additions and 10183 deletions

View File

@@ -1 +1,3 @@
# Add here new files to ignore
# These files contain some JSON schema definitions that are not C++ code
userspace/falco/config_json_schema.h
userspace/engine/rule_json_schema.h

View File

@@ -1 +1,2 @@
# Add here new files to ignore
# This commit formatted the Falco code for the first time.
50b98b30e588eadce641136da85bc94a60eb6a3d

View File

@@ -10,12 +10,11 @@
| deb-aarch64 | [![deb](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/debFALCOBUCKET/stable/falco-FALCOVER-aarch64.deb) |
| tgz-aarch64 | [![tgz](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/binFALCOBUCKET/aarch64/falco-FALCOVER-aarch64.tar.gz) |
| Images |
| --------------------------------------------------------------------------- |
| `docker pull docker.io/falcosecurity/falco:FALCOVER` |
| `docker pull public.ecr.aws/falcosecurity/falco:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-driver-loader-legacy:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-no-driver:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-distroless:FALCOVER` |
| Images |
|---------------------------------------------------------------------------|
| `docker pull docker.io/falcosecurity/falco:FALCOVER` |
| `docker pull public.ecr.aws/falcosecurity/falco:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:FALCOVER-buster` |
| `docker pull docker.io/falcosecurity/falco:FALCOVER-debian` |

63
.github/workflows/bump-libs.yaml vendored Normal file
View File

@@ -0,0 +1,63 @@
---
name: Bump Libs
on:
workflow_dispatch:
schedule:
- cron: '30 6 * * 1' # on each monday 6:30
# Checks if any concurrent jobs is running for kernels CI and eventually cancel it.
concurrency:
group: bump-libs-ci
cancel-in-progress: true
jobs:
bump-libs:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- name: Download libs master tar.gz
run: |
wget https://github.com/falcosecurity/libs/archive/refs/heads/master.tar.gz
- name: Store libs hash and shasum
id: store
run: |
gunzip -c master.tar.gz > master.tar
commit=$(cat master.tar | git get-tar-commit-id)
echo "COMMIT=$commit" >> "$GITHUB_OUTPUT"
wget https://github.com/falcosecurity/libs/archive/$commit.tar.gz
echo "SHASUM=$(sha256sum $commit.tar.gz | awk '{print $1}')" >> "$GITHUB_OUTPUT"
- name: Checkout
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
with:
path: falco
- name: Bump libs version and hash
run: |
cd falco
sed -i -E '45s/FALCOSECURITY_LIBS_VERSION "(.+)"/FALCOSECURITY_LIBS_VERSION "${{ steps.store.outputs.COMMIT }}"/' cmake/modules/falcosecurity-libs.cmake
sed -i -E '47s/"SHA256=(.+)"/"SHA256=${{ steps.store.outputs.SHASUM }}"/' cmake/modules/falcosecurity-libs.cmake
sed -i -E '38s/DRIVER_VERSION "(.+)"/DRIVER_VERSION "${{ steps.store.outputs.COMMIT }}"/' cmake/modules/driver.cmake
sed -i -E '40s/"SHA256=(.+)"/"SHA256=${{ steps.store.outputs.SHASUM }}"/' cmake/modules/driver.cmake
- name: Create Pull Request
uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7.0.5
with:
path: falco
signoff: true
base: master
branch: update/libs
title: 'update(cmake): update libs and driver to latest master'
body: |
This PR updates libs and driver to latest commit.
/kind release
/area build
```release-note
NONE
```
commit-message: 'update(cmake): update libs and driver to latest master.'
token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -19,22 +19,14 @@ jobs:
fetch-version:
uses: ./.github/workflows/reusable_fetch_version.yaml
build-dev-packages-sanitizers-x86_64:
needs: [fetch-version]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: x86_64
version: ${{ needs.fetch-version.outputs.version }}
build_type: Debug
sanitizers: true
build-dev-packages-x86_64:
needs: [fetch-version]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: x86_64
version: ${{ needs.fetch-version.outputs.version }}
build_type: Release
enable_debug: true
enable_sanitizers: true
build-dev-packages-arm64:
needs: [fetch-version]
@@ -42,22 +34,19 @@ jobs:
with:
arch: aarch64
version: ${{ needs.fetch-version.outputs.version }}
build_type: Debug
sanitizers: false
enable_debug: true
test-dev-packages:
needs: [fetch-version, build-dev-packages-sanitizers-x86_64]
needs: [fetch-version, build-dev-packages-x86_64]
uses: ./.github/workflows/reusable_test_packages.yaml
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
sanitizers: true
# static: ${{ matrix.static != '' && true || false }}
sanitizers: ${{ matrix.static == '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
test-dev-packages-arm64:

View File

@@ -32,7 +32,7 @@ jobs:
- name: Upload the git diff artifact 📦
if: failure()
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: format_diff.patch
path: ./format_diff.patch

View File

@@ -31,15 +31,13 @@ jobs:
test-dev-packages:
needs: [fetch-version, build-dev-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
# static: ${{ matrix.static != '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
test-dev-packages-arm64:

View File

@@ -6,13 +6,13 @@ on:
# Checks if any concurrent jobs is running for release CI and eventually cancel it.
concurrency:
group: ci-release
cancel-in-progress: true
cancel-in-progress: true
jobs:
release-settings:
runs-on: ubuntu-latest
outputs:
is_latest: ${{ steps.get_settings.outputs.is_latest }}
is_latest: ${{ steps.get_settings.outputs.is_latest }}
bucket_suffix: ${{ steps.get_settings.outputs.bucket_suffix }}
steps:
- name: Get latest release
@@ -69,25 +69,22 @@ jobs:
test-packages:
needs: [release-settings, build-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
# static: ${{ matrix.static != '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ github.event.release.tag_name }}
test-packages-arm64:
needs: [release-settings, build-packages-arm64]
uses: ./.github/workflows/reusable_test_packages.yaml
with:
arch: aarch64
version: ${{ github.event.release.tag_name }}
publish-packages:
needs: [release-settings, test-packages, test-packages-arm64]
uses: ./.github/workflows/reusable_publish_packages.yaml
@@ -95,7 +92,7 @@ jobs:
bucket_suffix: ${{ needs.release-settings.outputs.bucket_suffix }}
version: ${{ github.event.release.tag_name }}
secrets: inherit
# Both build-docker and its arm64 counterpart require build-packages because they use its output
build-docker:
needs: [release-settings, build-packages, publish-packages]
@@ -106,7 +103,7 @@ jobs:
version: ${{ github.event.release.tag_name }}
tag: ${{ github.event.release.tag_name }}
secrets: inherit
build-docker-arm64:
needs: [release-settings, build-packages, publish-packages]
uses: ./.github/workflows/reusable_build_docker.yaml
@@ -125,7 +122,7 @@ jobs:
is_latest: ${{ needs.release-settings.outputs.is_latest == 'true' }}
tag: ${{ github.event.release.tag_name }}
sign: true
release-body:
needs: [release-settings, publish-docker]
if: ${{ needs.release-settings.outputs.is_latest == 'true' }} # only for latest releases
@@ -135,7 +132,7 @@ jobs:
steps:
- name: Clone repo
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Extract LIBS and DRIVER versions
run: |
cp .github/release_template.md release-body.md
@@ -143,29 +140,48 @@ jobs:
DRIVER_VERS=$(cat cmake/modules/driver.cmake | grep 'set(DRIVER_VERSION' | tail -n1 | grep -o '[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*+driver')
sed -i s/LIBSVER/$LIBS_VERS/g release-body.md
sed -i s/DRIVERVER/$DRIVER_VERS/g release-body.md
- name: Append release matrixes
run: |
sed -i s/FALCOBUCKET/${{ needs.release-settings.outputs.bucket_suffix }}/g release-body.md
sed -i s/FALCOVER/${{ github.event.release.tag_name }}/g release-body.md
- name: Generate release notes
uses: leodido/rn2md@9c351d81278644c0e17b1ca68edbdba305276c73
with:
milestone: ${{ github.event.release.tag_name }}
output: ./notes.md
- name: Merge release notes to pre existent body
run: cat notes.md >> release-body.md
- name: Attach release creator to release body
run: |
echo "" >> release-body.md
echo "#### Release Manager @${{ github.event.release.author.login }}" >> release-body.md
- name: Download debug symbols for Falco x86_64
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ github.event.release.tag_name }}-x86_64.debug
- name: Rename x86_64 debug symbols
run: mv falco.debug falco-x86_64.debug
- name: Download debug symbols for Falco aarch64
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ github.event.release.tag_name }}-aarch64.debug
- name: Rename aarch64 debug symbols
run: mv falco.debug falco-aarch64.debug
- name: Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
with:
body_path: ./release-body.md
tag_name: ${{ github.event.release.tag_name }}
name: ${{ github.event.release.name }}
files: |
falco-x86_64.debug
falco-aarch64.debug

View File

@@ -39,7 +39,7 @@ permissions:
jobs:
build-and-test:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-22.04' }}
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
outputs:
cmdout: ${{ steps.run_cmd.outputs.out }}
steps:

View File

@@ -20,57 +20,47 @@ on:
required: true
type: string
# Here we just build all docker images as tarballs,
# Here we just build all docker images as tarballs,
# then we upload all the tarballs to be later downloaded by reusable_publish_docker workflow.
# In this way, we don't need to publish any arch specific image,
# In this way, we don't need to publish any arch specific image,
# and this "build" workflow is actually only building images.
permissions:
permissions:
contents: read
jobs:
build-docker:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
env:
TARGETARCH: ${{ (inputs.arch == 'aarch64' && 'arm64') || 'amd64' }}
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
- name: Build no-driver image
run: |
cd ${{ github.workspace }}/docker/no-driver/
docker build -t docker.io/falcosecurity/falco-no-driver:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg VERSION_BUCKET=bin${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-no-driver:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-no-driver-${{ inputs.arch }}.tar
- name: Build distroless image
run: |
cd ${{ github.workspace }}/docker/no-driver/
docker build -f Dockerfile.distroless -t docker.io/falcosecurity/falco-distroless:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg VERSION_BUCKET=bin${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-distroless:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-distroless-${{ inputs.arch }}.tar
- name: Build falco image
run: |
cd ${{ github.workspace }}/docker/falco/
docker build -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg VERSION_BUCKET=bin${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-${{ inputs.arch }}.tar
- name: Build falco-debian image
run: |
cd ${{ github.workspace }}/docker/falco-debian/
docker build -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}-debian \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}-debian --output /tmp/falco-${{ inputs.arch }}-debian.tar
- name: Build falco-driver-loader image
run: |
cd ${{ github.workspace }}/docker/driver-loader/
@@ -80,19 +70,19 @@ jobs:
.
docker save docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-driver-loader-${{ inputs.arch }}.tar
- name: Build falco-driver-loader-legacy image
- name: Build falco-driver-loader-buster image
run: |
cd ${{ github.workspace }}/docker/driver-loader-legacy/
docker build -t docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.arch }}-${{ inputs.tag }} \
cd ${{ github.workspace }}/docker/driver-loader-buster/
docker build -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}-buster \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-driver-loader-legacy-${{ inputs.arch }}.tar
docker save docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}-buster --output /tmp/falco-driver-loader-${{ inputs.arch }}-buster.tar
- name: Upload images tarballs
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-images
name: falco-images-${{ inputs.arch }}
path: /tmp/falco-*.tar
retention-days: 1

View File

@@ -10,13 +10,13 @@ on:
description: The Falco version to use when building packages
required: true
type: string
build_type:
description: The build type
enable_debug:
description: Also create a debug build
required: false
type: string
default: 'Release'
sanitizers:
description: enable sanitizer support
type: boolean
default: false
enable_sanitizers:
description: Also create a sanitizer build
required: false
type: boolean
default: false
@@ -27,13 +27,13 @@ permissions:
jobs:
build-modern-bpf-skeleton:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
container: fedora:latest
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build dependencies
run: |
dnf install -y bpftool ca-certificates cmake make automake gcc gcc-c++ kernel-devel clang git pkg-config autoconf automake libbpf-devel elfutils-libelf-devel
dnf install -y bpftool ca-certificates cmake make automake gcc gcc-c++ kernel-devel clang git pkg-config autoconf automake
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
@@ -45,120 +45,197 @@ jobs:
cmake --build skeleton-build --target ProbeSkeleton -j6
- name: Upload skeleton
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: skeleton-build/skel_dir/bpf_probe.skel.h
retention-days: 1
build-packages:
env:
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
build-packages-release:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
needs: [build-modern-bpf-skeleton]
container: centos:7
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Fix mirrors to use vault.centos.org
run: |
sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
sed -i s/^#.*baseurl=http/baseurl=https/g /etc/yum.repos.d/*.repo
sed -i s/^mirrorlist=http/#mirrorlist=https/g /etc/yum.repos.d/*.repo
- name: Install scl repos
run: |
yum -y install centos-release-scl
- name: Fix new mirrors to use vault.centos.org
run: |
sed -i s/mirror.centos.org/vault.centos.org/g /etc/yum.repos.d/*.repo
sed -i s/^#.*baseurl=http/baseurl=https/g /etc/yum.repos.d/*.repo
sed -i s/^mirrorlist=http/#mirrorlist=https/g /etc/yum.repos.d/*.repo
- name: Fix arm64 scl repos to use correct mirror
if: inputs.arch == 'aarch64'
run: |
sed -i 's/vault.centos.org\/centos/vault.centos.org\/altarch/g' /etc/yum.repos.d/CentOS-SCLo-scl*.repo
- name: Install build deps
run: |
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++
source /opt/rh/devtoolset-9/enable
yum install -y wget git make m4 rpm-build elfutils-libelf-devel perl-IPC-Cmd devtoolset-9-libasan-devel devtoolset-9-libubsan-devel
sudo apt update && sudo apt install -y --no-install-recommends ca-certificates cmake curl wget build-essential git pkg-config autoconf automake libtool m4 rpm
- name: Checkout
# It is not possible to upgrade the checkout action to versions >= v4.0.0 because of incompatibilities with centos 7's libc.
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Download skeleton
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: /tmp
- name: Install updated cmake
run: |
curl -L https://github.com/Kitware/CMake/releases/download/v3.22.5/cmake-3.22.5-linux-$(uname -m).tar.gz \
| tar --directory=/usr --strip-components=1 -xzp
- name: Install zig
if: inputs.sanitizers == false
uses: falcosecurity/libs/.github/actions/install-zig@master
- name: Prepare project
run: |
source /opt/rh/devtoolset-9/enable
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DUSE_BUNDLED_DEPS=On \
-DFALCO_ETC_DIR=/etc/falco \
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_ASAN=${{ (inputs.sanitizers == true && inputs.arch == 'x86_64' && 'ON') || 'OFF' }} \
-DUSE_JEMALLOC=ON \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
run: |
source /opt/rh/devtoolset-9/enable
cmake --build build --target falco -j6
- name: Build packages
run: |
source /opt/rh/devtoolset-9/enable
cmake --build build --target package
- name: Upload Falco tar.gz package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}${{ inputs.sanitizers == true && '-sanitizers' || '' }}.tar.gz
name: falco-${{ inputs.version }}-${{ inputs.arch }}.tar.gz
path: |
${{ github.workspace }}/build/falco-*.tar.gz
- name: Upload Falco deb package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}${{ inputs.sanitizers == true && '-sanitizers' || '' }}.deb
name: falco-${{ inputs.version }}-${{ inputs.arch }}.deb
path: |
${{ github.workspace }}/build/falco-*.deb
- name: Upload Falco rpm package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}${{ inputs.sanitizers == true && '-sanitizers' || '' }}.rpm
name: falco-${{ inputs.version }}-${{ inputs.arch }}.rpm
path: |
${{ github.workspace }}/build/falco-*.rpm
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
- name: Upload Falco debug symbols
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.debug
path: |
${{ github.workspace }}/build/userspace/falco/falco.debug
build-packages-debug:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-22.04' }}
if: ${{ inputs.enable_debug == true }}
needs: [build-modern-bpf-skeleton]
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build deps
run: |
sudo apt update && sudo apt install -y --no-install-recommends ca-certificates cmake curl wget build-essential git pkg-config autoconf automake libtool m4 rpm
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Download skeleton
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: /tmp
- name: Install zig
if: inputs.sanitizers == false
uses: falcosecurity/libs/.github/actions/install-zig@master
- name: Prepare project
run: |
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=Debug \
-DUSE_BUNDLED_DEPS=On \
-DFALCO_ETC_DIR=/etc/falco \
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=On \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
run: |
cmake --build build --target falco -j6
- name: Build packages
run: |
cmake --build build --target package
- name: Upload Falco tar.gz package
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}-debug.tar.gz
path: |
${{ github.workspace }}/build/falco-*.tar.gz
build-packages-sanitizers:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
if: ${{ inputs.enable_sanitizers == true }}
needs: [build-modern-bpf-skeleton]
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build deps
run: |
sudo apt update && sudo apt install -y --no-install-recommends ca-certificates cmake curl wget build-essential git pkg-config autoconf automake libtool m4 rpm
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Download skeleton
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: /tmp
- name: Prepare project
# Jemalloc and ASAN don't play very well together.
run: |
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=Debug \
-DUSE_BUNDLED_DEPS=On \
-DFALCO_ETC_DIR=/etc/falco \
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=Off \
-DUSE_ASAN=On \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
run: |
cmake --build build --target falco -j6
- name: Build packages
run: |
cmake --build build --target package
- name: Upload Falco tar.gz package
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}-sanitizers.tar.gz
path: |
${{ github.workspace }}/build/falco-*.tar.gz
build-musl-package:
# x86_64 only for now
# if: ${{ inputs.arch == 'x86_64' }}
if: false
if: ${{ inputs.arch == 'x86_64' }}
runs-on: ubuntu-latest
container: alpine:3.17
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build dependencies
run: |
apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils bpftool clang
apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils clang llvm
git clone https://github.com/libbpf/bpftool.git --branch v7.3.0 --single-branch
cd bpftool
git submodule update --init
cd src && make install
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
@@ -168,10 +245,14 @@ jobs:
- name: Prepare project
run: |
cmake -B build -S . \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DCMAKE_BUILD_TYPE=Release \
-DCPACK_GENERATOR=TGZ \
-DBUILD_BPF=Off -DBUILD_DRIVER=Off \
-DUSE_BUNDLED_DEPS=On -DUSE_BUNDLED_LIBELF=Off -DBUILD_LIBSCAP_MODERN_BPF=ON -DMUSL_OPTIMIZED_BUILD=On -DFALCO_ETC_DIR=/etc/falco -DFALCO_VERSION=${{ inputs.version }}
-DUSE_JEMALLOC=On \
-DUSE_BUNDLED_DEPS=On \
-DMUSL_OPTIMIZED_BUILD=On \
-DFALCO_ETC_DIR=/etc/falco \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
run: |
@@ -187,7 +268,7 @@ jobs:
mv falco-${{ inputs.version }}-x86_64.tar.gz falco-${{ inputs.version }}-static-x86_64.tar.gz
- name: Upload Falco static package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
path: |
@@ -195,7 +276,7 @@ jobs:
build-wasm-package:
if: ${{ inputs.arch == 'x86_64' }}
runs-on: ubuntu-latest
runs-on: ubuntu-22.04
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build dependencies
@@ -216,10 +297,7 @@ jobs:
- name: Prepare project
run: |
emcmake cmake -B build -S . \
-DBUILD_BPF=Off \
-DBUILD_DRIVER=Off \
-DBUILD_FALCO_MODERN_BPF=Off \
-DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_BUNDLED_DEPS=On \
-DFALCO_ETC_DIR=/etc/falco \
-DBUILD_FALCO_UNIT_TESTS=On \
@@ -241,7 +319,7 @@ jobs:
emmake make -j6 package
- name: Upload Falco WASM package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-wasm.tar.gz
path: |
@@ -259,28 +337,28 @@ jobs:
# NOTE: Backslash doesn't work as line continuation on Windows.
- name: Prepare project
run: |
cmake -B build -S . -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DMINIMAL_BUILD=On -DUSE_BUNDLED_DEPS=On -DBUILD_FALCO_UNIT_TESTS=On -DFALCO_VERSION=${{ inputs.version }}
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release -DMINIMAL_BUILD=On -DUSE_BUNDLED_DEPS=On -DBUILD_FALCO_UNIT_TESTS=On -DFALCO_VERSION=${{ inputs.version }}
- name: Build project
run: |
cmake --build build --target package --config ${{ inputs.build_type }}
cmake --build build --target package --config Release
- name: Run unit Tests
run: |
build/unit_tests/${{ inputs.build_type }}/falco_unit_tests.exe
build/unit_tests/Release/falco_unit_tests.exe
- name: Upload Falco win32 installer
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-installer-${{ inputs.version }}-win32.exe
name: falco-installer-Release-win32.exe
path: build/falco-*.exe
- name: Upload Falco win32 package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-win32.exe
name: falco-Release-win32.exe
path: |
${{ github.workspace }}/build/userspace/falco/${{ inputs.build_type }}/falco.exe
${{ github.workspace }}/build/userspace/falco/Release/falco.exe
build-macos-package:
if: ${{ inputs.arch == 'x86_64' }}
@@ -305,7 +383,7 @@ jobs:
sudo build/unit_tests/falco_unit_tests
- name: Upload Falco macos package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: falco-${{ inputs.version }}-macos
path: |

View File

@@ -18,44 +18,55 @@ on:
default: false
permissions:
id-token: write
contents: read
jobs:
publish-docker:
runs-on: ubuntu-latest
permissions:
attestations: write
id-token: write
contents: read
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
- name: Download images tarballs
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
- name: Download x86_64 images tarballs
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-images
name: falco-images-x86_64
path: /tmp/falco-images
- name: Download aarch64 images tarballs
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-images-aarch64
path: /tmp/falco-images
- name: Load all images
run: |
for img in /tmp/falco-images/falco-*.tar; do docker load --input $img; done
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
with:
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco-ecr"
aws-region: us-east-1 # The region must be set to us-east-1 in order to access ECR Public.
- name: Login to Amazon ECR
id: login-ecr-public
uses: aws-actions/amazon-ecr-login@2f9f10ea3fa2eed41ac443fee8bfbd059af2d0a4 # v1.6.0
with:
registry-type: public
registry-type: public
- name: Setup Crane
uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.3
with:
@@ -64,42 +75,29 @@ jobs:
# We're pushing the arch-specific manifests to Docker Hub so that we'll be able to easily create the index/multiarch later
- name: Push arch-specific images to Docker Hub
run: |
docker push docker.io/falcosecurity/falco-no-driver:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-no-driver:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-distroless:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-distroless:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }}-debian
docker push docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}-debian
docker push docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader-legacy:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader-legacy:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }}-buster
docker push docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}-buster
- name: Create no-driver manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-no-driver:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-no-driver:x86_64-${{ inputs.tag }}
push: true
- name: Create distroless manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco-distroless:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-distroless:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-distroless:x86_64-${{ inputs.tag }}
push: true
- name: Tag slim manifest on Docker Hub
run: |
crane copy docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} docker.io/falcosecurity/falco:${{ inputs.tag }}-slim
- name: Create falco manifest on Docker Hub
- name: Create Falco manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco:${{ inputs.tag }}
images: docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
push: true
- name: Create falco-debian manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco:${{ inputs.tag }}-debian
images: docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }}-debian,docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}-debian
push: true
- name: Create falco-driver-loader manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
@@ -107,48 +105,41 @@ jobs:
images: docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
push: true
- name: Create falco-driver-loader-legacy manifest on Docker Hub
- name: Create falco-driver-loader-buster manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-driver-loader-legacy:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-driver-loader-legacy:x86_64-${{ inputs.tag }}
inputs: docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}-buster
images: docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }}-buster,docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}-buster
push: true
- name: Get Digests for images
id: digests
# We could probably use the docker-manifest-action output instead of recomputing those with crane
run: |
echo "falco-no-driver=$(crane digest docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-distroless=$(crane digest docker.io/falcosecurity/falco-distroless:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco=$(crane digest docker.io/falcosecurity/falco:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-debian=$(crane digest docker.io/falcosecurity/falco:${{ inputs.tag }}-debian)" >> $GITHUB_OUTPUT
echo "falco-driver-loader=$(crane digest docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-driver-loader-legacy=$(crane digest docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-driver-loader-buster=$(crane digest docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}-buster)" >> $GITHUB_OUTPUT
- name: Publish images to ECR
run: |
crane copy docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco-distroless:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-distroless:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco:${{ inputs.tag }}-debian public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-debian
crane copy docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }}
crane copy public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim
crane copy docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}-buster public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }}-buster
- name: Tag latest on Docker Hub and ECR
if: inputs.is_latest
run: |
crane tag docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco-distroless:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }}-debian latest-debian
crane tag docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
crane tag docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}-buster latest-buster
crane tag public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco-distroless:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-debian latest-debian
crane tag public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
crane tag public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }}-buster latest-buster
- name: Setup Cosign
if: inputs.sign
@@ -160,14 +151,24 @@ jobs:
COSIGN_EXPERIMENTAL: "true"
COSIGN_YES: "true"
run: |
cosign sign docker.io/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
cosign sign docker.io/falcosecurity/falco-distroless@${{ steps.digests.outputs.falco-distroless }}
cosign sign docker.io/falcosecurity/falco@${{ steps.digests.outputs.falco }}
cosign sign docker.io/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign docker.io/falcosecurity/falco-driver-loader-legacy@${{ steps.digests.outputs.falco-driver-loader-legacy }}
cosign sign docker.io/falcosecurity/falco:latest@${{ steps.digests.outputs.falco }}
cosign sign docker.io/falcosecurity/falco:latest-debian@${{ steps.digests.outputs.falco-debian }}
cosign sign docker.io/falcosecurity/falco-driver-loader:latest@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign docker.io/falcosecurity/falco-driver-loader:latest-buster@${{ steps.digests.outputs.falco-driver-loader-buster }}
cosign sign public.ecr.aws/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
cosign sign public.ecr.aws/falcosecurity/falco-distroless@${{ steps.digests.outputs.falco-distroless }}
cosign sign public.ecr.aws/falcosecurity/falco@${{ steps.digests.outputs.falco }}
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader-legacy@${{ steps.digests.outputs.falco-driver-loader-legacy }}
cosign sign public.ecr.aws/falcosecurity/falco:latest@${{ steps.digests.outputs.falco }}
cosign sign public.ecr.aws/falcosecurity/falco:latest-debian@${{ steps.digests.outputs.falco-debian }}
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader:latest@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader:latest-buster@${{ steps.digests.outputs.falco-driver-loader-buster }}
- uses: actions/attest-build-provenance@173725a1209d09b31f9d30a3890cf2757ebbff0d # v1.1.2
with:
subject-name: docker.io/falcosecurity/falco
subject-digest: ${{ steps.digests.outputs.falco }}
push-to-registry: true
- uses: actions/attest-build-provenance@173725a1209d09b31f9d30a3890cf2757ebbff0d # v1.1.2
with:
subject-name: docker.io/falcosecurity/falco-driver-loader
subject-digest: ${{ steps.digests.outputs.falco-driver-loader }}
push-to-registry: true

View File

@@ -42,40 +42,37 @@ jobs:
aws-region: ${{ env.AWS_S3_REGION }}
- name: Download RPM x86_64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-x86_64.rpm
path: /tmp/falco-build-rpm
- name: Download RPM aarch64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-aarch64.rpm
path: /tmp/falco-build-rpm
- name: Download binary x86_64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-x86_64.tar.gz
path: /tmp/falco-build-bin
- name: Download binary aarch64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-aarch64.tar.gz
path: /tmp/falco-build-bin
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
- name: Download static binary x86_64
if: false
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
path: /tmp/falco-build-bin-static
- name: Download WASM package
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-wasm.tar.gz
path: /tmp/falco-wasm
@@ -88,7 +85,7 @@ jobs:
- name: Sign rpms
run: |
rpmsign --define '_gpg_name Falcosecurity Package Signing' --addsign /tmp/falco-build-rpm/falco-*.rpm
rpm --qf %{SIGPGP:pgpsig} -qp /tmp/falco-build-rpm/falco-*.rpm | grep SHA256
rpm -qp --qf '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{(none)}|}|\n' /tmp/falco-build-rpm/falco-*.rpm
- name: Publish wasm
run: |
@@ -102,11 +99,8 @@ jobs:
run: |
./scripts/publish-bin -f /tmp/falco-build-bin/falco-${{ inputs.version }}-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
./scripts/publish-bin -f /tmp/falco-build-bin/falco-${{ inputs.version }}-aarch64.tar.gz -r bin${{ inputs.bucket_suffix }} -a aarch64
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
- name: Publish static
if: false
run: |
./scripts/publish-bin -f /tmp/falco-build-bin-static/falco-${{ inputs.version }}-static-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
@@ -131,13 +125,13 @@ jobs:
aws-region: ${{ env.AWS_S3_REGION }}
- name: Download deb x86_64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-x86_64.deb
path: /tmp/falco-build-deb
- name: Download deb aarch64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}-aarch64.deb
path: /tmp/falco-build-deb

View File

@@ -27,10 +27,10 @@ permissions:
jobs:
test-packages:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
steps:
- name: Download binary
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
with:
name: falco-${{ inputs.version }}${{ inputs.static && '-static' || '' }}-${{ inputs.arch }}${{ inputs.sanitizers == true && '-sanitizers' || '' }}.tar.gz
@@ -43,7 +43,6 @@ jobs:
# We only run driver loader tests on x86_64
- name: Install kernel headers for falco-driver-loader tests
if: ${{ inputs.arch == 'x86_64' }}
run: |
sudo apt update -y
sudo apt install -y --no-install-recommends linux-headers-$(uname -r)
@@ -64,5 +63,6 @@ jobs:
test-k8saudit: 'true'
test-dummy: 'true'
static: ${{ inputs.static && 'true' || 'false' }}
test-drivers: ${{ inputs.arch == 'x86_64' && 'true' || 'false' }}
test-drivers: 'true'
show-all: 'true'
report-name-suffix: ${{ inputs.static && '-static' || '' }}${{ inputs.sanitizers && '-sanitizers' || '' }}

View File

@@ -65,7 +65,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: SARIF file
path: results.sarif

View File

@@ -29,7 +29,7 @@ jobs:
cmake --build build -j4 --target cppcheck_htmlreport
- name: Upload reports ⬆️
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: static-analysis-reports
path: ./build/static-analysis-reports

View File

@@ -1,5 +1,136 @@
# Change Log
## v0.39.2
Released on 2024-11-21
### Minor Changes
* update(cmake): bumped falcoctl to v0.10.1. [[#3408](https://github.com/falcosecurity/falco/pull/3408)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): bump yaml-cpp to latest master. [[#3394](https://github.com/falcosecurity/falco/pull/3394)] - [@FedeDP](https://github.com/FedeDP)
### Non user-facing changes
* update(ci): use arm64 CNCF runners for GH actions [[#3386](https://github.com/falcosecurity/falco/pull/3386)] - [@LucaGuerra](https://github.com/LucaGuerra)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 1 |
| Release note | 2 |
| Total | 3 |
## v0.39.1
Released on 2024-10-09
### Bug Fixes
* fix(engine): allow null init_config for plugin info [[#3372](https://github.com/falcosecurity/falco/pull/3372)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(engine): fix parsing issues in -o key={object} when the object definition contains a comma [[#3363](https://github.com/falcosecurity/falco/pull/3363)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(userspace/falco): fix event set selection for plugin with parsing capability [[#3368](https://github.com/falcosecurity/falco/pull/3368)] - [@FedeDP](https://github.com/FedeDP)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 0 |
| Release note | 3 |
| Total | 3 |
## v0.39.0
Released on 2024-10-01
### Breaking Changes :warning:
* fix(falco_metrics)!: split tags label into multiple `tag_`-prefixed labels [[#3337](https://github.com/falcosecurity/falco/pull/3337)] - [@ekoops](https://github.com/ekoops)
* fix(falco_metrics)!: use full name for configs and rules files [[#3337](https://github.com/falcosecurity/falco/pull/3337)] - [@ekoops](https://github.com/ekoops)
* update(falco_metrics)!: rearrange `n_evts_cpu` and `n_drops_cpu` Prometheus metrics to follow best practices [[#3319](https://github.com/falcosecurity/falco/pull/3319)] - [@incertum](https://github.com/incertum)
* cleanup(userspace/falco)!: drop deprecated -t,-T,-D options. [[#3311](https://github.com/falcosecurity/falco/pull/3311)] - [@FedeDP](https://github.com/FedeDP)
### Major Changes
* feat(stats): add host_netinfo networking information stats family [[#3344](https://github.com/falcosecurity/falco/pull/3344)] - [@ekoops](https://github.com/ekoops)
* new(falco): add json_include_message_property to have a message field without date and priority [[#3314](https://github.com/falcosecurity/falco/pull/3314)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(userspace/falco,userspace/engine): rule json schema validation [[#3313](https://github.com/falcosecurity/falco/pull/3313)] - [@FedeDP](https://github.com/FedeDP)
* new(falco): introduce append_output configuration [[#3308](https://github.com/falcosecurity/falco/pull/3308)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(userspace/falco): added --config-schema action to print config schema [[#3312](https://github.com/falcosecurity/falco/pull/3312)] - [@FedeDP](https://github.com/FedeDP)
* new(falco): enable CLI options with -o key={object} [[#3310](https://github.com/falcosecurity/falco/pull/3310)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(config): add `container_engines` config to falco.yaml [[#3266](https://github.com/falcosecurity/falco/pull/3266)] - [@incertum](https://github.com/incertum)
* new(metrics): add host_ifinfo metric [[#3253](https://github.com/falcosecurity/falco/pull/3253)] - [@incertum](https://github.com/incertum)
* new(userspace,unit_tests): validate configs against schema [[#3302](https://github.com/falcosecurity/falco/pull/3302)] - [@FedeDP](https://github.com/FedeDP)
### Minor Changes
* update(falco): upgrade libs to 0.18.1 [[#3349](https://github.com/falcosecurity/falco/pull/3349)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(systemd): users can refer to systemd falco services with a consistent unique alias falco.service [[#3332](https://github.com/falcosecurity/falco/pull/3332)] - [@ekoops](https://github.com/ekoops)
* update(cmake): bump libs to 0.18.0 and driver to 7.3.0+driver. [[#3330](https://github.com/falcosecurity/falco/pull/3330)] - [@FedeDP](https://github.com/FedeDP)
* chore(userspace/falco): deprecate `cri` related CLI options. [[#3329](https://github.com/falcosecurity/falco/pull/3329)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): bumped falcoctl to v0.10.0 and rules to 3.2.0 [[#3327](https://github.com/falcosecurity/falco/pull/3327)] - [@FedeDP](https://github.com/FedeDP)
* update(falco_metrics): change prometheus rules metric naming [[#3324](https://github.com/falcosecurity/falco/pull/3324)] - [@incertum](https://github.com/incertum)
### Bug Fixes
* fix(falco): allow disable_cri_async from both CLI and config [[#3353](https://github.com/falcosecurity/falco/pull/3353)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(engine): sync outputs before printing stats at shutdown [[#3338](https://github.com/falcosecurity/falco/pull/3338)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(falco): allow plugin init_config map in json schema [[#3335](https://github.com/falcosecurity/falco/pull/3335)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(userspace/falco): properly account for plugin with CAP_PARSING when computing interesting sc set [[#3334](https://github.com/falcosecurity/falco/pull/3334)] - [@FedeDP](https://github.com/FedeDP)
### Non user-facing changes
* feat(cmake): add conditional builds for falcoctl and rules paths [[#3305](https://github.com/falcosecurity/falco/pull/3305)] - [@tembleking](https://github.com/tembleking)
* cleanup(falco): ignore lint commit [[#3354](https://github.com/falcosecurity/falco/pull/3354)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore(falco): apply code formatting [[#3350](https://github.com/falcosecurity/falco/pull/3350)] - [@poiana](https://github.com/poiana)
* chore: ignore_some_files for clang format [[#3351](https://github.com/falcosecurity/falco/pull/3351)] - [@Andreagit97](https://github.com/Andreagit97)
* sync: release 0.39.x [[#3340](https://github.com/falcosecurity/falco/pull/3340)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/engine): improve rule json schema to account for `source` and `required_plugin_versions` [[#3328](https://github.com/falcosecurity/falco/pull/3328)] - [@FedeDP](https://github.com/FedeDP)
* cleanup(falco): use header file for json schema [[#3325](https://github.com/falcosecurity/falco/pull/3325)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(engine): modify append_output format [[#3322](https://github.com/falcosecurity/falco/pull/3322)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore: scaffolding for enabling code formatting [[#3321](https://github.com/falcosecurity/falco/pull/3321)] - [@Andreagit97](https://github.com/Andreagit97)
* update(cmake): bump libs and driver to 0.18.0-rc1. [[#3320](https://github.com/falcosecurity/falco/pull/3320)] - [@FedeDP](https://github.com/FedeDP)
* fix(ci): restore master and release CI workflow permissions. [[#3317](https://github.com/falcosecurity/falco/pull/3317)] - [@FedeDP](https://github.com/FedeDP)
* fixed the token-permission and pinned-dependencies issue [[#3299](https://github.com/falcosecurity/falco/pull/3299)] - [@harshitasao](https://github.com/harshitasao)
* update(cmake): bump falcoctl to v0.10.0-rc1 [[#3316](https://github.com/falcosecurity/falco/pull/3316)] - [@alacuku](https://github.com/alacuku)
* ci(insecure-api): update semgrep docker image [[#3315](https://github.com/falcosecurity/falco/pull/3315)] - [@francesco-furlan](https://github.com/francesco-furlan)
* Add demo environment instructions and docker-config files [[#3295](https://github.com/falcosecurity/falco/pull/3295)] - [@bbl232](https://github.com/bbl232)
* chore(deps): Bump submodules/falcosecurity-rules from `baecf18` to `b6ad373` [[#3301](https://github.com/falcosecurity/falco/pull/3301)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake): bump libs and driver to latest master [[#3283](https://github.com/falcosecurity/falco/pull/3283)] - [@jasondellaluce](https://github.com/jasondellaluce)
* chore(deps): Bump submodules/falcosecurity-rules from `342b20d` to `baecf18` [[#3298](https://github.com/falcosecurity/falco/pull/3298)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): Bump submodules/falcosecurity-rules from `068f0f2` to `342b20d` [[#3288](https://github.com/falcosecurity/falco/pull/3288)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* vote: add sgaist to OWNERS [[#3264](https://github.com/falcosecurity/falco/pull/3264)] - [@sgaist](https://github.com/sgaist)
* Add Tulip Retail to adopters list [[#3291](https://github.com/falcosecurity/falco/pull/3291)] - [@bbl232](https://github.com/bbl232)
* chore(deps): Bump submodules/falcosecurity-rules from `28b98b6` to `068f0f2` [[#3282](https://github.com/falcosecurity/falco/pull/3282)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): Bump submodules/falcosecurity-rules from `c0a9bf1` to `28b98b6` [[#3267](https://github.com/falcosecurity/falco/pull/3267)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* Added the OpenSSF Scorecard Badge [[#3250](https://github.com/falcosecurity/falco/pull/3250)] - [@harshitasao](https://github.com/harshitasao)
* chore(deps): Bump submodules/falcosecurity-rules from `ea57e78` to `c0a9bf1` [[#3247](https://github.com/falcosecurity/falco/pull/3247)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake,userspace): bump libs and driver to latest master. [[#3263](https://github.com/falcosecurity/falco/pull/3263)] - [@FedeDP](https://github.com/FedeDP)
* If rule compilation fails, return immediately [[#3260](https://github.com/falcosecurity/falco/pull/3260)] - [@mstemm](https://github.com/mstemm)
* new(userspace/engine): generalize indexable ruleset [[#3251](https://github.com/falcosecurity/falco/pull/3251)] - [@mstemm](https://github.com/mstemm)
* update(cmake): bump libs to master. [[#3249](https://github.com/falcosecurity/falco/pull/3249)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `df963b6` to `ea57e78` [[#3240](https://github.com/falcosecurity/falco/pull/3240)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore(ci): enable dummy tests on the testing framework. [[#3233](https://github.com/falcosecurity/falco/pull/3233)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `679a50a` to `df963b6` [[#3231](https://github.com/falcosecurity/falco/pull/3231)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake): bump libs and driver to master. [[#3225](https://github.com/falcosecurity/falco/pull/3225)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `9e56293` to `679a50a` [[#3222](https://github.com/falcosecurity/falco/pull/3222)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(docs): update CHANGELOG for 0.38.0 (master branch) [[#3224](https://github.com/falcosecurity/falco/pull/3224)] - [@LucaGuerra](https://github.com/LucaGuerra)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 35 |
| Release note | 22 |
| Total | 57 |
## v0.38.2
Released on 2024-08-19

View File

@@ -2,78 +2,100 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
cmake_minimum_required(VERSION 3.5.1)
project(falco)
option(USE_BUNDLED_DEPS "Bundle hard to find dependencies into the Falco binary" ON)
option(USE_DYNAMIC_LIBELF "Dynamically link libelf" ON)
option(USE_DYNAMIC_LIBELF "Dynamically link libelf" OFF)
option(BUILD_WARNINGS_AS_ERRORS "Enable building with -Wextra -Werror flags" OFF)
option(MINIMAL_BUILD "Build a minimal version of Falco, containing only the engine and basic input/output (EXPERIMENTAL)" OFF)
option(
MINIMAL_BUILD
"Build a minimal version of Falco, containing only the engine and basic input/output (EXPERIMENTAL)"
OFF
)
option(MUSL_OPTIMIZED_BUILD "Enable if you want a musl optimized build" OFF)
option(BUILD_FALCO_UNIT_TESTS "Build falco unit tests" OFF)
option(USE_ASAN "Build with AddressSanitizer" OFF)
option(USE_UBSAN "Build with UndefinedBehaviorSanitizer" OFF)
option(UBSAN_HALT_ON_ERROR "Halt on error when building with UBSan" ON)
option(USE_JEMALLOC "Use jemalloc allocator" OFF)
if(WIN32)
if(POLICY CMP0091)
# Needed for CMAKE_MSVC_RUNTIME_LIBRARY
# https://cmake.org/cmake/help/latest/policy/CMP0091.html
cmake_policy(SET CMP0091 NEW)
endif()
if(POLICY CMP0091)
# Needed for CMAKE_MSVC_RUNTIME_LIBRARY
# https://cmake.org/cmake/help/latest/policy/CMP0091.html
cmake_policy(SET CMP0091 NEW)
endif()
set(CPACK_GENERATOR "NSIS") # this needs NSIS installed, and available
elseif (APPLE)
elseif(APPLE)
set(CPACK_GENERATOR "DragNDrop")
elseif(EMSCRIPTEN)
set(USE_BUNDLED_DEPS ON CACHE BOOL "" FORCE)
set(BUILD_DRIVER OFF CACHE BOOL "" FORCE)
set(ENABLE_DKMS OFF CACHE BOOL "" FORCE)
set(BUILD_BPF OFF CACHE BOOL "" FORCE)
set(CPACK_GENERATOR TGZ CACHE BOOL "" FORCE)
set(USE_BUNDLED_DEPS
ON
CACHE BOOL "" FORCE
)
set(BUILD_DRIVER
OFF
CACHE BOOL "" FORCE
)
set(ENABLE_DKMS
OFF
CACHE BOOL "" FORCE
)
set(BUILD_BPF
OFF
CACHE BOOL "" FORCE
)
set(CPACK_GENERATOR
TGZ
CACHE BOOL "" FORCE
)
endif()
# gVisor is currently only supported on Linux x86_64
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" AND CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
option(BUILD_FALCO_GVISOR "Build gVisor support for Falco" ON)
if (BUILD_FALCO_GVISOR)
add_definitions(-DHAS_GVISOR)
endif()
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64"
AND CMAKE_SYSTEM_NAME MATCHES "Linux"
AND NOT MINIMAL_BUILD
)
option(BUILD_FALCO_GVISOR "Build gVisor support for Falco" ON)
if(BUILD_FALCO_GVISOR)
add_definitions(-DHAS_GVISOR)
endif()
endif()
# Modern BPF is not supported on not Linux systems and in MINIMAL_BUILD
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
option(BUILD_FALCO_MODERN_BPF "Build modern BPF support for Falco" ON)
if(BUILD_FALCO_MODERN_BPF)
add_definitions(-DHAS_MODERN_BPF)
endif()
option(BUILD_FALCO_MODERN_BPF "Build modern BPF support for Falco" ON)
if(BUILD_FALCO_MODERN_BPF)
add_definitions(-DHAS_MODERN_BPF)
endif()
endif()
# We shouldn't need to set this, see https://gitlab.kitware.com/cmake/cmake/-/issues/16419
option(EP_UPDATE_DISCONNECTED "ExternalProject update disconnected" OFF)
if (${EP_UPDATE_DISCONNECTED})
set_property(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
PROPERTY EP_UPDATE_DISCONNECTED TRUE)
if(${EP_UPDATE_DISCONNECTED})
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY EP_UPDATE_DISCONNECTED TRUE)
endif()
# Elapsed time
# set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") # TODO(fntlnz, leodido): add a flag to enable this
# Elapsed time set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") #
# TODO(fntlnz, leodido): add a flag to enable this
# Make flag for parallel processing
include(ProcessorCount)
processorcount(PROCESSOR_COUNT)
ProcessorCount(PROCESSOR_COUNT)
if(NOT PROCESSOR_COUNT EQUAL 0)
set(PROCESSOUR_COUNT_MAKE_FLAG -j${PROCESSOR_COUNT})
set(PROCESSOUR_COUNT_MAKE_FLAG -j${PROCESSOR_COUNT})
endif()
# Custom CMake modules
@@ -83,14 +105,14 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
include(GNUInstallDirs)
if(NOT DEFINED FALCO_ETC_DIR)
set(FALCO_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falco")
set(FALCO_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falco")
endif()
# This will be used to print the architecture for which Falco is compiled.
if (EMSCRIPTEN)
set(FALCO_TARGET_ARCH "wasm")
if(EMSCRIPTEN)
set(FALCO_TARGET_ARCH "wasm")
else()
set(FALCO_TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
set(FALCO_TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
endif()
include(CompilerFlags)
@@ -100,25 +122,33 @@ set(DRIVER_NAME "falco")
set(DRIVER_DEVICE_NAME "falco")
set(DRIVERS_REPO "https://download.falco.org/driver")
# If no path is provided, try to search the BPF probe in: `home/.falco/falco-bpf.o`
# This is the same fallback that we had in the libraries: `SCAP_PROBE_BPF_FILEPATH`.
# If no path is provided, try to search the BPF probe in: `home/.falco/falco-bpf.o` This is the same
# fallback that we had in the libraries: `SCAP_PROBE_BPF_FILEPATH`.
set(FALCO_PROBE_BPF_FILEPATH ".${DRIVER_NAME}/${DRIVER_NAME}-bpf.o")
add_definitions(-DFALCO_PROBE_BPF_FILEPATH="${FALCO_PROBE_BPF_FILEPATH}")
if(NOT DEFINED FALCO_COMPONENT_NAME)
set(FALCO_COMPONENT_NAME "${CMAKE_PROJECT_NAME}")
set(FALCO_COMPONENT_NAME "${CMAKE_PROJECT_NAME}")
endif()
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX
/usr
CACHE PATH "Default install path" FORCE)
set(CMAKE_INSTALL_PREFIX
/usr
CACHE PATH "Default install path" FORCE
)
endif()
set(CMD_MAKE make)
include(ExternalProject)
if(USE_JEMALLOC)
if(USE_ASAN)
message(WARNING "Jemalloc and ASAN are known to have issues when combined")
endif()
include(jemalloc)
endif()
# libs
include(falcosecurity-libs)
@@ -131,61 +161,93 @@ include(njson)
# yaml-cpp
include(yaml-cpp)
if(NOT WIN32 AND NOT APPLE AND NOT MINIMAL_BUILD AND NOT EMSCRIPTEN)
# OpenSSL
include(openssl)
if(NOT WIN32
AND NOT APPLE
AND NOT MINIMAL_BUILD
AND NOT EMSCRIPTEN
)
# OpenSSL
include(openssl)
# libcurl
include(curl)
# libcurl
include(curl)
# todo(jasondellaluce,rohith-raju): support webserver for non-linux builds too
# cpp-httlib
include(cpp-httplib)
# todo(jasondellaluce,rohith-raju): support webserver for non-linux builds too cpp-httlib
include(cpp-httplib)
endif()
include(cxxopts)
# One TBB
if (NOT EMSCRIPTEN)
include(tbb)
if(NOT EMSCRIPTEN)
include(tbb)
endif()
include(zlib)
include(valijson)
if (NOT MINIMAL_BUILD)
if (NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN)
include(cares)
include(protobuf)
# gRPC
include(grpc)
endif()
if(NOT MINIMAL_BUILD)
if(NOT WIN32
AND NOT APPLE
AND NOT EMSCRIPTEN
)
include(cares)
include(protobuf)
# gRPC
include(grpc)
endif()
endif()
# Installation
if(WIN32)
set(FALCO_INSTALL_CONF_FILE "%PROGRAMFILES%/${PACKAGE_NAME}-${FALCO_VERSION}/etc/falco/falco.yaml")
install(FILES falco.yaml DESTINATION etc/falco/ COMPONENT "${FALCO_COMPONENT_NAME}")
install(DIRECTORY DESTINATION etc/falco/config.d COMPONENT "${FALCO_COMPONENT_NAME}")
set(FALCO_INSTALL_CONF_FILE
"%PROGRAMFILES%/${PACKAGE_NAME}-${FALCO_VERSION}/etc/falco/falco.yaml"
)
install(
FILES falco.yaml
DESTINATION etc/falco/
COMPONENT "${FALCO_COMPONENT_NAME}"
)
install(
DIRECTORY
DESTINATION etc/falco/config.d
COMPONENT "${FALCO_COMPONENT_NAME}"
)
elseif(APPLE)
set(FALCO_INSTALL_CONF_FILE "/etc/falco/falco.yaml")
install(FILES falco.yaml DESTINATION etc/falco/ COMPONENT "${FALCO_COMPONENT_NAME}")
install(DIRECTORY DESTINATION etc/falco/config.d COMPONENT "${FALCO_COMPONENT_NAME}")
install(
FILES falco.yaml
DESTINATION etc/falco/
COMPONENT "${FALCO_COMPONENT_NAME}"
)
install(
DIRECTORY
DESTINATION etc/falco/config.d
COMPONENT "${FALCO_COMPONENT_NAME}"
)
else()
set(FALCO_INSTALL_CONF_FILE "/etc/falco/falco.yaml")
install(FILES falco.yaml DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
install(DIRECTORY DESTINATION "${FALCO_ETC_DIR}/config.d" COMPONENT "${FALCO_COMPONENT_NAME}")
install(
FILES falco.yaml
DESTINATION "${FALCO_ETC_DIR}"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
install(
DIRECTORY
DESTINATION "${FALCO_ETC_DIR}/config.d"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
endif()
if(NOT MINIMAL_BUILD)
# Coverage
include(Coverage)
# Coverage
include(Coverage)
endif()
# Rules
include(rules)
# Clang format
# add_custom_target(format COMMAND clang-format --style=file -i $<TARGET_PROPERTY:falco,SOURCES> COMMENT "Formatting ..." VERBATIM)
# Clang format add_custom_target(format COMMAND clang-format --style=file -i
# $<TARGET_PROPERTY:falco,SOURCES> COMMENT "Formatting ..." VERBATIM)
# Static analysis
include(static-analysis)
@@ -199,13 +261,17 @@ add_subdirectory(scripts)
add_subdirectory(userspace/engine)
add_subdirectory(userspace/falco)
if(NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN AND NOT MUSL_OPTIMIZED_BUILD)
include(falcoctl)
if(NOT WIN32
AND NOT APPLE
AND NOT EMSCRIPTEN
AND NOT MUSL_OPTIMIZED_BUILD
)
include(falcoctl)
endif()
# Packages configuration
include(CPackConfig)
if(BUILD_FALCO_UNIT_TESTS)
add_subdirectory(unit_tests)
add_subdirectory(unit_tests)
endif()

View File

@@ -2,24 +2,53 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
if(CPACK_GENERATOR MATCHES "DEB" OR CPACK_GENERATOR MATCHES "RPM")
list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-kmod-inject.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-kmod.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-bpf.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-modern-bpf.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-custom.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falcoctl-artifact-follow.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(
APPEND
CPACK_INSTALL_COMMANDS
"mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
list(
APPEND
CPACK_INSTALL_COMMANDS
"cp scripts/systemd/falco-kmod-inject.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
list(
APPEND
CPACK_INSTALL_COMMANDS
"cp scripts/systemd/falco-kmod.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
list(
APPEND
CPACK_INSTALL_COMMANDS
"cp scripts/systemd/falco-bpf.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
list(
APPEND
CPACK_INSTALL_COMMANDS
"cp scripts/systemd/falco-modern-bpf.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
list(
APPEND
CPACK_INSTALL_COMMANDS
"cp scripts/systemd/falco-custom.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
list(
APPEND
CPACK_INSTALL_COMMANDS
"cp scripts/systemd/falcoctl-artifact-follow.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system"
)
endif()
if(CPACK_GENERATOR MATCHES "TGZ")

View File

@@ -2,19 +2,21 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}")
set(CPACK_PACKAGE_VENDOR "Cloud Native Computing Foundation (CNCF) cncf.io.")
set(CPACK_PACKAGE_CONTACT "cncf-falco-dev@lists.cncf.io") # todo: change this once we've got @falco.org addresses
set(CPACK_PACKAGE_CONTACT "cncf-falco-dev@lists.cncf.io") # todo: change this once we've got
# @falco.org addresses
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Falco - Container Native Runtime Security")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/scripts/description.txt")
set(CPACK_PACKAGE_VERSION "${FALCO_VERSION}")
@@ -22,34 +24,41 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${FALCO_VERSION_MAJOR}")
set(CPACK_PACKAGE_VERSION_MINOR "${FALCO_VERSION_MINOR}")
set(CPACK_PACKAGE_VERSION_PATCH "${FALCO_VERSION_PATCH}")
set(CPACK_PROJECT_CONFIG_FILE "${PROJECT_SOURCE_DIR}/cmake/cpack/CMakeCPackOptions.cmake")
set(CPACK_STRIP_FILES "ON")
set(CPACK_PACKAGE_RELOCATABLE "OFF")
if (EMSCRIPTEN)
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-wasm")
if(CMAKE_BUILD_TYPE STREQUAL "debug")
set(CPACK_STRIP_FILES "OFF")
else()
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_STRIP_FILES "ON")
endif()
set(CPACK_PACKAGE_RELOCATABLE "OFF")
if(EMSCRIPTEN)
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-wasm")
else()
set(CPACK_PACKAGE_FILE_NAME
"${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}"
)
endif()
if(WIN32)
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
endif()
# Built packages will include only the following components
set(CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_CURRENT_BINARY_DIR};${FALCO_COMPONENT_NAME};${FALCO_COMPONENT_NAME};/"
"${CMAKE_CURRENT_BINARY_DIR};${FALCO_COMPONENT_NAME};${FALCO_COMPONENT_NAME};/"
)
if(CMAKE_SYSTEM_NAME MATCHES "Linux") # only Linux has drivers
list(APPEND CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_CURRENT_BINARY_DIR};${DRIVER_COMPONENT_NAME};${DRIVER_COMPONENT_NAME};/")
list(APPEND CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_CURRENT_BINARY_DIR};${DRIVER_COMPONENT_NAME};${DRIVER_COMPONENT_NAME};/"
)
endif()
if(NOT CPACK_GENERATOR)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(CPACK_GENERATOR DEB RPM TGZ)
else()
set(CPACK_GENERATOR TGZ)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(CPACK_GENERATOR DEB RPM TGZ)
else()
set(CPACK_GENERATOR TGZ)
endif()
endif()
message(STATUS "Using package generators: ${CPACK_GENERATOR}")
@@ -57,33 +66,35 @@ message(STATUS "Package architecture: ${CMAKE_SYSTEM_PROCESSOR}")
set(CPACK_DEBIAN_PACKAGE_SECTION "utils")
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
endif()
if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
endif()
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://www.falco.org")
set(CPACK_DEBIAN_PACKAGE_DEPENDS "dkms (>= 2.1.0.0)")
set(CPACK_DEBIAN_PACKAGE_SUGGESTS "dkms (>= 2.1.0.0)")
set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA
"${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${CMAKE_BINARY_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cmake/cpack/debian/conffiles"
"${CMAKE_BINARY_DIR}/scripts/debian/postinst;${CMAKE_BINARY_DIR}/scripts/debian/prerm;${CMAKE_BINARY_DIR}/scripts/debian/postrm;${PROJECT_SOURCE_DIR}/cmake/cpack/debian/conffiles"
)
set(CPACK_RPM_PACKAGE_LICENSE "Apache v2.0")
set(CPACK_RPM_PACKAGE_ARCHITECTURE, "amd64")
set(CPACK_RPM_PACKAGE_URL "https://www.falco.org")
set(CPACK_RPM_PACKAGE_REQUIRES "dkms, kernel-devel, systemd")
set(CPACK_RPM_PACKAGE_REQUIRES "systemd")
set(CPACK_RPM_PACKAGE_SUGGESTS "dkms, kernel-devel")
set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_BINARY_DIR}/scripts/rpm/postinstall")
set(CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE "${CMAKE_BINARY_DIR}/scripts/rpm/preuninstall")
set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE "${CMAKE_BINARY_DIR}/scripts/rpm/postuninstall")
set(CPACK_RPM_PACKAGE_VERSION "${FALCO_VERSION}")
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
/usr/src
/usr/share/man
/usr/share/man/man8
/etc
/usr
/usr/bin
/usr/share)
/usr/src
/usr/share/man
/usr/share/man/man8
/etc
/usr
/usr/bin
/usr/share
)
set(CPACK_RPM_PACKAGE_RELOCATABLE "OFF")
include(CPack)

View File

@@ -2,51 +2,54 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT FALCO_EXTRA_DEBUG_FLAGS)
set(FALCO_EXTRA_DEBUG_FLAGS "-D_DEBUG")
set(FALCO_EXTRA_DEBUG_FLAGS "-D_DEBUG")
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
if(CMAKE_BUILD_TYPE STREQUAL "debug")
set(KBUILD_FLAGS "${FALCO_EXTRA_DEBUG_FLAGS} ${FALCO_EXTRA_FEATURE_FLAGS}")
set(KBUILD_FLAGS "${FALCO_EXTRA_DEBUG_FLAGS} ${FALCO_EXTRA_FEATURE_FLAGS}")
elseif(CMAKE_BUILD_TYPE STREQUAL "relwithdebinfo")
set(KBUILD_FLAGS "${FALCO_EXTRA_FEATURE_FLAGS}")
add_definitions(-DBUILD_TYPE_RELWITHDEBINFO)
else()
set(CMAKE_BUILD_TYPE "release")
set(KBUILD_FLAGS "${FALCO_EXTRA_FEATURE_FLAGS}")
add_definitions(-DBUILD_TYPE_RELEASE)
set(CMAKE_BUILD_TYPE "release")
set(KBUILD_FLAGS "${FALCO_EXTRA_FEATURE_FLAGS}")
add_definitions(-DBUILD_TYPE_RELEASE)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if(MINIMAL_BUILD)
set(MINIMAL_BUILD_FLAGS "-DMINIMAL_BUILD")
set(MINIMAL_BUILD_FLAGS "-DMINIMAL_BUILD")
endif()
if(MUSL_OPTIMIZED_BUILD)
set(MUSL_FLAGS "-static -Os -fPIE -pie")
add_definitions(-DMUSL_OPTIMIZED)
set(MUSL_FLAGS "-static -Os -fPIE -pie")
add_definitions(-DMUSL_OPTIMIZED)
endif()
# explicitly set hardening flags
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(FALCO_SECURITY_FLAGS "")
if(LINUX)
set(FALCO_SECURITY_FLAGS "${FALCO_SECURITY_FLAGS} -fstack-protector-strong")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro,-z,now")
set(FALCO_SECURITY_FLAGS "${FALCO_SECURITY_FLAGS} -fstack-protector-strong")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-z,relro,-z,now")
endif()
if(NOT MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "release")
@@ -64,7 +67,9 @@ if(NOT MSVC)
endif()
endif()
set(CMAKE_COMMON_FLAGS "${FALCO_SECURITY_FLAGS} -Wall -ggdb ${FALCO_EXTRA_FEATURE_FLAGS} ${MINIMAL_BUILD_FLAGS} ${MUSL_FLAGS}")
set(CMAKE_COMMON_FLAGS
"${FALCO_SECURITY_FLAGS} -Wall -ggdb ${FALCO_EXTRA_FEATURE_FLAGS} ${MINIMAL_BUILD_FLAGS} ${MUSL_FLAGS}"
)
if(BUILD_WARNINGS_AS_ERRORS)
set(CMAKE_SUPPRESSED_WARNINGS
@@ -83,27 +88,38 @@ if(NOT MSVC)
set(CMAKE_C_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} -g")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} -g")
# Add linker flags to generate separate debug files
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
"${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} -Wl,--build-id"
)
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
"${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} -Wl,--build-id"
)
else() # MSVC
set(MINIMAL_BUILD ON)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
# The WIN32_LEAN_AND_MEAN define avoids possible macro pollution
# when a libsinsp consumer includes the windows.h header:
# https://stackoverflow.com/a/28380820
# Same goes for NOMINMAX:
# The WIN32_LEAN_AND_MEAN define avoids possible macro pollution when a libsinsp consumer
# includes the windows.h header: https://stackoverflow.com/a/28380820 Same goes for NOMINMAX:
# https://stackoverflow.com/questions/5004858/why-is-stdmin-failing-when-windows-h-is-included
add_compile_definitions(
_HAS_STD_BYTE=0
_CRT_SECURE_NO_WARNINGS
WIN32
MINIMAL_BUILD
WIN32_LEAN_AND_MEAN
NOMINMAX
_HAS_STD_BYTE=0 _CRT_SECURE_NO_WARNINGS WIN32 MINIMAL_BUILD WIN32_LEAN_AND_MEAN NOMINMAX
)
set(FALCOSECURITY_LIBS_COMMON_FLAGS "/EHsc /W3 /Zi /std:c++17")
set(FALCOSECURITY_LIBS_DEBUG_FLAGS "/MTd /Od")
set(FALCOSECURITY_LIBS_RELEASE_FLAGS "/MT")
set(FALCOSECURITY_LIBS_RELWITHDEBINFO_FLAGS "/MT /Zi")
# Ensure linker generates PDB files for MSVC
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
"${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} /DEBUG"
)
set(CMAKE_C_FLAGS "${FALCOSECURITY_LIBS_COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS "${FALCOSECURITY_LIBS_COMMON_FLAGS}")
@@ -114,4 +130,7 @@ else() # MSVC
set(CMAKE_C_FLAGS_RELEASE "${FALCOSECURITY_LIBS_RELEASE_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${FALCOSECURITY_LIBS_RELEASE_FLAGS}")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${FALCOSECURITY_LIBS_RELWITHDEBINFO_FLAGS}")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${FALCOSECURITY_LIBS_RELWITHDEBINFO_FLAGS}")
endif()

View File

@@ -2,25 +2,28 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
# Tests coverage
option(FALCO_COVERAGE "Build test suite with coverage information" OFF)
if(FALCO_COVERAGE)
if(NOT (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")))
message(FATAL_ERROR "FALCO_COVERAGE requires GCC or Clang.")
endif()
if(NOT (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES
"Clang"))
)
message(FATAL_ERROR "FALCO_COVERAGE requires GCC or Clang.")
endif()
message(STATUS "Building with coverage information")
add_compile_options(-g --coverage)
set(CMAKE_SHARED_LINKER_FLAGS "--coverage ${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "--coverage ${CMAKE_EXE_LINKER_FLAGS}")
message(STATUS "Building with coverage information")
add_compile_options(-g --coverage)
set(CMAKE_SHARED_LINKER_FLAGS "--coverage ${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "--coverage ${CMAKE_EXE_LINKER_FLAGS}")
endif()

View File

@@ -2,30 +2,32 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
function(copy_files_to_build_dir source_files targetsuffix)
set(build_files)
set(build_files)
foreach(file_path ${source_files})
get_filename_component(trace_file ${file_path} NAME)
list(APPEND build_files ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
endforeach()
foreach(file_path ${source_files})
get_filename_component(trace_file ${file_path} NAME)
list(APPEND build_files ${CMAKE_CURRENT_BINARY_DIR}/${trace_file})
endforeach()
add_custom_target(copy-files-${targetsuffix} ALL
DEPENDS ${build_files})
add_custom_target(copy-files-${targetsuffix} ALL DEPENDS ${build_files})
add_custom_command(OUTPUT ${build_files}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${source_files} ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${source_files})
add_custom_command(
OUTPUT ${build_files}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${source_files} ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${source_files}
)
endfunction()

View File

@@ -2,25 +2,31 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
option(USE_BUNDLED_CPPHTTPLIB "Enable building of the bundled cpp-httplib" ${USE_BUNDLED_DEPS})
if(USE_BUNDLED_CPPHTTPLIB)
include(FetchContent)
FetchContent_Declare(cpp-httplib
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.15.3.tar.gz
URL_HASH SHA256=2121bbf38871bb2aafb5f7f2b9b94705366170909f434428352187cb0216124e
)
FetchContent_MakeAvailable(cpp-httplib)
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
set(HTTPLIB_REQUIRE_BROTLI OFF)
set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF)
set(HTTPLIB_REQUIRE_ZLIB OFF)
include(FetchContent)
FetchContent_Declare(
cpp-httplib
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.15.3.tar.gz
URL_HASH SHA256=2121bbf38871bb2aafb5f7f2b9b94705366170909f434428352187cb0216124e
)
FetchContent_MakeAvailable(cpp-httplib)
else()
find_package(httplib CONFIG REQUIRED)
find_package(httplib CONFIG REQUIRED)
endif()

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
#
@@ -19,25 +20,26 @@
option(USE_BUNDLED_CXXOPTS "Enable building of the bundled cxxopts" ${USE_BUNDLED_DEPS})
if(CXXOPTS_INCLUDE_DIR)
# we already have cxxopts
# we already have cxxopts
elseif(NOT USE_BUNDLED_CXXOPTS)
find_package(cxxopts CONFIG REQUIRED)
get_target_property(CXXOPTS_INCLUDE_DIR cxxopts::cxxopts INTERFACE_INCLUDE_DIRECTORIES)
find_package(cxxopts CONFIG REQUIRED)
get_target_property(CXXOPTS_INCLUDE_DIR cxxopts::cxxopts INTERFACE_INCLUDE_DIRECTORIES)
else()
set(CXXOPTS_SRC "${PROJECT_BINARY_DIR}/cxxopts-prefix/src/cxxopts/")
set(CXXOPTS_INCLUDE_DIR "${CXXOPTS_SRC}/include")
set(CXXOPTS_SRC "${PROJECT_BINARY_DIR}/cxxopts-prefix/src/cxxopts/")
set(CXXOPTS_INCLUDE_DIR "${CXXOPTS_SRC}/include")
message(STATUS "Using bundled cxxopts in ${CXXOPTS_SRC}")
message(STATUS "Using bundled cxxopts in ${CXXOPTS_SRC}")
ExternalProject_Add(
cxxopts
URL "https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.0.0.tar.gz"
URL_HASH "SHA256=36f41fa2a46b3c1466613b63f3fa73dc24d912bc90d667147f1e43215a8c6d00"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
ExternalProject_Add(
cxxopts
URL "https://github.com/jarro2783/cxxopts/archive/refs/tags/v3.0.0.tar.gz"
URL_HASH "SHA256=36f41fa2a46b3c1466613b63f3fa73dc24d912bc90d667147f1e43215a8c6d00"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
endif()
if(NOT TARGET cxxopts)
add_custom_target(cxxopts)
add_custom_target(cxxopts)
endif()

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
cmake_minimum_required(VERSION 3.5.1)
@@ -20,12 +21,12 @@ message(STATUS "Driver repository: ${DRIVER_REPO}")
message(STATUS "Driver version: ${DRIVER_VERSION}")
ExternalProject_Add(
driver
URL "https://github.com/${DRIVER_REPO}/archive/${DRIVER_VERSION}.tar.gz"
URL_HASH "${DRIVER_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
PATCH_COMMAND sh -c "mv ./driver ../driver.tmp && rm -rf ./* && mv ../driver.tmp/* ."
driver
URL "https://github.com/${DRIVER_REPO}/archive/${DRIVER_VERSION}.tar.gz"
URL_HASH "${DRIVER_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
PATCH_COMMAND sh -c "mv ./driver ../driver.tmp && rm -rf ./* && mv ../driver.tmp/* ."
)

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
set(DRIVER_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/driver-repo")
@@ -18,37 +19,42 @@ set(DRIVER_CMAKE_WORKING_DIR "${CMAKE_BINARY_DIR}/driver-repo")
file(MAKE_DIRECTORY ${DRIVER_CMAKE_WORKING_DIR})
if(DRIVER_SOURCE_DIR)
set(DRIVER_VERSION "0.0.0-local")
message(STATUS "Using local version for driver: '${DRIVER_SOURCE_DIR}'")
set(DRIVER_VERSION "0.0.0-local")
message(STATUS "Using local version for driver: '${DRIVER_SOURCE_DIR}'")
else()
# DRIVER_REPO accepts a repository name (<org name>/<repo name>) alternative to the falcosecurity/libs repository.
# In case you want to test against a fork of falcosecurity/libs just pass the variable -
# ie., `cmake -DDRIVER_REPO=<your-gh-handle>/libs ..`
if (NOT DRIVER_REPO)
set(DRIVER_REPO "falcosecurity/libs")
endif()
# DRIVER_REPO accepts a repository name (<org name>/<repo name>) alternative to the
# falcosecurity/libs repository. In case you want to test against a fork of falcosecurity/libs
# just pass the variable - ie., `cmake -DDRIVER_REPO=<your-gh-handle>/libs ..`
if(NOT DRIVER_REPO)
set(DRIVER_REPO "falcosecurity/libs")
endif()
# DRIVER_VERSION accepts a git reference (branch name, commit hash, or tag) to the falcosecurity/libs repository
# which contains the driver source code under the `/driver` directory.
# The chosen driver version must be compatible with the given FALCOSECURITY_LIBS_VERSION.
# 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 "0.18.0-rc2")
set(DRIVER_CHECKSUM "SHA256=e016ee1113eb5a14c85d9c4828244f5fba37cd663ecd38f5b58fbc4142348782")
endif()
# DRIVER_VERSION accepts a git reference (branch name, commit hash, or tag) to the
# falcosecurity/libs repository which contains the driver source code under the `/driver`
# directory. The chosen driver version must be compatible with the given
# FALCOSECURITY_LIBS_VERSION. 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 "8.0.0+driver")
set(DRIVER_CHECKSUM
"SHA256=f35990d6a1087a908fe94e1390027b9580d4636032c0f2b80bf945219474fd6b"
)
endif()
# cd /path/to/build && cmake /path/to/source
execute_process(COMMAND "${CMAKE_COMMAND}"
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
-DDRIVER_REPO=${DRIVER_REPO}
-DDRIVER_VERSION=${DRIVER_VERSION}
-DDRIVER_CHECKSUM=${DRIVER_CHECKSUM}
${DRIVER_CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${DRIVER_CMAKE_WORKING_DIR})
# cd /path/to/build && cmake /path/to/source
execute_process(
COMMAND
"${CMAKE_COMMAND}" -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" -DDRIVER_REPO=${DRIVER_REPO}
-DDRIVER_VERSION=${DRIVER_VERSION} -DDRIVER_CHECKSUM=${DRIVER_CHECKSUM}
${DRIVER_CMAKE_SOURCE_DIR}
WORKING_DIRECTORY ${DRIVER_CMAKE_WORKING_DIR}
)
# cmake --build .
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${DRIVER_CMAKE_WORKING_DIR}")
set(DRIVER_SOURCE_DIR "${DRIVER_CMAKE_WORKING_DIR}/driver-prefix/src/driver")
# cmake --build .
execute_process(
COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${DRIVER_CMAKE_WORKING_DIR}"
)
set(DRIVER_SOURCE_DIR "${DRIVER_CMAKE_WORKING_DIR}/driver-prefix/src/driver")
endif()
add_definitions(-D_GNU_SOURCE)

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
# Retrieve git ref and commit hash
@@ -17,33 +18,39 @@ include(GetVersionFromGit)
# Get Falco version variable according to git index
if(NOT FALCO_VERSION)
set(FALCO_VERSION "0.0.0")
get_version_from_git(FALCO_VERSION "" "")
set(FALCO_VERSION "0.0.0")
get_version_from_git(FALCO_VERSION "" "")
endif()
# Remove the starting "v" in case there is one
string(REGEX REPLACE "^v(.*)" "\\1" FALCO_VERSION "${FALCO_VERSION}")
string(REGEX MATCH "^(0|[1-9][0-9]*)" FALCO_VERSION_MAJOR "${FALCO_VERSION}")
string(REGEX REPLACE "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\..*" "\\2" FALCO_VERSION_MINOR "${FALCO_VERSION}")
string(REGEX REPLACE "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*).*" "\\3" FALCO_VERSION_PATCH
"${FALCO_VERSION}")
string(REGEX REPLACE "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\..*" "\\2" FALCO_VERSION_MINOR
"${FALCO_VERSION}"
)
string(REGEX REPLACE "^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*).*" "\\3"
FALCO_VERSION_PATCH "${FALCO_VERSION}"
)
string(
REGEX
REPLACE
"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*).*"
"\\5"
FALCO_VERSION_PRERELEASE
"${FALCO_VERSION}")
REGEX
REPLACE
"^(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-((0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*)(\\.(0|[1-9][0-9]*|[0-9]*[a-zA-Z-][0-9a-zA-Z-]*))*).*"
"\\5"
FALCO_VERSION_PRERELEASE
"${FALCO_VERSION}"
)
if(FALCO_VERSION_PRERELEASE STREQUAL "${FALCO_VERSION}")
set(FALCO_VERSION_PRERELEASE "")
set(FALCO_VERSION_PRERELEASE "")
endif()
if(NOT FALCO_VERSION_BUILD)
string(REGEX REPLACE ".*\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)" "\\1" FALCO_VERSION_BUILD "${FALCO_VERSION}")
string(REGEX REPLACE ".*\\+([0-9a-zA-Z-]+(\\.[0-9a-zA-Z-]+)*)" "\\1" FALCO_VERSION_BUILD
"${FALCO_VERSION}"
)
endif()
if(FALCO_VERSION_BUILD STREQUAL "${FALCO_VERSION}")
set(FALCO_VERSION_BUILD "")
set(FALCO_VERSION_BUILD "")
endif()
message(STATUS "Falco version: ${FALCO_VERSION}")

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
include(ExternalProject)
@@ -17,30 +18,39 @@ include(ExternalProject)
option(ADD_FALCOCTL_DEPENDENCY "Add falcoctl dependency while building falco" ON)
if(ADD_FALCOCTL_DEPENDENCY)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} FALCOCTL_SYSTEM_NAME)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} FALCOCTL_SYSTEM_NAME)
set(FALCOCTL_VERSION "0.10.0")
set(FALCOCTL_VERSION "0.11.0")
message(STATUS "Building with falcoctl: ${FALCOCTL_VERSION}")
message(STATUS "Building with falcoctl: ${FALCOCTL_VERSION}")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "32d1be4ab2335d9c3fc8ae8900341bcc26d3166094fc553ddb7bb783aa6c7b68")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "9186fd948c1230c338a7fa36d6569ce85d3c4aa8153b30e8d86d2e887eb76756")
endif()
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "b9d0e0f50813e7172a945f36f70c5c3c16a677ab4c85b35b6f7a155bc92768fc")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "689c625d1d414cbf53d39ef94083a53dda3ea4ac4908799fb85f4519e21442e0")
endif()
ExternalProject_Add(
falcoctl
URL "https://github.com/falcosecurity/falcoctl/releases/download/v${FALCOCTL_VERSION}/falcoctl_${FALCOCTL_VERSION}_${FALCOCTL_SYSTEM_NAME}_${FALCOCTL_SYSTEM_PROC_GO}.tar.gz"
URL_HASH "SHA256=${FALCOCTL_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
ExternalProject_Add(
falcoctl
URL "https://github.com/falcosecurity/falcoctl/releases/download/v${FALCOCTL_VERSION}/falcoctl_${FALCOCTL_VERSION}_${FALCOCTL_SYSTEM_NAME}_${FALCOCTL_SYSTEM_PROC_GO}.tar.gz"
URL_HASH "SHA256=${FALCOCTL_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
install(PROGRAMS "${PROJECT_BINARY_DIR}/falcoctl-prefix/src/falcoctl/falcoctl" DESTINATION "${FALCO_BIN_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
install(DIRECTORY DESTINATION "${FALCO_ABSOLUTE_SHARE_DIR}/plugins" COMPONENT "${FALCO_COMPONENT_NAME}")
install(
PROGRAMS "${PROJECT_BINARY_DIR}/falcoctl-prefix/src/falcoctl/falcoctl"
DESTINATION "${FALCO_BIN_DIR}"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
install(
DIRECTORY
DESTINATION "${FALCO_ABSOLUTE_SHARE_DIR}/plugins"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
else()
message(STATUS "Won't build with falcoctl")
message(STATUS "Won't build with falcoctl")
endif()

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
cmake_minimum_required(VERSION 3.5.1)
@@ -20,11 +21,11 @@ message(STATUS "Libs repository: ${FALCOSECURITY_LIBS_REPO}")
message(STATUS "Libs version: ${FALCOSECURITY_LIBS_VERSION}")
ExternalProject_Add(
falcosecurity-libs
URL "https://github.com/${FALCOSECURITY_LIBS_REPO}/archive/${FALCOSECURITY_LIBS_VERSION}.tar.gz"
URL_HASH "${FALCOSECURITY_LIBS_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
falcosecurity-libs
URL "https://github.com/${FALCOSECURITY_LIBS_REPO}/archive/${FALCOSECURITY_LIBS_VERSION}.tar.gz"
URL_HASH "${FALCOSECURITY_LIBS_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)

View File

@@ -2,65 +2,81 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
set(FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/falcosecurity-libs-repo")
set(FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/falcosecurity-libs-repo"
)
set(FALCOSECURITY_LIBS_CMAKE_WORKING_DIR "${CMAKE_BINARY_DIR}/falcosecurity-libs-repo")
file(MAKE_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR})
# explicitly disable the bundled driver, since we pull it separately
set(USE_BUNDLED_DRIVER OFF CACHE BOOL "")
set(USE_BUNDLED_DRIVER
OFF
CACHE BOOL ""
)
if(FALCOSECURITY_LIBS_SOURCE_DIR)
set(FALCOSECURITY_LIBS_VERSION "0.0.0-local")
message(STATUS "Using local version of falcosecurity/libs: '${FALCOSECURITY_LIBS_SOURCE_DIR}'")
set(FALCOSECURITY_LIBS_VERSION "0.0.0-local")
message(STATUS "Using local version of falcosecurity/libs: '${FALCOSECURITY_LIBS_SOURCE_DIR}'")
else()
# FALCOSECURITY_LIBS_REPO accepts a repository name (<org name>/<repo name>) alternative to the falcosecurity/libs repository.
# In case you want to test against a fork of falcosecurity/libs just pass the variable -
# ie., `cmake -DFALCOSECURITY_LIBS_REPO=<your-gh-handle>/libs ..`
if (NOT FALCOSECURITY_LIBS_REPO)
set(FALCOSECURITY_LIBS_REPO "falcosecurity/libs")
endif()
# FALCOSECURITY_LIBS_REPO accepts a repository name (<org name>/<repo name>) alternative to the
# falcosecurity/libs repository. In case you want to test against a fork of falcosecurity/libs
# just pass the variable - ie., `cmake -DFALCOSECURITY_LIBS_REPO=<your-gh-handle>/libs ..`
if(NOT FALCOSECURITY_LIBS_REPO)
set(FALCOSECURITY_LIBS_REPO "falcosecurity/libs")
endif()
# FALCOSECURITY_LIBS_VERSION accepts a git reference (branch name, commit hash, or tag) to the falcosecurity/libs repository.
# 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 "0.18.0-rc2")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=e016ee1113eb5a14c85d9c4828244f5fba37cd663ecd38f5b58fbc4142348782")
endif()
# FALCOSECURITY_LIBS_VERSION accepts a git reference (branch name, commit hash, or tag) to the
# falcosecurity/libs repository. 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 "0.20.0")
set(FALCOSECURITY_LIBS_CHECKSUM
"SHA256=4ae6ddb42a1012bacd88c63abdaa7bd27ca0143c4721338a22c45597e63bc99d"
)
endif()
# cd /path/to/build && cmake /path/to/source
execute_process(COMMAND "${CMAKE_COMMAND}"
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
-DFALCOSECURITY_LIBS_REPO=${FALCOSECURITY_LIBS_REPO}
-DFALCOSECURITY_LIBS_VERSION=${FALCOSECURITY_LIBS_VERSION}
-DFALCOSECURITY_LIBS_CHECKSUM=${FALCOSECURITY_LIBS_CHECKSUM}
${FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR} WORKING_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR})
# cd /path/to/build && cmake /path/to/source
execute_process(
COMMAND
"${CMAKE_COMMAND}" -DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
-DFALCOSECURITY_LIBS_REPO=${FALCOSECURITY_LIBS_REPO}
-DFALCOSECURITY_LIBS_VERSION=${FALCOSECURITY_LIBS_VERSION}
-DFALCOSECURITY_LIBS_CHECKSUM=${FALCOSECURITY_LIBS_CHECKSUM}
${FALCOSECURITY_LIBS_CMAKE_SOURCE_DIR}
WORKING_DIRECTORY ${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}
)
# cmake --build .
execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}")
set(FALCOSECURITY_LIBS_SOURCE_DIR "${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}/falcosecurity-libs-prefix/src/falcosecurity-libs")
# cmake --build .
execute_process(
COMMAND "${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY "${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}"
)
set(FALCOSECURITY_LIBS_SOURCE_DIR
"${FALCOSECURITY_LIBS_CMAKE_WORKING_DIR}/falcosecurity-libs-prefix/src/falcosecurity-libs"
)
endif()
set(LIBS_PACKAGE_NAME "falcosecurity")
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_definitions(-D_GNU_SOURCE)
add_definitions(-DHAS_CAPTURE)
add_definitions(-D_GNU_SOURCE)
endif()
if(MUSL_OPTIMIZED_BUILD)
add_definitions(-DMUSL_OPTIMIZED)
add_definitions(-DMUSL_OPTIMIZED)
endif()
set(SCAP_HOST_ROOT_ENV_VAR_NAME "HOST_ROOT")
@@ -68,27 +84,60 @@ set(SCAP_HOSTNAME_ENV_VAR "FALCO_HOSTNAME")
set(SINSP_AGENT_CGROUP_MEM_PATH_ENV_VAR "FALCO_CGROUP_MEM_PATH")
if(NOT LIBS_DIR)
set(LIBS_DIR "${FALCOSECURITY_LIBS_SOURCE_DIR}")
set(LIBS_DIR "${FALCOSECURITY_LIBS_SOURCE_DIR}")
endif()
# configure gVisor support
set(BUILD_LIBSCAP_GVISOR ${BUILD_FALCO_GVISOR} CACHE BOOL "")
set(BUILD_LIBSCAP_GVISOR
${BUILD_FALCO_GVISOR}
CACHE BOOL ""
)
# configure modern BPF support
set(BUILD_LIBSCAP_MODERN_BPF ${BUILD_FALCO_MODERN_BPF} CACHE BOOL "")
set(BUILD_LIBSCAP_MODERN_BPF
${BUILD_FALCO_MODERN_BPF}
CACHE BOOL ""
)
# explicitly disable the tests/examples of this dependency
set(CREATE_TEST_TARGETS OFF CACHE BOOL "")
set(BUILD_LIBSCAP_EXAMPLES OFF CACHE BOOL "")
set(CREATE_TEST_TARGETS
OFF
CACHE BOOL ""
)
set(BUILD_LIBSCAP_EXAMPLES
OFF
CACHE BOOL ""
)
set(USE_BUNDLED_TBB ON CACHE BOOL "")
set(USE_BUNDLED_JSONCPP ON CACHE BOOL "")
set(USE_BUNDLED_VALIJSON ON CACHE BOOL "")
set(USE_BUNDLED_RE2 ON CACHE BOOL "")
set(USE_BUNDLED_UTHASH ON CACHE BOOL "")
set(USE_BUNDLED_TBB
ON
CACHE BOOL ""
)
set(USE_BUNDLED_JSONCPP
ON
CACHE BOOL ""
)
set(USE_BUNDLED_VALIJSON
ON
CACHE BOOL ""
)
set(USE_BUNDLED_RE2
ON
CACHE BOOL ""
)
set(USE_BUNDLED_UTHASH
ON
CACHE BOOL ""
)
if(USE_DYNAMIC_LIBELF)
set(USE_BUNDLED_LIBELF OFF CACHE BOOL "")
set(USE_SHARED_LIBELF ON CACHE BOOL "")
set(USE_BUNDLED_LIBELF
OFF
CACHE BOOL ""
)
set(USE_SHARED_LIBELF
ON
CACHE BOOL ""
)
endif()
list(APPEND CMAKE_MODULE_PATH "${FALCOSECURITY_LIBS_SOURCE_DIR}/cmake/modules")
@@ -97,15 +146,18 @@ include(CheckSymbolExists)
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
if(HAVE_STRLCPY)
message(STATUS "Existing strlcpy and strlcat found, will *not* use local definition by setting -DHAVE_STRLCPY and -DHAVE_STRLCAT.")
add_definitions(-DHAVE_STRLCPY)
add_definitions(-DHAVE_STRLCAT)
message(
STATUS
"Existing strlcpy and strlcat found, will *not* use local definition by setting -DHAVE_STRLCPY and -DHAVE_STRLCAT."
)
add_definitions(-DHAVE_STRLCPY)
add_definitions(-DHAVE_STRLCAT)
else()
message(STATUS "No strlcpy and strlcat found, will use local definition")
message(STATUS "No strlcpy and strlcat found, will use local definition")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
include(driver)
include(driver)
endif()
include(libscap)
include(libsinsp)

View File

@@ -0,0 +1,70 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2024 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.
#
option(USE_BUNDLED_JEMALLOC "Use bundled jemalloc allocator" ${USE_BUNDLED_DEPS})
if(JEMALLOC_INCLUDE)
# we already have JEMALLOC
elseif(NOT USE_BUNDLED_JEMALLOC)
find_path(JEMALLOC_INCLUDE jemalloc/jemalloc.h)
set(JEMALLOC_INCLUDE ${JEMALLOC_INCLUDE}/jemalloc)
if(BUILD_SHARED_LIBS)
set(JEMALLOC_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
else()
set(JEMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
find_library(JEMALLOC_LIB NAMES libjemalloc${JEMALLOC_LIB_SUFFIX})
if(JEMALLOC_LIB)
message(STATUS "Found JEMALLOC: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}")
else()
message(FATAL_ERROR "Couldn't find system jemalloc")
endif()
else()
if(BUILD_SHARED_LIBS)
set(JEMALLOC_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
else()
set(JEMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
set(JEMALLOC_SRC "${PROJECT_BINARY_DIR}/jemalloc-prefix/src")
set(JEMALLOC_LIB "${JEMALLOC_SRC}/jemalloc/lib/libjemalloc${JEMALLOC_LIB_SUFFIX}")
set(JEMALLOC_INCLUDE "${JEMALLOC_SRC}/jemalloc/include/jemalloc")
ExternalProject_Add(
jemalloc
PREFIX "${PROJECT_BINARY_DIR}/jemalloc-prefix"
URL "https://github.com/jemalloc/jemalloc/archive/refs/tags/5.3.0.tar.gz"
URL_HASH "SHA256=ef6f74fd45e95ee4ef7f9e19ebe5b075ca6b7fbe0140612b2a161abafb7ee179"
CONFIGURE_COMMAND ./autogen.sh --enable-prof --disable-libdl
BUILD_IN_SOURCE 1
BUILD_COMMAND make build_lib_static
INSTALL_COMMAND ""
UPDATE_COMMAND ""
BUILD_BYPRODUCTS ${JEMALLOC_LIB}
)
message(STATUS "Using bundled jemalloc: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}")
install(
FILES "${JEMALLOC_LIB}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
endif()
# We add a custom target, in this way we can always depend on `jemalloc` without distinguishing
# between "bundled" and "not-bundled" case
if(NOT TARGET jemalloc)
add_custom_target(jemalloc)
endif()
include_directories(${JEMALLOC_INCLUDE})
add_compile_definitions(HAS_JEMALLOC)

View File

@@ -2,25 +2,27 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
option(USE_BUNDLED_NLOHMANN_JSON "Enable building of the bundled nlohmann-json" ${USE_BUNDLED_DEPS})
if(USE_BUNDLED_NLOHMANN_JSON)
include(FetchContent)
FetchContent_Declare(nlohmann_json
URL https://github.com/nlohmann/json/archive/v3.11.3.tar.gz
URL_HASH SHA256=0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406
)
FetchContent_MakeAvailable(nlohmann_json)
include(FetchContent)
FetchContent_Declare(
nlohmann_json
URL https://github.com/nlohmann/json/archive/v3.11.3.tar.gz
URL_HASH SHA256=0d8ef5af7f9794e3263480193c491549b2ba6cc74bb018906202ada498a79406
)
FetchContent_MakeAvailable(nlohmann_json)
else()
find_package(nlohmann_json CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
endif()

View File

@@ -2,39 +2,46 @@
#
# Copyright (C) 2024 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
# 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.
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
include(GNUInstallDirs)
include(ExternalProject)
if(NOT DEFINED FALCOSECURITY_RULES_FALCO_PATH)
# falco_rules.yaml
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-3.2.0")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM "SHA256=b3990bf0209cfbf6a903b361e458a1f5851a9a5aeee808ad26a5ddbe1377157d")
set(FALCOSECURITY_RULES_FALCO_PATH "${PROJECT_BINARY_DIR}/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml")
ExternalProject_Add(
falcosecurity-rules-falco
URL "https://download.falco.org/rules/${FALCOSECURITY_RULES_FALCO_VERSION}.tar.gz"
URL_HASH "${FALCOSECURITY_RULES_FALCO_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
# falco_rules.yaml
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-3.2.0")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM
"SHA256=b3990bf0209cfbf6a903b361e458a1f5851a9a5aeee808ad26a5ddbe1377157d"
)
set(FALCOSECURITY_RULES_FALCO_PATH
"${PROJECT_BINARY_DIR}/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml"
)
ExternalProject_Add(
falcosecurity-rules-falco
URL "https://download.falco.org/rules/${FALCOSECURITY_RULES_FALCO_VERSION}.tar.gz"
URL_HASH "${FALCOSECURITY_RULES_FALCO_CHECKSUM}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
endif()
if(NOT DEFINED FALCOSECURITY_RULES_LOCAL_PATH)
# falco_rules.local.yaml
set(FALCOSECURITY_RULES_LOCAL_PATH "${PROJECT_BINARY_DIR}/falcosecurity-rules-local-prefix/falco_rules.local.yaml")
file(WRITE "${FALCOSECURITY_RULES_LOCAL_PATH}" "# Your custom rules!\n")
# falco_rules.local.yaml
set(FALCOSECURITY_RULES_LOCAL_PATH
"${PROJECT_BINARY_DIR}/falcosecurity-rules-local-prefix/falco_rules.local.yaml"
)
file(WRITE "${FALCOSECURITY_RULES_LOCAL_PATH}" "# Your custom rules!\n")
endif()
if(NOT DEFINED FALCO_ETC_DIR)
@@ -46,34 +53,43 @@ if(WIN32 OR APPLE)
endif()
if(NOT DEFINED FALCO_RULES_DEST_FILENAME)
set(FALCO_RULES_DEST_FILENAME "falco_rules.yaml")
set(FALCO_LOCAL_RULES_DEST_FILENAME "falco_rules.local.yaml")
set(FALCO_RULES_DEST_FILENAME "falco_rules.yaml")
set(FALCO_LOCAL_RULES_DEST_FILENAME "falco_rules.local.yaml")
endif()
if(DEFINED FALCO_COMPONENT) # Allow a slim version of Falco to be embedded in other projects, intentionally *not* installing all rulesets.
install(
FILES "${FALCOSECURITY_RULES_FALCO_PATH}"
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_RULES_DEST_FILENAME}")
if(DEFINED FALCO_COMPONENT) # Allow a slim version of Falco to be embedded in other projects,
# intentionally *not* installing all rulesets.
install(
FILES "${FALCOSECURITY_RULES_FALCO_PATH}"
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_RULES_DEST_FILENAME}"
)
install(
FILES "${FALCOSECURITY_RULES_LOCAL_PATH}"
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}")
install(
FILES "${FALCOSECURITY_RULES_LOCAL_PATH}"
COMPONENT "${FALCO_COMPONENT}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}"
)
else() # Default Falco installation
install(
FILES "${FALCOSECURITY_RULES_FALCO_PATH}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}")
install(
FILES "${FALCOSECURITY_RULES_FALCO_PATH}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
install(
FILES "${FALCOSECURITY_RULES_LOCAL_PATH}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}")
install(
FILES "${FALCOSECURITY_RULES_LOCAL_PATH}"
DESTINATION "${FALCO_ETC_DIR}"
RENAME "${FALCO_LOCAL_RULES_DEST_FILENAME}"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
install(DIRECTORY DESTINATION "${FALCO_ETC_DIR}/rules.d" COMPONENT "${FALCO_COMPONENT_NAME}")
install(
DIRECTORY
DESTINATION "${FALCO_ETC_DIR}/rules.d"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
endif()

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
# create the reports folder
@@ -22,35 +23,42 @@ find_program(CPPCHECK cppcheck)
find_program(CPPCHECK_HTMLREPORT cppcheck-htmlreport)
if(NOT CPPCHECK)
message(STATUS "cppcheck command not found, static code analysis using cppcheck will not be available.")
message(
STATUS
"cppcheck command not found, static code analysis using cppcheck will not be available."
)
else()
message(STATUS "cppcheck found at: ${CPPCHECK}")
# we are aware that cppcheck can be run
# along with the software compilation in a single step
# using the CMAKE_CXX_CPPCHECK variables.
# However, for practical needs we want to keep the
# two things separated and have a specific target for it.
# Our cppcheck target reads the compilation database produced by CMake
set(CMAKE_EXPORT_COMPILE_COMMANDS On)
add_custom_target(
cppcheck
COMMAND ${CPPCHECK}
"--enable=all"
"--force"
"--inconclusive"
"--inline-suppr" # allows to specify suppressions directly in source code
"--xml" # we want to generate a report
"--output-file=${CMAKE_CURRENT_BINARY_DIR}/static-analysis-reports/cppcheck/cppcheck.xml" # generate the report under the reports folder in the build folder
"-i${CMAKE_CURRENT_BINARY_DIR}"# exclude the build folder
"${CMAKE_SOURCE_DIR}"
)
message(STATUS "cppcheck found at: ${CPPCHECK}")
# we are aware that cppcheck can be run along with the software compilation in a single step
# using the CMAKE_CXX_CPPCHECK variables. However, for practical needs we want to keep the two
# things separated and have a specific target for it. Our cppcheck target reads the compilation
# database produced by CMake
set(CMAKE_EXPORT_COMPILE_COMMANDS On)
add_custom_target(
cppcheck
COMMAND
${CPPCHECK} "--enable=all" "--force" "--inconclusive" "--inline-suppr" # allows to
# specify suppressions directly in source code
"--xml" # we want to generate a report
"--output-file=${CMAKE_CURRENT_BINARY_DIR}/static-analysis-reports/cppcheck/cppcheck.xml" # generate
# the report under the reports folder in the build folder
"-i${CMAKE_CURRENT_BINARY_DIR}" # exclude the build folder
"${CMAKE_SOURCE_DIR}"
)
endif() # CPPCHECK
if(NOT CPPCHECK_HTMLREPORT)
message(STATUS "cppcheck-htmlreport command not found, will not be able to produce html reports for cppcheck results")
message(
STATUS
"cppcheck-htmlreport command not found, will not be able to produce html reports for cppcheck results"
)
else()
message(STATUS "cppcheck-htmlreport found at: ${CPPCHECK_HTMLREPORT}")
add_custom_target(
cppcheck_htmlreport
COMMAND ${CPPCHECK_HTMLREPORT} --title=${CMAKE_PROJECT_NAME} --report-dir=${CMAKE_CURRENT_BINARY_DIR}/static-analysis-reports/cppcheck --file=static-analysis-reports/cppcheck/cppcheck.xml)
message(STATUS "cppcheck-htmlreport found at: ${CPPCHECK_HTMLREPORT}")
add_custom_target(
cppcheck_htmlreport
COMMAND
${CPPCHECK_HTMLREPORT} --title=${CMAKE_PROJECT_NAME}
--report-dir=${CMAKE_CURRENT_BINARY_DIR}/static-analysis-reports/cppcheck
--file=static-analysis-reports/cppcheck/cppcheck.xml
)
endif() # CPPCHECK_HTMLREPORT

View File

@@ -2,25 +2,27 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
option(USE_BUNDLED_YAMLCPP "Enable building of the bundled yamlcpp" ${USE_BUNDLED_DEPS})
if(USE_BUNDLED_YAMLCPP)
include(FetchContent)
FetchContent_Declare(yamlcpp
URL https://github.com/jbeder/yaml-cpp/archive/refs/tags/0.8.0.tar.gz
URL_HASH SHA256=fbe74bbdcee21d656715688706da3c8becfd946d92cd44705cc6098bb23b3a16
)
FetchContent_MakeAvailable(yamlcpp)
include(FetchContent)
FetchContent_Declare(
yamlcpp
URL https://github.com/jbeder/yaml-cpp/archive/c2bec4c755c67ad86185a2a264996137904fb712.tar.gz
URL_HASH SHA256=faea1ffdbad81b958b3b45a63ba667f4db53a3fffb983ca5df4745cf90044797
)
FetchContent_MakeAvailable(yamlcpp)
else()
find_package(yaml-cpp CONFIG REQUIRED)
find_package(yaml-cpp CONFIG REQUIRED)
endif()

View File

@@ -4,15 +4,9 @@ This directory contains various ways to package Falco as a container and related
## Currently Supported Images
| Name | Directory | Description |
|---|---|---|
| [falcosecurity/falco:latest](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/falco | Falco (DEB built from git tag or from the master) with all the building toolchain. |
| [falcosecurity/falco-driver-loader:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:master](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader) | docker/driver-loader | `falco-driver-loader` as entrypoint with the building toolchain. |
| [falcosecurity/falco-no-driver:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver), [falcosecurity/falco-no-driver:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver),[falcosecurity/falco-no-driver:master](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver) | docker/no-driver | Falco (TGZ built from git tag or from the master) without the building toolchain. |
| [falcosecurity/falco-driver-loader-legacy:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader-legacy), [falcosecurity/falco-driver-loader-legacy:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader-legacy) | docker/driver-loader-legacy | `falco-driver-loader` as entrypoint with the legacy building toolchain. Recommended for kernels < 4.0 |
## Experimental Images
| Name | Directory | Description |
|---|---|---|
| [falcosecurity/falco-distroless:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-distroless), [falcosecurity/falco-distroless:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-distroless),[falcosecurity/falco-distroless:master](https://hub.docker.com/repository/docker/falcosecurity/falco-distroless) | docker/no-driver/Dockerfile.distroless | Falco without the building toolchain built from a distroless base image. This results in a smaller image that has less potentially vulnerable components. |
| Name | Directory | Description |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [falcosecurity/falco:latest](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/falco | Distroless image based on the latest released tar.gz of Falco. No tools are included in the image. |
| [falcosecurity/falco:latest-debian](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_-debian](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master-debian](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/falco-debian | Debian-based image. Include some tools (i.e. jq, curl). No driver-building toolchain support. |
| [falcosecurity/falco-driver-loader:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:master](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader) | docker/driver-loader | Based on falcosecurity/falco:x.y.z-debian (see above) plus the driver building toolchain support and falcoctl. This is intended to be used as an installer or an init container when modern eBPF cannot be used. |
| [falcosecurity/falco-driver-loader:latest-buster](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:_tag_-buster](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:master-debian](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader) | docker/driver-loader-buster | Similar to falcosecurity/falco-driver-loader (see above) but based on a legacy Debian image (i.e. buster ). Recommended only for old kernel versions. |

View File

@@ -13,7 +13,7 @@ services:
- /proc:/host/proc:ro
- /etc:/host/etc:ro
- ./config/http_output.yml:/etc/falco/config.d/http_output.yml
image: falcosecurity/falco-no-driver:latest
image: falcosecurity/falco:latest
sidekick:
container_name: falco-sidekick

View File

@@ -3,7 +3,7 @@ FROM debian:buster
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc --name NAME IMAGE"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader:latest-buster [driver] [options]"
ARG TARGETARCH
@@ -31,7 +31,6 @@ RUN apt-get update \
gcc \
jq \
libc6-dev \
libelf-dev \
libssl-dev \
llvm-7 \
netcat \
@@ -41,8 +40,8 @@ RUN apt-get update \
&& rm -rf /var/lib/apt/lists/*
RUN if [ "$TARGETARCH" = "amd64" ]; \
then apt-get install -y --no-install-recommends libmpx2; \
fi
then apt-get install -y --no-install-recommends libmpx2; \
fi
# gcc 6 is no longer included in debian stable, but we need it to
# build kernel modules on the default debian-based ami used by
@@ -51,7 +50,7 @@ RUN if [ "$TARGETARCH" = "amd64" ]; \
# or so.
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
curl -L -o cpp-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_${TARGETARCH}.deb \
curl -L -o cpp-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o gcc-6-base_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o gcc-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libasan3_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_${TARGETARCH}.deb \
@@ -60,8 +59,8 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGE
&& curl -L -o libmpfr4_3.1.3-2_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_${TARGETARCH}.deb \
&& curl -L -o libisl15_0.18-1_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-1_${TARGETARCH}.deb \
&& dpkg -i cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb; \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb \
&& rm -f cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb libcilkrts5_6.3.0-18_${TARGETARCH}.deb libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb
# gcc 5 is no longer included in debian stable, but we need it to
@@ -70,15 +69,15 @@ RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGE
# snapshots with the prefix https://snapshot.debian.org/archive/debian/20190122T000000Z.
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libmpx0_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
curl -L -o cpp-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_${TARGETARCH}.deb \
curl -L -o cpp-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o gcc-5-base_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o gcc-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libasan2_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libisl15_0.18-4_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-4_${TARGETARCH}.deb \
&& dpkg -i cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb; \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb \
&& rm -f cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb libmpx0_5.5.0-12_${TARGETARCH}.deb
# Since our base Debian image ships with GCC 7 which breaks older kernels, revert the
@@ -113,10 +112,10 @@ RUN rm -df /lib/modules \
# forcibly install binutils 2.30-22 instead.
RUN if [ "$TARGETARCH" = "amd64" ] ; then \
curl -L -o binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
else \
curl -L -o binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
fi
curl -L -o binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
else \
curl -L -o binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
fi
RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils_2.30-22_${TARGETARCH}.deb \
&& curl -L -o libbinutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/libbinutils_2.30-22_${TARGETARCH}.deb \

View File

@@ -21,7 +21,7 @@
print_usage() {
echo ""
echo "Usage:"
echo " docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader-legacy:latest [driver] [options]"
echo " docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader:latest-buster [driver] [options]"
echo ""
echo "Available drivers:"
echo " auto leverage automatic driver selection logic (default)"

View File

@@ -1,14 +1,46 @@
ARG FALCO_IMAGE_TAG=latest
FROM docker.io/falcosecurity/falco:${FALCO_IMAGE_TAG}
FROM docker.io/falcosecurity/falco:${FALCO_IMAGE_TAG}-debian
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro --name NAME IMAGE"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader:latest [driver] [options]"
ENV HOST_ROOT /host
ENV HOME /root
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bc \
bison \
ca-certificates \
clang \
curl \
dkms \
dwarves \
flex \
gcc \
gcc-11 \
gnupg2 \
jq \
libc6-dev \
libssl-dev \
llvm \
make \
netcat-openbsd \
patchelf \
xz-utils \
zstd \
&& rm -rf /var/lib/apt/lists/*
# Some base images have an empty /lib/modules by default
# If it's not empty, docker build will fail instead of
# silently overwriting the existing directory
RUN rm -df /lib/modules \
&& ln -s $HOST_ROOT/lib/modules /lib/modules
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -50,6 +50,7 @@ echo "* Setting up /usr/src links from host"
for i in "$HOST_ROOT/usr/src"/*
do
[[ -e $i ]] || continue
base=$(basename "$i")
ln -s "$i" "/usr/src/$base"
done

View File

@@ -0,0 +1,31 @@
FROM debian:12-slim
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco/docker/falco-debian"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /proc:/host/proc:ro -v /etc:/host/etc:ro falcosecurity/falco:latest-debian"
ARG FALCO_VERSION
ARG VERSION_BUCKET=deb
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
ENV HOST_ROOT /host
ENV HOME /root
RUN apt-get -y update && apt-get -y install ca-certificates curl jq ca-certificates gnupg2 \
&& apt clean -y && rm -rf /var/lib/apt/lists/*
WORKDIR /
RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& echo "deb https://download.falco.org/packages/${VERSION_BUCKET} stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list \
&& apt-get update -y \
&& if [ "$FALCO_VERSION" = "latest" ]; then FALCO_DRIVER_CHOICE=none apt-get install -y --no-install-recommends falco; else FALCO_DRIVER_CHOICE=none apt-get install -y --no-install-recommends falco=${FALCO_VERSION}; fi \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN sed -i -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' /etc/falco/falco.yaml
CMD ["/usr/bin/falco"]

View File

@@ -1,67 +1,36 @@
FROM debian:bookworm
FROM cgr.dev/chainguard/wolfi-base
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc --name NAME IMAGE"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /proc:/host/proc:ro -v /etc:/host/etc:ro falcosecurity/falco:latest"
# NOTE: for the "least privileged" use case, please refer to the official documentation
ARG TARGETARCH
ARG FALCO_VERSION=latest
ARG VERSION_BUCKET=deb
ENV VERSION_BUCKET=${VERSION_BUCKET}
ARG FALCO_VERSION
ARG VERSION_BUCKET=bin
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
ENV HOST_ROOT /host
ENV HOME /root
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
RUN apk update && apk add curl ca-certificates jq libstdc++
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bc \
bison \
ca-certificates \
clang \
curl \
dkms \
dwarves \
flex \
gcc \
gcc-11 \
gnupg2 \
jq \
libc6-dev \
libelf-dev \
libssl-dev \
llvm \
make \
netcat-openbsd \
patchelf \
xz-utils \
zstd \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /
RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& echo "deb https://download.falco.org/packages/${VERSION_BUCKET} stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list \
&& apt-get update -y \
&& if [ "$FALCO_VERSION" = "latest" ]; then FALCO_DRIVER_CHOICE=none apt-get install -y --no-install-recommends falco; else FALCO_DRIVER_CHOICE=none apt-get install -y --no-install-recommends falco=${FALCO_VERSION}; fi \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
RUN FALCO_VERSION_URLENCODED=$(echo -n ${FALCO_VERSION}|jq -sRr @uri) && \
curl -L -o falco.tar.gz \
https://download.falco.org/packages/${VERSION_BUCKET}/$(uname -m)/falco-${FALCO_VERSION_URLENCODED}-$(uname -m).tar.gz && \
tar -xvf falco.tar.gz && \
rm -f falco.tar.gz && \
mv falco-${FALCO_VERSION}-$(uname -m) falco && \
rm -rf /falco/usr/src/falco-* && \
cp -r /falco/* / && \
rm -rf /falco
# Change the falco config within the container to enable ISO 8601
# output.
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /etc/falco/falco.yaml > /etc/falco/falco.yaml.new \
&& mv /etc/falco/falco.yaml.new /etc/falco/falco.yaml
RUN sed -i -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' /etc/falco/falco.yaml
# Some base images have an empty /lib/modules by default
# If it's not empty, docker build will fail instead of
# silently overwriting the existing directory
RUN rm -df /lib/modules \
&& ln -s $HOST_ROOT/lib/modules /lib/modules
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
# Falcoctl is not included here.
RUN rm -rf /usr/bin/falcoctl /etc/falcoctl/
CMD ["/usr/bin/falco"]

View File

@@ -1,136 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 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.
#
print_usage() {
echo ""
echo "Usage:"
echo " docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro -e 'FALCO_DRIVER_LOADER_OPTIONS=[driver] [options]' falcosecurity/falco:latest"
echo ""
echo "Available FALCO_DRIVER_LOADER_OPTIONS drivers:"
echo " auto leverage automatic driver selection logic (default)"
echo " modern_ebpf modern eBPF CORE probe"
echo " kmod kernel module"
echo " ebpf eBPF probe"
echo ""
echo "FALCO_DRIVER_LOADER_OPTIONS options:"
echo " --help show this help message"
echo " --clean try to remove an already present driver installation"
echo " --compile try to compile the driver locally (default true)"
echo " --download try to download a prebuilt driver (default true)"
echo " --http-insecure enable insecure downloads"
echo " --print-env skip execution and print env variables for other tools to consume"
echo ""
echo "Environment variables:"
echo " FALCOCTL_DRIVER_REPOS specify different URL(s) where to look for prebuilt Falco drivers (comma separated)"
echo " FALCOCTL_DRIVER_NAME specify a different name for the driver"
echo " FALCOCTL_DRIVER_HTTP_HEADERS specify comma separated list of http headers for driver download (e.g. 'x-emc-namespace: default,Proxy-Authenticate: Basic')"
echo ""
}
# Set the SKIP_DRIVER_LOADER variable to skip loading the driver
if [[ -z "${SKIP_DRIVER_LOADER}" ]]; then
echo "* Setting up /usr/src links from host"
for i in "$HOST_ROOT/usr/src"/*
do
base=$(basename "$i")
ln -s "$i" "/usr/src/$base"
done
# convert the optional space-separated env variable FALCO_DRIVER_LOADER_OPTIONS to array, prevent
# shell expansion and use it as argument list for falcoctl
read -a falco_driver_loader_option_arr <<< $FALCO_DRIVER_LOADER_OPTIONS
ENABLE_COMPILE="false"
ENABLE_DOWNLOAD="false"
HTTP_INSECURE="false"
driver=
has_opts=
for opt in "${falco_driver_loader_option_arr[@]}"
do
case "$opt" in
auto|kmod|ebpf|modern_ebpf)
if [ -n "$driver" ]; then
>&2 echo "Only one driver per invocation"
print_usage
exit 1
else
driver=$opt
fi
;;
-h|--help)
print_usage
exit 0
;;
--clean)
/usr/bin/falcoctl driver cleanup
exit 0
;;
--compile)
ENABLE_COMPILE="true"
has_opts="true"
;;
--download)
ENABLE_DOWNLOAD="true"
has_opts="true"
;;
--http-insecure)
HTTP_INSECURE="true"
;;
--print-env)
/usr/bin/falcoctl driver printenv
exit 0
;;
--*)
>&2 echo "Unknown option: $opt"
print_usage
exit 1
;;
*)
>&2 echo "Unknown driver: $opt"
print_usage
exit 1
;;
esac
done
# No opts passed, enable both compile and download
if [ -z "$has_opts" ]; then
ENABLE_COMPILE="true"
ENABLE_DOWNLOAD="true"
fi
# Default value: auto
if [ -z "$driver" ]; then
driver="auto"
fi
if [ "$driver" != "auto" ]; then
/usr/bin/falcoctl driver config --type $driver
else
# Needed because we need to configure Falco to start with correct driver
/usr/bin/falcoctl driver config --type modern_ebpf --type kmod --type ebpf
fi
/usr/bin/falcoctl driver install --compile=$ENABLE_COMPILE --download=$ENABLE_DOWNLOAD --http-insecure=$HTTP_INSECURE --http-headers="$FALCOCTL_DRIVER_HTTP_HEADERS"
fi
exec "$@"

View File

@@ -1,39 +0,0 @@
FROM debian:12 as builder
ARG FALCO_VERSION
ARG VERSION_BUCKET=bin
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
RUN apt-get -y update && apt-get -y install gridsite-clients curl ca-certificates
WORKDIR /
RUN curl -L -o falco.tar.gz \
https://download.falco.org/packages/${VERSION_BUCKET}/$(uname -m)/falco-$(urlencode ${FALCO_VERSION})-$(uname -m).tar.gz && \
tar -xvf falco.tar.gz && \
rm -f falco.tar.gz && \
mv falco-${FALCO_VERSION}-$(uname -m) falco && \
rm -rf /falco/usr/src/falco-*
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/etc/falco/falco.yaml > /falco/etc/falco/falco.yaml.new \
&& mv /falco/etc/falco/falco.yaml.new /falco/etc/falco/falco.yaml
FROM debian:12-slim
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro --name NAME IMAGE"
# NOTE: for the "least privileged" use case, please refer to the official documentation
RUN apt-get -y update && apt-get -y install ca-certificates curl jq libelf1 \
&& apt clean -y && rm -rf /var/lib/apt/lists/*
ENV HOST_ROOT /host
ENV HOME /root
COPY --from=builder /falco /
CMD ["/usr/bin/falco", "-o", "time_format_iso_8601=true"]

View File

@@ -1,40 +0,0 @@
FROM cgr.dev/chainguard/wolfi-base as builder
ARG FALCO_VERSION
ARG VERSION_BUCKET=bin
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
RUN apk update && apk add build-base gcc curl ca-certificates jq elfutils
WORKDIR /
RUN FALCO_VERSION_URLENCODED=$(echo -n ${FALCO_VERSION}|jq -sRr @uri) && \
curl -L -o falco.tar.gz \
https://download.falco.org/packages/${VERSION_BUCKET}/$(uname -m)/falco-${FALCO_VERSION_URLENCODED}-$(uname -m).tar.gz && \
tar -xvf falco.tar.gz && \
rm -f falco.tar.gz && \
mv falco-${FALCO_VERSION}-$(uname -m) falco && \
rm -rf /falco/usr/src/falco-*
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/etc/falco/falco.yaml > /falco/etc/falco/falco.yaml.new \
&& mv /falco/etc/falco/falco.yaml.new /falco/etc/falco/falco.yaml
FROM cgr.dev/chainguard/wolfi-base
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro --name NAME IMAGE"
# NOTE: for the "least privileged" use case, please refer to the official documentation
RUN apk update && apk add libelf libstdc++
ENV HOST_ROOT /host
ENV HOME /root
USER root
COPY --from=builder /falco /
CMD ["/usr/bin/falco", "-o", "time_format_iso_8601=true"]

View File

@@ -480,6 +480,14 @@ plugins:
- name: json
library_path: libjson.so
# [Sandbox] `plugins_hostinfo`
#
# Uncomment to disable host info support for source plugins
# that DO NOT generate raw events from the libscap event table
# or for plugins that DO NOT parse raw events generated by drivers,
# effectively dropping the `proc-fs` hostPath volume requirement for them:
# https://github.com/falcosecurity/charts/blob/bd57711e7c8e00919ea288716e0d9d5fdad8867e/charts/falco/templates/pod-template.tpl#L302-L304
# plugins_hostinfo: false
##########################
# Falco outputs settings #
@@ -492,6 +500,13 @@ plugins:
# the /etc/localtime configuration.
time_format_iso_8601: false
# [Incubating] `buffer_format_base64`
#
# When enabled, Falco will output data buffer with base64 encoding. This is useful
# for encoding binary data that needs to be used over media designed to consume
# this format.
buffer_format_base64: false
# [Stable] `priority`
#
# Any rule with a priority level more severe than or equal to the specified
@@ -538,9 +553,14 @@ json_include_tags_property: true
# [Stable] `buffered_outputs`
#
# Enabling buffering for the output queue can offer performance optimization,
# efficient resource usage, and smoother data flow, resulting in a more reliable
# output mechanism. By default, buffering is disabled (false).
# Global buffering option for output channels. When disabled, the output channel
# that supports buffering flushes the output buffer on every alert. This can lead to
# increased CPU usage but is useful when piping outputs to another process or script.
# Buffering is currently supported by `file_output`, `program_output`, and `std_output`.
# Some output channels may implement buffering strategies you cannot control.
# Additionally, this setting is separate from the `output_queue` option. The output queue
# sits between the rule engine and the output channels, while output buffering occurs
# afterward once the specific channel implementation outputs the formatted message.
buffered_outputs: false
# [Incubating] `rule_matching`
@@ -568,7 +588,7 @@ rule_matching: first
#
# Falco utilizes tbb::concurrent_bounded_queue for handling outputs, and this parameter
# allows you to customize the queue capacity. Please refer to the official documentation:
# https://oneapi-src.github.io/oneTBB/main/tbb_userguide/Concurrent_Queue_Classes.html.
# https://uxlfoundation.github.io/oneTBB/main/tbb_userguide/Concurrent_Queue_Classes.html.
# On a healthy system with optimized Falco rules, the queue should not fill up.
# If it does, it is most likely happening due to the entire event flow being too slow,
# indicating that the server is under heavy load.
@@ -611,6 +631,7 @@ outputs_queue:
# affect the regular Falco message in any way. These can be specified as a
# custom name with a custom format or as any supported field
# (see: https://falco.org/docs/reference/rules/supported-fields/)
# `suggested_output`: enable the use of extractor plugins suggested fields for the matching source output.
#
# Example:
#
@@ -627,6 +648,13 @@ outputs_queue:
# property you will find three new ones: "evt.cpu", "home_directory" which will contain the value of the
# environment variable $HOME, and "evt.hostname" which will contain the hostname.
# By default, we enable suggested_output for any source.
# This means that any extractor plugin that indicates some of its fields
# as suggested output formats, will see these fields in the output
# in the form "foo_bar=$foo.bar"
append_output:
- suggested_output: true
##########################
# Falco outputs channels #
@@ -1096,6 +1124,8 @@ syscall_event_drops:
# there will be no metrics available. In other words, there are no default or
# generic plugin metrics at this time. This may be subject to change.
#
# `jemalloc_stats_enabled`: Falco can now expose jemalloc related stats.
#
# If metrics are enabled, the web server can be configured to activate the
# corresponding Prometheus endpoint using `webserver.prometheus_metrics_enabled`.
# Prometheus output can be used in combination with the other output options.
@@ -1117,6 +1147,7 @@ metrics:
kernel_event_counters_per_cpu_enabled: false
libbpf_stats_enabled: true
plugins_metrics_enabled: true
jemalloc_stats_enabled: false
convert_memory_to_mb: true
include_empty_values: false
@@ -1155,6 +1186,14 @@ metrics:
# Falco, the `base_syscalls` option allows for finer end-user control of
# syscalls traced by Falco.
#
# --- [base_syscalls.all]
#
# `base_syscalls.all` enables monitoring of all events supported by Falco and
# defined in rules and configs.
# By default some events, such as `write`, are ignored (run `falco -i` to get
# the full list) unless base_syscalls.all is true.
# This option may negatively impact performance.
#
# --- [base_syscalls.custom_set]
#
# CAUTION: Misconfiguration of this setting may result in incomplete Falco event
@@ -1259,8 +1298,15 @@ base_syscalls:
# `metrics.state_counters_enabled` to measure how the internal state handling is performing,
# and the fields called `n_drops_full_threadtable` or `n_store_evts_drops` will inform you
# if you should increase this value for optimal performance.
#
# `snaplen`
#
# Set how many bytes are collected of each I/O buffer for 'syscall' events.
# Use this option with caution since it can have a strong performance impact.
#
falco_libs:
thread_table_size: 262144
snaplen: 80
# [Incubating] `container_engines`
#
@@ -1284,8 +1330,6 @@ falco_libs:
# - `container_engines.cri.disable_async`: Since API lookups may not always be quick or
# perfect, resulting in empty fields for container metadata, you can use this option option
# to disable asynchronous fetching. Note that missing fields may still occasionally occur.
#
# The equivalent (stable) CLI args are `--cri` or `--disable-cri-async`.
container_engines:
docker:

View File

@@ -2,35 +2,44 @@
#
# Copyright (C) 2023 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
#
# 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
#
# 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.
# 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.
#
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
# Systemd
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/scripts/systemd)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-kmod-inject.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-kmod.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-bpf.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-modern-bpf.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falco-custom.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file("${PROJECT_SOURCE_DIR}/scripts/systemd/falcoctl-artifact-follow.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY)
configure_file(
"${PROJECT_SOURCE_DIR}/scripts/systemd/falco-kmod-inject.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY
)
configure_file(
"${PROJECT_SOURCE_DIR}/scripts/systemd/falco-kmod.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY
)
configure_file(
"${PROJECT_SOURCE_DIR}/scripts/systemd/falco-bpf.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY
)
configure_file(
"${PROJECT_SOURCE_DIR}/scripts/systemd/falco-modern-bpf.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY
)
configure_file(
"${PROJECT_SOURCE_DIR}/scripts/systemd/falco-custom.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY
)
configure_file(
"${PROJECT_SOURCE_DIR}/scripts/systemd/falcoctl-artifact-follow.service"
"${PROJECT_BINARY_DIR}/scripts/systemd" COPYONLY
)
# Debian
configure_file(debian/postinst.in debian/postinst COPYONLY)
@@ -44,21 +53,32 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
endif()
# Install Falcoctl config file
if (NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN AND NOT MUSL_OPTIMIZED_BUILD)
if(NOT WIN32
AND NOT APPLE
AND NOT EMSCRIPTEN
AND NOT MUSL_OPTIMIZED_BUILD
)
if(NOT DEFINED FALCOCTL_ETC_DIR)
set(FALCOCTL_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falcoctl")
endif()
set(FALCOCTL_DRIVER_TYPES_LIST "")
if (BUILD_FALCO_MODERN_BPF)
endif()
set(FALCOCTL_DRIVER_TYPES_LIST "")
if(BUILD_FALCO_MODERN_BPF)
list(APPEND FALCOCTL_DRIVER_TYPES_LIST "modern_ebpf")
endif()
if (BUILD_DRIVER)
if(BUILD_DRIVER)
list(APPEND FALCOCTL_DRIVER_TYPES_LIST "kmod")
endif()
if (BUILD_BPF)
if(BUILD_BPF)
list(APPEND FALCOCTL_DRIVER_TYPES_LIST "ebpf")
endif()
string(REPLACE ";" ", " FALCOCTL_DRIVER_TYPES "${FALCOCTL_DRIVER_TYPES_LIST}")
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/falcoctl/falcoctl.yaml.in ${PROJECT_BINARY_DIR}/scripts/falcoctl/falcoctl.yaml)
install(FILES ${PROJECT_BINARY_DIR}/scripts/falcoctl/falcoctl.yaml DESTINATION "${FALCOCTL_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/falcoctl/falcoctl.yaml.in
${PROJECT_BINARY_DIR}/scripts/falcoctl/falcoctl.yaml
)
install(
FILES ${PROJECT_BINARY_DIR}/scripts/falcoctl/falcoctl.yaml
DESTINATION "${FALCOCTL_ETC_DIR}"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
endif()

View File

@@ -24,3 +24,4 @@ StandardOutput=null
[Install]
WantedBy=multi-user.target
Alias=falco.service

View File

@@ -24,3 +24,4 @@ StandardOutput=null
[Install]
WantedBy=multi-user.target
Alias=falco.service

View File

@@ -24,3 +24,4 @@ StandardOutput=null
[Install]
WantedBy=multi-user.target
Alias=falco.service

View File

@@ -2,14 +2,15 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
#
message(STATUS "Falco unit tests build enabled")
@@ -17,72 +18,72 @@ message(STATUS "Falco unit tests build enabled")
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.14.0
)
FetchContent_MakeAvailable(googletest)
# Create a libscap_test_var.h file with some variables used by our tests
# for example the kmod path or the bpf path.
configure_file (
${CMAKE_CURRENT_SOURCE_DIR}/falco_test_var.h.in
${CMAKE_CURRENT_BINARY_DIR}/falco_test_var.h
# Create a libscap_test_var.h file with some variables used by our tests for example the kmod path
# or the bpf path.
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/falco_test_var.h.in ${CMAKE_CURRENT_BINARY_DIR}/falco_test_var.h
)
add_executable(falco_unit_tests
test_falco_engine.cpp
engine/test_add_source.cpp
engine/test_alt_rule_loader.cpp
engine/test_enable_rule.cpp
engine/test_extra_output.cpp
engine/test_falco_utils.cpp
engine/test_filter_details_resolver.cpp
engine/test_filter_macro_resolver.cpp
engine/test_filter_warning_resolver.cpp
engine/test_plugin_requirements.cpp
engine/test_rule_loader.cpp
engine/test_rulesets.cpp
falco/test_configuration.cpp
falco/test_configuration_rule_selection.cpp
falco/test_configuration_config_files.cpp
falco/test_configuration_env_vars.cpp
falco/test_configuration_output_options.cpp
falco/test_configuration_schema.cpp
falco/app/actions/test_select_event_sources.cpp
falco/app/actions/test_load_config.cpp
add_executable(
falco_unit_tests
test_falco_engine.cpp
engine/test_add_source.cpp
engine/test_alt_rule_loader.cpp
engine/test_enable_rule.cpp
engine/test_extra_output.cpp
engine/test_falco_utils.cpp
engine/test_filter_details_resolver.cpp
engine/test_filter_macro_resolver.cpp
engine/test_filter_warning_resolver.cpp
engine/test_plugin_requirements.cpp
engine/test_rule_loader.cpp
engine/test_rulesets.cpp
falco/test_configuration.cpp
falco/test_configuration_rule_selection.cpp
falco/test_configuration_config_files.cpp
falco/test_configuration_env_vars.cpp
falco/test_configuration_output_options.cpp
falco/test_configuration_schema.cpp
falco/app/actions/test_select_event_sources.cpp
falco/app/actions/test_load_config.cpp
)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_sources(falco_unit_tests
PRIVATE
falco/test_atomic_signal_handler.cpp
falco/app/actions/test_configure_interesting_sets.cpp
falco/app/actions/test_configure_syscall_buffer_num.cpp
)
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
target_sources(
falco_unit_tests
PRIVATE falco/test_atomic_signal_handler.cpp
falco/app/actions/test_configure_interesting_sets.cpp
falco/app/actions/test_configure_syscall_buffer_num.cpp
)
endif()
target_include_directories(falco_unit_tests
PRIVATE
${CMAKE_SOURCE_DIR}/userspace
${CMAKE_BINARY_DIR}/userspace/falco # we need it to include indirectly `config_falco.h` file
${CMAKE_SOURCE_DIR}/userspace/engine # we need it to include indirectly `falco_common.h` file
${CMAKE_CURRENT_BINARY_DIR} # we need it to include `falco_test_var.h`
target_include_directories(
falco_unit_tests
PRIVATE ${CMAKE_SOURCE_DIR}/userspace
${CMAKE_BINARY_DIR}/userspace/falco # we need it to include indirectly `config_falco.h`
# file
${CMAKE_SOURCE_DIR}/userspace/engine # we need it to include indirectly `falco_common.h`
# file
${CMAKE_CURRENT_BINARY_DIR} # we need it to include `falco_test_var.h`
)
get_target_property(FALCO_APPLICATION_LIBRARIES falco_application LINK_LIBRARIES)
target_link_libraries(falco_unit_tests
falco_application
GTest::gtest
GTest::gtest_main
${FALCO_APPLICATION_LIBRARIES}
target_link_libraries(
falco_unit_tests falco_application GTest::gtest GTest::gtest_main
${FALCO_APPLICATION_LIBRARIES}
)
if (EMSCRIPTEN)
if(EMSCRIPTEN)
target_compile_options(falco_unit_tests PRIVATE "-sDISABLE_EXCEPTION_CATCHING=0")
target_link_options(falco_unit_tests PRIVATE "-sDISABLE_EXCEPTION_CATCHING=0")
target_link_options(falco_unit_tests PRIVATE "-sALLOW_MEMORY_GROWTH=1")
target_link_options(falco_unit_tests PRIVATE "-sALLOW_MEMORY_GROWTH=1")
target_link_options(falco_unit_tests PRIVATE "-sEXPORTED_FUNCTIONS=['_main','_htons','_ntohs']")
endif()

View File

@@ -26,36 +26,30 @@ static std::string syscall_source_name = "syscall";
// for the underlying ruleset. This allows testing of
// ruleset_for_source
namespace
{
class test_ruleset_factory : public evttype_index_ruleset_factory
{
namespace {
class test_ruleset_factory : public evttype_index_ruleset_factory {
public:
explicit test_ruleset_factory(std::shared_ptr<sinsp_filter_factory> factory):
evttype_index_ruleset_factory(factory)
{
evttype_index_ruleset_factory(factory) {
ruleset = evttype_index_ruleset_factory::new_ruleset();
}
virtual ~test_ruleset_factory() = default;
inline std::shared_ptr<filter_ruleset> new_ruleset() override
{
return ruleset;
}
inline std::shared_ptr<filter_ruleset> new_ruleset() override { return ruleset; }
std::shared_ptr<filter_ruleset> ruleset;
};
}; // namespace
}; // namespace
TEST(AddSource, basic)
{
TEST(AddSource, basic) {
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
auto filter_factory = std::make_shared<sinsp_filter_factory>(&inspector, filterchecks);
auto formatter_factory = std::make_shared<sinsp_evt_formatter_factory>(&inspector, filterchecks);
auto formatter_factory =
std::make_shared<sinsp_evt_formatter_factory>(&inspector, filterchecks);
auto ruleset_factory = std::make_shared<test_ruleset_factory>(filter_factory);
falco_source syscall_source;
@@ -66,9 +60,9 @@ TEST(AddSource, basic)
syscall_source.formatter_factory = formatter_factory;
size_t source_idx = engine.add_source(syscall_source_name,
filter_factory,
formatter_factory,
ruleset_factory);
filter_factory,
formatter_factory,
ruleset_factory);
ASSERT_TRUE(engine.is_source_valid(syscall_source_name));

View File

@@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include <memory>
#include <string>
#include <gtest/gtest.h>
@@ -32,42 +33,38 @@ limitations under the License.
#include "rule_loader_collector.h"
#include "rule_loader_compiler.h"
namespace
{
namespace {
struct test_object_info
{
struct test_object_info {
std::string name;
std::string property;
};
struct test_compile_output : public rule_loader::compile_output
{
struct test_compile_output : public rule_loader::compile_output {
test_compile_output() = default;
~test_compile_output() = default;
virtual ~test_compile_output() = default;
virtual std::unique_ptr<compile_output> clone() const override {
return std::make_unique<test_compile_output>(*this);
}
std::set<std::string> defined_test_properties;
};
class test_compiler : public rule_loader::compiler
{
class test_compiler : public rule_loader::compiler {
public:
test_compiler() = default;
virtual ~test_compiler() = default;
std::unique_ptr<rule_loader::compile_output> new_compile_output() override
{
std::unique_ptr<rule_loader::compile_output> new_compile_output() override {
return std::make_unique<test_compile_output>();
}
void compile(
rule_loader::configuration& cfg,
const rule_loader::collector& col,
rule_loader::compile_output& out) const override;
void compile(rule_loader::configuration& cfg,
const rule_loader::collector& col,
rule_loader::compile_output& out) const override;
};
class test_collector : public rule_loader::collector
{
class test_collector : public rule_loader::collector {
public:
test_collector() = default;
virtual ~test_collector() = default;
@@ -75,32 +72,27 @@ public:
indexed_vector<test_object_info> test_object_infos;
};
class test_reader : public rule_loader::reader
{
class test_reader : public rule_loader::reader {
public:
test_reader() = default;
virtual ~test_reader() = default;
protected:
rule_loader::context create_context(const YAML::Node& item,
const rule_loader::context& parent)
{
const rule_loader::context& parent) {
return rule_loader::context(item,
rule_loader::context::EXTENSION_ITEM,
"test object",
parent);
rule_loader::context::EXTENSION_ITEM,
"test object",
parent);
};
void read_item(rule_loader::configuration& cfg,
rule_loader::collector& collector,
const YAML::Node& item,
const rule_loader::context& parent) override
{
test_collector& test_col =
dynamic_cast<test_collector&>(collector);
rule_loader::collector& collector,
const YAML::Node& item,
const rule_loader::context& parent) override {
test_collector& test_col = dynamic_cast<test_collector&>(collector);
if(item["test_object"].IsDefined())
{
if(item["test_object"].IsDefined()) {
rule_loader::context tmp = create_context(item, parent);
test_object_info obj;
std::string name;
@@ -113,37 +105,29 @@ protected:
obj.property = property;
test_col.test_object_infos.insert(obj, obj.name);
}
else
{
} else {
rule_loader::reader::read_item(cfg, collector, item, parent);
}
};
};
class test_ruleset : public evttype_index_ruleset
{
class test_ruleset : public evttype_index_ruleset {
public:
explicit test_ruleset(std::shared_ptr<sinsp_filter_factory> factory):
evttype_index_ruleset(factory){};
evttype_index_ruleset(factory) {};
virtual ~test_ruleset() = default;
void add_compile_output(
const rule_loader::compile_output& compile_output,
falco_common::priority_type min_priority,
const std::string& source)
{
evttype_index_ruleset::add_compile_output(compile_output,
min_priority,
source);
void add_compile_output(const rule_loader::compile_output& compile_output,
falco_common::priority_type min_priority,
const std::string& source) {
evttype_index_ruleset::add_compile_output(compile_output, min_priority, source);
std::shared_ptr<filter_ruleset> ruleset;
get_engine_state().get_ruleset(source, ruleset);
EXPECT_EQ(this, ruleset.get());
const test_compile_output& test_output =
dynamic_cast<const test_compile_output&>(compile_output);
dynamic_cast<const test_compile_output&>(compile_output);
defined_properties = test_output.defined_test_properties;
};
@@ -151,40 +135,31 @@ public:
std::set<std::string> defined_properties;
};
class test_ruleset_factory : public filter_ruleset_factory
{
class test_ruleset_factory : public filter_ruleset_factory {
public:
explicit test_ruleset_factory(std::shared_ptr<sinsp_filter_factory> factory):
m_filter_factory(factory)
{
}
m_filter_factory(factory) {}
virtual ~test_ruleset_factory() = default;
inline std::shared_ptr<filter_ruleset> new_ruleset() override
{
inline std::shared_ptr<filter_ruleset> new_ruleset() override {
return std::make_shared<test_ruleset>(m_filter_factory);
}
std::shared_ptr<sinsp_filter_factory> m_filter_factory;
};
}; // namespace
}; // namespace
void test_compiler::compile(
rule_loader::configuration& cfg,
const rule_loader::collector& col,
rule_loader::compile_output& out) const
{
void test_compiler::compile(rule_loader::configuration& cfg,
const rule_loader::collector& col,
rule_loader::compile_output& out) const {
rule_loader::compiler::compile(cfg, col, out);
const test_collector& test_col =
dynamic_cast<const test_collector&>(col);
const test_collector& test_col = dynamic_cast<const test_collector&>(col);
test_compile_output& test_output =
dynamic_cast<test_compile_output&>(out);
test_compile_output& test_output = dynamic_cast<test_compile_output&>(out);
for(auto& test_obj : test_col.test_object_infos)
{
for(auto& test_obj : test_col.test_object_infos) {
test_output.defined_test_properties.insert(test_obj.property);
}
}
@@ -230,12 +205,13 @@ static std::string content = R"END(
static std::string syscall_source_name = "syscall";
static std::shared_ptr<rule_loader::configuration> create_configuration(sinsp& inspector,
sinsp_filter_check_list& filterchecks,
indexed_vector<falco_source>& sources)
{
static std::shared_ptr<rule_loader::configuration> create_configuration(
sinsp& inspector,
sinsp_filter_check_list& filterchecks,
indexed_vector<falco_source>& sources) {
auto filter_factory = std::make_shared<sinsp_filter_factory>(&inspector, filterchecks);
auto formatter_factory = std::make_shared<sinsp_evt_formatter_factory>(&inspector, filterchecks);
auto formatter_factory =
std::make_shared<sinsp_evt_formatter_factory>(&inspector, filterchecks);
auto ruleset_factory = std::make_shared<evttype_index_ruleset_factory>(filter_factory);
falco_source syscall_source;
@@ -247,17 +223,15 @@ static std::shared_ptr<rule_loader::configuration> create_configuration(sinsp& i
sources.insert(syscall_source, syscall_source_name);
return std::make_shared<rule_loader::configuration>(content,
sources,
"test configuration");
return std::make_shared<rule_loader::configuration>(content, sources, "test configuration");
}
static void load_rules(sinsp& inspector,
sinsp_filter_check_list& filterchecks,
std::unique_ptr<rule_loader::compile_output>& compile_output,
indexed_vector<falco_source>& sources)
{
std::shared_ptr<rule_loader::configuration> cfg = create_configuration(inspector, filterchecks, sources);
sinsp_filter_check_list& filterchecks,
std::unique_ptr<rule_loader::compile_output>& compile_output,
indexed_vector<falco_source>& sources) {
std::shared_ptr<rule_loader::configuration> cfg =
create_configuration(inspector, filterchecks, sources);
rule_loader::reader reader;
rule_loader::collector collector;
@@ -270,8 +244,7 @@ static void load_rules(sinsp& inspector,
compiler.compile(*cfg, collector, *compile_output);
}
TEST(engine_loader_alt_loader, load_rules)
{
TEST(engine_loader_alt_loader, load_rules) {
sinsp inspector;
sinsp_filter_check_list filterchecks;
std::unique_ptr<rule_loader::compile_output> compile_output;
@@ -292,8 +265,7 @@ TEST(engine_loader_alt_loader, load_rules)
EXPECT_TRUE(compile_output->rules.at("test debug rule") != nullptr);
}
TEST(engine_loader_alt_loader, pass_compile_output_to_ruleset)
{
TEST(engine_loader_alt_loader, pass_compile_output_to_ruleset) {
sinsp inspector;
sinsp_filter_check_list filterchecks;
std::unique_ptr<rule_loader::compile_output> compile_output;
@@ -304,8 +276,8 @@ TEST(engine_loader_alt_loader, pass_compile_output_to_ruleset)
std::shared_ptr<filter_ruleset> ruleset = sources.at(syscall_source_name)->ruleset;
ruleset->add_compile_output(*compile_output,
falco_common::PRIORITY_INFORMATIONAL,
syscall_source_name);
falco_common::PRIORITY_INFORMATIONAL,
syscall_source_name);
// Enable all rules for a ruleset id. Because the compile
// output contained one rule with priority >= INFO, that rule
@@ -316,14 +288,14 @@ TEST(engine_loader_alt_loader, pass_compile_output_to_ruleset)
EXPECT_EQ(ruleset->enabled_count(ruleset_id), 1);
}
TEST(engine_loader_alt_loader, falco_engine_alternate_loader)
{
TEST(engine_loader_alt_loader, falco_engine_alternate_loader) {
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
auto filter_factory = std::make_shared<sinsp_filter_factory>(&inspector, filterchecks);
auto formatter_factory = std::make_shared<sinsp_evt_formatter_factory>(&inspector, filterchecks);
auto formatter_factory =
std::make_shared<sinsp_evt_formatter_factory>(&inspector, filterchecks);
auto ruleset_factory = std::make_shared<test_ruleset_factory>(filter_factory);
engine.add_source(syscall_source_name, filter_factory, formatter_factory, ruleset_factory);
@@ -345,9 +317,40 @@ TEST(engine_loader_alt_loader, falco_engine_alternate_loader)
EXPECT_EQ(collector->test_object_infos.size(), 2);
std::shared_ptr<filter_ruleset> ruleset = engine.ruleset_for_source(syscall_source_name);
std::set<std::string>& defined_properties = std::dynamic_pointer_cast<test_ruleset>(ruleset)->defined_properties;
std::set<std::string>& defined_properties =
std::dynamic_pointer_cast<test_ruleset>(ruleset)->defined_properties;
EXPECT_TRUE(defined_properties.find("my-value") != defined_properties.end());
EXPECT_TRUE(defined_properties.find("other-value") != defined_properties.end());
EXPECT_TRUE(defined_properties.find("not-exists-value") == defined_properties.end());
};
TEST(engine_loader_alt_loader, clone_compile_output) {
sinsp inspector;
sinsp_filter_check_list filterchecks;
indexed_vector<falco_source> sources;
std::shared_ptr<rule_loader::configuration> cfg =
create_configuration(inspector, filterchecks, sources);
test_reader reader;
test_collector collector;
test_compiler compiler;
EXPECT_TRUE(reader.read(*cfg, collector));
std::unique_ptr<rule_loader::compile_output> compile_output = compiler.new_compile_output();
compiler.compile(*cfg, collector, *compile_output);
const test_compile_output& original_ref =
dynamic_cast<const test_compile_output&>(*(compile_output.get()));
std::unique_ptr<rule_loader::compile_output> copy = compile_output->clone();
const test_compile_output& copy_ref = dynamic_cast<const test_compile_output&>(*(copy.get()));
EXPECT_EQ(copy_ref.lists, original_ref.lists);
EXPECT_EQ(copy_ref.macros, original_ref.macros);
EXPECT_EQ(copy_ref.rules, original_ref.rules);
EXPECT_EQ(copy_ref.defined_test_properties, original_ref.defined_test_properties);
}

View File

@@ -72,8 +72,6 @@ static std::string multi_rule = R"END(
tags: [exec]
)END";
// This must be kept in line with the (private) falco_engine::s_default_ruleset
static const std::string default_ruleset = "falco-default-ruleset";
@@ -82,8 +80,7 @@ static const std::string ruleset_2 = "ruleset-2";
static const std::string ruleset_3 = "ruleset-3";
static const std::string ruleset_4 = "ruleset-4";
TEST_F(test_falco_engine, enable_rule_name)
{
TEST_F(test_falco_engine, enable_rule_name) {
load_rules(single_rule, "single_rule.yaml");
// No rules should be enabled yet for any custom rulesets
@@ -119,8 +116,7 @@ TEST_F(test_falco_engine, enable_rule_name)
EXPECT_EQ(2, m_engine->num_rules_for_ruleset(ruleset_3));
}
TEST_F(test_falco_engine, enable_rule_tags)
{
TEST_F(test_falco_engine, enable_rule_tags) {
std::set<std::string> process_tags = {"process"};
load_rules(single_rule, "single_rule.yaml");
@@ -147,8 +143,7 @@ TEST_F(test_falco_engine, enable_rule_tags)
EXPECT_EQ(0, m_engine->num_rules_for_ruleset(ruleset_2));
}
TEST_F(test_falco_engine, enable_disabled_rule_by_tag)
{
TEST_F(test_falco_engine, enable_disabled_rule_by_tag) {
std::set<std::string> exec_process_tags = {"exec process"};
load_rules(single_rule, "single_rule.yaml");
@@ -163,8 +158,7 @@ TEST_F(test_falco_engine, enable_disabled_rule_by_tag)
EXPECT_EQ(2, m_engine->num_rules_for_ruleset(default_ruleset));
}
TEST_F(test_falco_engine, enable_rule_id)
{
TEST_F(test_falco_engine, enable_rule_id) {
uint16_t ruleset_1_id;
uint16_t ruleset_2_id;
uint16_t ruleset_3_id;
@@ -204,8 +198,7 @@ TEST_F(test_falco_engine, enable_rule_id)
EXPECT_EQ(2, m_engine->num_rules_for_ruleset(ruleset_3));
}
TEST_F(test_falco_engine, enable_rule_name_exact)
{
TEST_F(test_falco_engine, enable_rule_name_exact) {
load_rules(single_rule, "single_rule.yaml");
EXPECT_EQ(1, m_engine->num_rules_for_ruleset(default_ruleset));
@@ -247,8 +240,7 @@ TEST_F(test_falco_engine, enable_rule_name_exact)
EXPECT_EQ(2, m_engine->num_rules_for_ruleset(ruleset_4));
}
TEST_F(test_falco_engine, enable_rule_name_wildcard)
{
TEST_F(test_falco_engine, enable_rule_name_wildcard) {
load_rules(multi_rule, "multi_rule.yaml");
EXPECT_EQ(1, m_engine->num_rules_for_ruleset(default_ruleset));
@@ -283,4 +275,3 @@ TEST_F(test_falco_engine, enable_rule_name_wildcard)
EXPECT_EQ(1, m_engine->num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(3, m_engine->num_rules_for_ruleset(ruleset_4));
}

View File

@@ -19,8 +19,7 @@ limitations under the License.
#include "../test_falco_engine.h"
TEST_F(test_falco_engine, extra_format_all)
{
TEST_F(test_falco_engine, extra_format_all) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
@@ -32,11 +31,11 @@ TEST_F(test_falco_engine, extra_format_all)
m_engine->add_extra_output_format("evt.type=%evt.type", "", {}, "", false);
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
EXPECT_EQ(get_compiled_rule_output("legit_rule"),"user=%user.name command=%proc.cmdline file=%fd.name evt.type=%evt.type");
EXPECT_EQ(get_compiled_rule_output("legit_rule"),
"user=%user.name command=%proc.cmdline file=%fd.name evt.type=%evt.type");
}
TEST_F(test_falco_engine, extra_format_by_rule)
{
TEST_F(test_falco_engine, extra_format_by_rule) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
@@ -54,12 +53,11 @@ TEST_F(test_falco_engine, extra_format_by_rule)
m_engine->add_extra_output_format("evt.type=%evt.type", "", {}, "legit_rule", false);
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
EXPECT_EQ(get_compiled_rule_output("legit_rule"),"out 1 evt.type=%evt.type");
EXPECT_EQ(get_compiled_rule_output("another_rule"),"out 2");
EXPECT_EQ(get_compiled_rule_output("legit_rule"), "out 1 evt.type=%evt.type");
EXPECT_EQ(get_compiled_rule_output("another_rule"), "out 2");
}
TEST_F(test_falco_engine, extra_format_by_tag_rule)
{
TEST_F(test_falco_engine, extra_format_by_tag_rule) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
@@ -89,13 +87,12 @@ TEST_F(test_falco_engine, extra_format_by_tag_rule)
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
EXPECT_EQ(get_compiled_rule_output("legit_rule"),"out 1 extra 1");
EXPECT_EQ(get_compiled_rule_output("another_rule"),"out 2 extra 1 extra 2");
EXPECT_EQ(get_compiled_rule_output("a_third_rule"),"out 3 extra 1 extra 3");
EXPECT_EQ(get_compiled_rule_output("legit_rule"), "out 1 extra 1");
EXPECT_EQ(get_compiled_rule_output("another_rule"), "out 2 extra 1 extra 2");
EXPECT_EQ(get_compiled_rule_output("a_third_rule"), "out 3 extra 1 extra 3");
}
TEST_F(test_falco_engine, extra_format_replace_container_info)
{
TEST_F(test_falco_engine, extra_format_replace_container_info) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
@@ -120,8 +117,7 @@ TEST_F(test_falco_engine, extra_format_replace_container_info)
EXPECT_EQ(get_compiled_rule_output("another_rule"), "out 2 extra 1");
}
TEST_F(test_falco_engine, extra_format_do_not_replace_container_info)
{
TEST_F(test_falco_engine, extra_format_do_not_replace_container_info) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
@@ -130,15 +126,14 @@ TEST_F(test_falco_engine, extra_format_do_not_replace_container_info)
priority: INFO
tags: [tag1]
)END";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
auto output = get_compiled_rule_output("legit_rule");
EXPECT_TRUE(output.find("%container.info") == output.npos);
}
TEST_F(test_falco_engine, extra_fields_all)
{
TEST_F(test_falco_engine, extra_fields_all) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
@@ -147,11 +142,11 @@ TEST_F(test_falco_engine, extra_fields_all)
priority: INFO
)END";
std::unordered_map<std::string, std::string> extra_formatted_fields = {{"my_field", "hello %evt.num"}};
for (auto const& f : extra_formatted_fields)
{
m_engine->add_extra_output_formatted_field(f.first, f.second, "", {}, "");
}
std::unordered_map<std::string, std::string> extra_formatted_fields = {
{"my_field", "hello %evt.num"}};
for(auto const& f : extra_formatted_fields) {
m_engine->add_extra_output_formatted_field(f.first, f.second, "", {}, "");
}
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;

View File

@@ -18,8 +18,7 @@ limitations under the License.
#include <gtest/gtest.h>
#include <engine/falco_utils.h>
TEST(FalcoUtils, is_unix_scheme)
{
TEST(FalcoUtils, is_unix_scheme) {
/* Wrong prefix */
ASSERT_EQ(falco::utils::network::is_unix_scheme("something:///run/falco/falco.sock"), false);
@@ -38,15 +37,14 @@ TEST(FalcoUtils, is_unix_scheme)
ASSERT_EQ(falco::utils::network::is_unix_scheme(url_char), true);
}
TEST(FalcoUtils, parse_prometheus_interval)
{
TEST(FalcoUtils, parse_prometheus_interval) {
/* Test matrix around correct time conversions. */
ASSERT_EQ(falco::utils::parse_prometheus_interval("1ms"), 1UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1s"), 1000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1m"), 60000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1h"), 3600000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1d"), 86400000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1w"), 604800000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1w"), 604800000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1y"), (unsigned long)31536000000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("300ms"), 300UL);
@@ -57,8 +55,11 @@ TEST(FalcoUtils, parse_prometheus_interval)
ASSERT_EQ(falco::utils::parse_prometheus_interval("60m"), 3600000UL);
/* Test matrix for concatenated time interval examples. */
ASSERT_EQ(falco::utils::parse_prometheus_interval("1h3m2s1ms"), 3600000UL + 3 * 60000UL + 2 * 1000UL + 1UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1y1w1d1h1m1s1ms"),(unsigned long) 31536000000UL + 604800000UL + 86400000UL + 3600000UL + 60000UL + 1000UL + 1UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1h3m2s1ms"),
3600000UL + 3 * 60000UL + 2 * 1000UL + 1UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1y1w1d1h1m1s1ms"),
(unsigned long)31536000000UL + 604800000UL + 86400000UL + 3600000UL + 60000UL +
1000UL + 1UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("2h5m"), 2 * 3600000UL + 5 * 60000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("2h 5m"), 2 * 3600000UL + 5 * 60000UL);
@@ -73,16 +74,16 @@ TEST(FalcoUtils, parse_prometheus_interval)
ASSERT_EQ(falco::utils::parse_prometheus_interval("200"), 0UL);
}
TEST(FalcoUtils, sanitize_rule_name)
{
ASSERT_EQ(falco::utils::sanitize_rule_name("Testing rule 2 (CVE-2244)"), "Testing_rule_2_CVE_2244");
TEST(FalcoUtils, sanitize_rule_name) {
ASSERT_EQ(falco::utils::sanitize_rule_name("Testing rule 2 (CVE-2244)"),
"Testing_rule_2_CVE_2244");
ASSERT_EQ(falco::utils::sanitize_rule_name("Testing rule__:2)"), "Testing_rule_:2");
ASSERT_EQ(falco::utils::sanitize_rule_name("This@is_a$test rule123"), "This_is_a_test_rule123");
ASSERT_EQ(falco::utils::sanitize_rule_name("RULEwith:special#characters"), "RULEwith:special_characters");
ASSERT_EQ(falco::utils::sanitize_rule_name("RULEwith:special#characters"),
"RULEwith:special_characters");
}
TEST(FalcoUtils, matches_wildcard)
{
TEST(FalcoUtils, matches_wildcard) {
ASSERT_TRUE(falco::utils::matches_wildcard("*", "anything"));
ASSERT_TRUE(falco::utils::matches_wildcard("**", "anything"));
ASSERT_TRUE(falco::utils::matches_wildcard("*", ""));

View File

@@ -18,33 +18,33 @@ limitations under the License.
#include <gtest/gtest.h>
#include <engine/filter_details_resolver.h>
TEST(DetailsResolver, resolve_ast) {
std::string cond =
"(spawned_process or evt.type = open) and (proc.name icontains cat or proc.name in "
"(known_procs, ps))";
auto ast = libsinsp::filter::parser(cond).parse();
filter_details details;
details.known_macros.insert("spawned_process");
details.known_lists.insert("known_procs");
filter_details_resolver resolver;
resolver.run(ast.get(), details);
TEST(DetailsResolver, resolve_ast)
{
std::string cond = "(spawned_process or evt.type = open) and (proc.name icontains cat or proc.name in (known_procs, ps))";
auto ast = libsinsp::filter::parser(cond).parse();
filter_details details;
details.known_macros.insert("spawned_process");
details.known_lists.insert("known_procs");
filter_details_resolver resolver;
resolver.run(ast.get(), details);
// Assert fields
ASSERT_EQ(details.fields.size(), 2);
ASSERT_NE(details.fields.find("evt.type"), details.fields.end());
ASSERT_NE(details.fields.find("proc.name"), details.fields.end());
// Assert fields
ASSERT_EQ(details.fields.size(), 2);
ASSERT_NE(details.fields.find("evt.type"), details.fields.end());
ASSERT_NE(details.fields.find("proc.name"), details.fields.end());
// Assert macros
ASSERT_EQ(details.macros.size(), 1);
ASSERT_NE(details.macros.find("spawned_process"), details.macros.end());
// Assert macros
ASSERT_EQ(details.macros.size(), 1);
ASSERT_NE(details.macros.find("spawned_process"), details.macros.end());
// Assert operators
ASSERT_EQ(details.operators.size(), 3);
ASSERT_NE(details.operators.find("="), details.operators.end());
ASSERT_NE(details.operators.find("icontains"), details.operators.end());
ASSERT_NE(details.operators.find("in"), details.operators.end());
// Assert operators
ASSERT_EQ(details.operators.size(), 3);
ASSERT_NE(details.operators.find("="), details.operators.end());
ASSERT_NE(details.operators.find("icontains"), details.operators.end());
ASSERT_NE(details.operators.find("in"), details.operators.end());
// Assert lists
ASSERT_EQ(details.lists.size(), 1);
ASSERT_NE(details.lists.find("known_procs"), details.lists.end());
// Assert lists
ASSERT_EQ(details.lists.size(), 1);
ASSERT_NE(details.lists.find("known_procs"), details.lists.end());
}

View File

@@ -21,33 +21,37 @@ limitations under the License.
namespace filter_ast = libsinsp::filter::ast;
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)
{
const std::vector<filter_macro_resolver::value_info>& values,
const std::string& ref) {
return std::find_if(
values.begin(),
values.end(),
[&ref](const filter_macro_resolver::value_info& v)
{ return v.first == ref; });
values.begin(),
values.end(),
[&ref](const filter_macro_resolver::value_info& v) { return v.first == ref; });
}
#define MACRO_NAME "test_macro"
#define MACRO_A_NAME "test_macro_1"
#define MACRO_B_NAME "test_macro_2"
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST)
{
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST) {
filter_ast::pos_info macro_pos(12, 85, 27);
std::shared_ptr<filter_ast::expr> macro = filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""), "exists");
std::shared_ptr<filter_ast::expr> macro =
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""),
"exists");
std::vector<std::unique_ptr<filter_ast::expr>> filter_and;
filter_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("evt.name", ""), "exists"));
filter_and.push_back(filter_ast::not_expr::create(filter_ast::identifier_expr::create(MACRO_NAME, macro_pos)));
filter_and.push_back(
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("evt.name", ""),
"exists"));
filter_and.push_back(filter_ast::not_expr::create(
filter_ast::identifier_expr::create(MACRO_NAME, macro_pos)));
std::shared_ptr<filter_ast::expr> filter = filter_ast::and_expr::create(filter_and);
std::vector<std::unique_ptr<filter_ast::expr>> expected_and;
expected_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("evt.name", ""), "exists"));
expected_and.push_back(
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("evt.name", ""),
"exists"));
expected_and.push_back(filter_ast::not_expr::create(clone(macro.get())));
std::shared_ptr<filter_ast::expr> expected = filter_ast::and_expr::create(expected_and);
@@ -69,13 +73,15 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST)
ASSERT_TRUE(filter->is_equal(expected.get()));
}
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_single_node)
{
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_single_node) {
filter_ast::pos_info macro_pos(12, 85, 27);
std::shared_ptr<filter_ast::expr> macro = filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""), "exists");
std::shared_ptr<filter_ast::expr> macro =
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""),
"exists");
std::shared_ptr<filter_ast::expr> filter = filter_ast::identifier_expr::create(MACRO_NAME, macro_pos);
std::shared_ptr<filter_ast::expr> filter =
filter_ast::identifier_expr::create(MACRO_NAME, macro_pos);
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
@@ -99,13 +105,16 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_single_node)
ASSERT_TRUE(filter->is_equal(macro.get()));
}
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_multiple_macros)
{
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_multiple_macros) {
filter_ast::pos_info a_macro_pos(11, 75, 43);
filter_ast::pos_info b_macro_pos(91, 21, 9);
std::shared_ptr<filter_ast::expr> a_macro = filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""), "exists");
std::shared_ptr<filter_ast::expr> b_macro = filter_ast::unary_check_expr::create(filter_ast::field_expr::create("another.field", ""), "exists");
std::shared_ptr<filter_ast::expr> a_macro =
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""),
"exists");
std::shared_ptr<filter_ast::expr> b_macro = filter_ast::unary_check_expr::create(
filter_ast::field_expr::create("another.field", ""),
"exists");
std::vector<std::unique_ptr<filter_ast::expr>> filter_or;
filter_or.push_back(filter_ast::identifier_expr::create(MACRO_A_NAME, a_macro_pos));
@@ -143,24 +152,31 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_multiple_macros)
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
}
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_nested_macros)
{
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_nested_macros) {
filter_ast::pos_info a_macro_pos(47, 1, 76);
filter_ast::pos_info b_macro_pos(111, 65, 2);
std::vector<std::unique_ptr<filter_ast::expr>> a_macro_and;
a_macro_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""), "exists"));
a_macro_and.push_back(
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""),
"exists"));
a_macro_and.push_back(filter_ast::identifier_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<filter_ast::expr> a_macro = filter_ast::and_expr::create(a_macro_and);
std::shared_ptr<filter_ast::expr> b_macro =
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("another.field", ""), "exists");
std::shared_ptr<filter_ast::expr> b_macro = filter_ast::unary_check_expr::create(
filter_ast::field_expr::create("another.field", ""),
"exists");
std::shared_ptr<filter_ast::expr> filter = filter_ast::identifier_expr::create(MACRO_A_NAME, a_macro_pos);
std::shared_ptr<filter_ast::expr> filter =
filter_ast::identifier_expr::create(MACRO_A_NAME, a_macro_pos);
std::vector<std::unique_ptr<filter_ast::expr>> expected_and;
expected_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""), "exists"));
expected_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("another.field", ""), "exists"));
expected_and.push_back(
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""),
"exists"));
expected_and.push_back(filter_ast::unary_check_expr::create(
filter_ast::field_expr::create("another.field", ""),
"exists"));
std::shared_ptr<filter_ast::expr> expected_filter = filter_ast::and_expr::create(expected_and);
filter_macro_resolver resolver;
@@ -191,13 +207,15 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_nested_macros)
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
}
TEST(MacroResolver, should_find_unknown_macros)
{
TEST(MacroResolver, should_find_unknown_macros) {
filter_ast::pos_info macro_pos(9, 4, 2);
std::vector<std::unique_ptr<filter_ast::expr>> filter_and;
filter_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("evt.name", ""), "exists"));
filter_and.push_back(filter_ast::not_expr::create(filter_ast::identifier_expr::create(MACRO_NAME, macro_pos)));
filter_and.push_back(
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("evt.name", ""),
"exists"));
filter_and.push_back(filter_ast::not_expr::create(
filter_ast::identifier_expr::create(MACRO_NAME, macro_pos)));
std::shared_ptr<filter_ast::expr> filter = filter_ast::and_expr::create(filter_and);
filter_macro_resolver resolver;
@@ -208,17 +226,19 @@ TEST(MacroResolver, should_find_unknown_macros)
ASSERT_TRUE(resolver.get_resolved_macros().empty());
}
TEST(MacroResolver, should_find_unknown_nested_macros)
{
TEST(MacroResolver, should_find_unknown_nested_macros) {
filter_ast::pos_info a_macro_pos(32, 84, 9);
filter_ast::pos_info b_macro_pos(1, 0, 5);
std::vector<std::unique_ptr<filter_ast::expr>> a_macro_and;
a_macro_and.push_back(filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""), "exists"));
a_macro_and.push_back(
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("one.field", ""),
"exists"));
a_macro_and.push_back(filter_ast::identifier_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<filter_ast::expr> a_macro = filter_ast::and_expr::create(a_macro_and);
std::shared_ptr<filter_ast::expr> filter = filter_ast::identifier_expr::create(MACRO_A_NAME, a_macro_pos);
std::shared_ptr<filter_ast::expr> filter =
filter_ast::identifier_expr::create(MACRO_A_NAME, a_macro_pos);
auto expected_filter = clone(a_macro.get());
filter_macro_resolver resolver;
@@ -234,14 +254,17 @@ TEST(MacroResolver, should_find_unknown_nested_macros)
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
}
TEST(MacroResolver, should_undefine_macro)
{
TEST(MacroResolver, should_undefine_macro) {
filter_ast::pos_info macro_pos_1(12, 9, 3);
filter_ast::pos_info macro_pos_2(9, 6, 3);
std::shared_ptr<filter_ast::expr> macro = filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""), "exists");
std::shared_ptr<filter_ast::expr> a_filter = filter_ast::identifier_expr::create(MACRO_NAME, macro_pos_1);
std::shared_ptr<filter_ast::expr> b_filter = filter_ast::identifier_expr::create(MACRO_NAME, macro_pos_2);
std::shared_ptr<filter_ast::expr> macro =
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""),
"exists");
std::shared_ptr<filter_ast::expr> a_filter =
filter_ast::identifier_expr::create(MACRO_NAME, macro_pos_1);
std::shared_ptr<filter_ast::expr> b_filter =
filter_ast::identifier_expr::create(MACRO_NAME, macro_pos_2);
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
@@ -261,11 +284,13 @@ TEST(MacroResolver, should_undefine_macro)
}
/* checks that the macro AST is cloned and not shared across resolved filters */
TEST(MacroResolver, should_clone_macro_AST)
{
TEST(MacroResolver, should_clone_macro_AST) {
filter_ast::pos_info macro_pos(5, 2, 8888);
std::shared_ptr<filter_ast::unary_check_expr> macro = filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""), "exists");
std::shared_ptr<filter_ast::expr> filter = filter_ast::identifier_expr::create(MACRO_NAME, macro_pos);
std::shared_ptr<filter_ast::unary_check_expr> macro =
filter_ast::unary_check_expr::create(filter_ast::field_expr::create("test.field", ""),
"exists");
std::shared_ptr<filter_ast::expr> filter =
filter_ast::identifier_expr::create(MACRO_NAME, macro_pos);
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);

View File

@@ -18,16 +18,14 @@ limitations under the License.
#include <gtest/gtest.h>
#include <engine/filter_warning_resolver.h>
static bool warns(const std::string& condition)
{
static bool warns(const std::string& condition) {
std::set<falco::load_result::warning_code> w;
auto ast = libsinsp::filter::parser(condition).parse();
filter_warning_resolver().run(ast.get(), w);
return !w.empty();
}
TEST(WarningResolver, warnings_in_filtering_conditions)
{
TEST(WarningResolver, warnings_in_filtering_conditions) {
ASSERT_FALSE(warns("ka.field exists"));
ASSERT_FALSE(warns("some.field = <NA>"));
ASSERT_TRUE(warns("jevt.field = <NA>"));

View File

@@ -20,22 +20,19 @@ limitations under the License.
#include <gtest/gtest.h>
static bool check_requirements(std::string& err,
const std::vector<falco_engine::plugin_version_requirement>& plugins,
const std::string& ruleset_content)
{
const std::vector<falco_engine::plugin_version_requirement>& plugins,
const std::string& ruleset_content) {
falco_engine e;
falco::load_result::rules_contents_t c = {{"test", ruleset_content}};
auto res = e.load_rules(c.begin()->second, c.begin()->first);
if(!res->successful())
{
if(!res->successful()) {
return false;
}
return e.check_plugin_requirements(plugins, err);
}
TEST(PluginRequirements, check_plugin_requirements_success)
{
TEST(PluginRequirements, check_plugin_requirements_success) {
std::string error;
/* No requirement */
@@ -47,7 +44,7 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: k8saudit
version: 0.1.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin newer version */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.2.0"}}, R"(
@@ -55,7 +52,7 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: k8saudit
version: 0.1.0
)")) << error
<< std::endl;
<< std::endl;
/* Multiple plugins */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.1.0"}, {"json", "0.3.0"}}, R"(
@@ -65,7 +62,7 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: json
version: 0.3.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin multiple versions */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.2.0"}}, R"(
@@ -76,7 +73,7 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: k8saudit
version: 0.2.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin with alternatives */
ASSERT_TRUE(check_requirements(error, {{"k8saudit-other", "0.5.0"}}, R"(
@@ -87,7 +84,7 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: k8saudit-other
version: 0.4.0
)")) << error
<< std::endl;
<< std::endl;
/* Multiple plugins with alternatives */
ASSERT_TRUE(check_requirements(error, {{"k8saudit-other", "0.5.0"}, {"json2", "0.5.0"}}, R"(
@@ -103,7 +100,7 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: json2
version: 0.1.0
)")) << error
<< std::endl;
<< std::endl;
/* Multiple plugins with alternatives with multiple versions */
ASSERT_TRUE(check_requirements(error, {{"k8saudit-other", "0.7.0"}, {"json2", "0.5.0"}}, R"(
@@ -125,11 +122,10 @@ TEST(PluginRequirements, check_plugin_requirements_success)
- name: k8saudit-other
version: 0.7.0
)")) << error
<< std::endl;
<< std::endl;
}
TEST(PluginRequirements, check_plugin_requirements_reject)
{
TEST(PluginRequirements, check_plugin_requirements_reject) {
std::string error;
/* No plugin loaded */
@@ -138,7 +134,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit
version: 0.1.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin wrong name */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
@@ -146,7 +142,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit2
version: 0.1.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin wrong version */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
@@ -154,7 +150,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit
version: 0.2.0
)")) << error
<< std::endl;
<< std::endl;
/* Multiple plugins */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
@@ -164,7 +160,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: json
version: 0.3.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin multiple versions */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
@@ -175,7 +171,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit
version: 0.2.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin with alternatives */
ASSERT_FALSE(check_requirements(error, {{"k8saudit2", "0.5.0"}}, R"(
@@ -186,7 +182,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit-other
version: 0.4.0
)")) << error
<< std::endl;
<< std::endl;
/* Single plugin with overlapping alternatives */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.5.0"}}, R"(
@@ -197,7 +193,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit
version: 0.4.0
)")) << error
<< std::endl;
<< std::endl;
/* Multiple plugins with alternatives */
ASSERT_FALSE(check_requirements(error, {{"k8saudit-other", "0.5.0"}, {"json3", "0.5.0"}}, R"(
@@ -213,7 +209,7 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: json2
version: 0.1.0
)")) << error
<< std::endl;
<< std::endl;
/* Multiple plugins with alternatives with multiple versions */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.7.0"}, {"json2", "0.5.0"}}, R"(
@@ -235,5 +231,5 @@ TEST(PluginRequirements, check_plugin_requirements_reject)
- name: k8saudit-other
version: 0.7.0
)")) << error
<< std::endl;
<< std::endl;
}

File diff suppressed because it is too large Load Diff

View File

@@ -23,32 +23,28 @@ limitations under the License.
#define RULESET_2 2
/* Helpers methods */
static std::shared_ptr<sinsp_filter_factory> create_factory(sinsp* inspector, filter_check_list& list)
{
static std::shared_ptr<sinsp_filter_factory> create_factory(sinsp* inspector,
filter_check_list& list) {
return std::make_shared<sinsp_filter_factory>(inspector, list);
}
static std::shared_ptr<filter_ruleset> create_ruleset(std::shared_ptr<sinsp_filter_factory> f)
{
static std::shared_ptr<filter_ruleset> create_ruleset(std::shared_ptr<sinsp_filter_factory> f) {
return std::make_shared<evttype_index_ruleset>(f);
}
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(std::shared_ptr<sinsp_filter_factory> f)
{
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(
std::shared_ptr<sinsp_filter_factory> f) {
libsinsp::filter::parser parser("evt.type=open");
return parser.parse();
}
static std::shared_ptr<sinsp_filter> create_filter(
std::shared_ptr<sinsp_filter_factory> f,
libsinsp::filter::ast::expr* ast)
{
static std::shared_ptr<sinsp_filter> create_filter(std::shared_ptr<sinsp_filter_factory> f,
libsinsp::filter::ast::expr* ast) {
sinsp_filter_compiler compiler(f, ast);
return std::shared_ptr<sinsp_filter>(compiler.compile());
}
TEST(Ruleset, enable_disable_rules_using_names)
{
TEST(Ruleset, enable_disable_rules_using_names) {
sinsp inspector;
sinsp_filter_check_list filterlist;
@@ -140,8 +136,7 @@ TEST(Ruleset, enable_disable_rules_using_names)
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
}
TEST(Ruleset, enable_disable_rules_using_tags)
{
TEST(Ruleset, enable_disable_rules_using_tags) {
sinsp inspector;
sinsp_filter_check_list filterlist;

View File

@@ -19,5 +19,17 @@ limitations under the License.
#include <falco/app/state.h>
#include <falco/app/actions/actions.h>
#define EXPECT_ACTION_OK(r) { auto result = r; EXPECT_TRUE(result.success); EXPECT_TRUE(result.proceed); EXPECT_EQ(result.errstr, ""); }
#define EXPECT_ACTION_FAIL(r) { auto result = r; EXPECT_FALSE(result.success); EXPECT_FALSE(result.proceed); EXPECT_NE(result.errstr, ""); }
#define EXPECT_ACTION_OK(r) \
{ \
auto result = r; \
EXPECT_TRUE(result.success); \
EXPECT_TRUE(result.proceed); \
EXPECT_EQ(result.errstr, ""); \
}
#define EXPECT_ACTION_FAIL(r) \
{ \
auto result = r; \
EXPECT_FALSE(result.success); \
EXPECT_FALSE(result.proceed); \
EXPECT_NE(result.errstr, ""); \
}

View File

@@ -23,23 +23,21 @@ limitations under the License.
#include <falco/app/app.h>
#include "app_action_helpers.h"
#define ASSERT_NAMES_EQ(a, b) { \
EXPECT_EQ(_order(a).size(), _order(b).size()); \
ASSERT_EQ(_order(a), _order(b)); \
}
#define ASSERT_NAMES_EQ(a, b) \
{ \
EXPECT_EQ(_order(a).size(), _order(b).size()); \
ASSERT_EQ(_order(a), _order(b)); \
}
#define ASSERT_NAMES_CONTAIN(a, b) { \
ASSERT_NAMES_EQ(unordered_set_intersection(a, b), b); \
}
#define ASSERT_NAMES_CONTAIN(a, b) \
{ ASSERT_NAMES_EQ(unordered_set_intersection(a, b), b); }
#define ASSERT_NAMES_NOCONTAIN(a, b) { \
ASSERT_NAMES_EQ(unordered_set_intersection(a, b), strset_t({})); \
}
#define ASSERT_NAMES_NOCONTAIN(a, b) \
{ ASSERT_NAMES_EQ(unordered_set_intersection(a, b), strset_t({})); }
using strset_t = std::unordered_set<std::string>;
static std::set<std::string> _order(const strset_t& s)
{
static std::set<std::string> _order(const strset_t& s) {
return std::set<std::string>(s.begin(), s.end());
}
@@ -48,38 +46,31 @@ static std::string s_sample_ruleset = "sample-ruleset";
static std::string s_sample_source = falco_common::syscall_source;
static strset_t s_sample_filters = {
"evt.type=connect or evt.type=accept or evt.type=accept4 or evt.type=umount2",
"evt.type in (open, ptrace, mmap, execve, read, container)",
"evt.type in (open, execve, mprotect) and not evt.type=mprotect"};
"evt.type=connect or evt.type=accept or evt.type=accept4 or evt.type=umount2",
"evt.type in (open, ptrace, mmap, execve, read, container)",
"evt.type in (open, execve, mprotect) and not evt.type=mprotect"};
static strset_t s_sample_generic_filters = {
"evt.type=syncfs or evt.type=fanotify_init"};
static strset_t s_sample_generic_filters = {"evt.type=syncfs or evt.type=fanotify_init"};
static strset_t s_sample_nonsyscall_filters = {
"evt.type in (procexit, switch, pluginevent, container)"};
"evt.type in (procexit, switch, pluginevent, container)"};
static std::string ruleset_from_filters(const strset_t& filters)
{
static std::string ruleset_from_filters(const strset_t& filters) {
std::string dummy_rules;
falco::load_result::rules_contents_t content = {{"dummy_rules.yaml", dummy_rules}};
int n_rules = 0;
for (const auto& f : filters)
{
for(const auto& f : filters) {
n_rules++;
dummy_rules +=
"- rule: Dummy Rule " + std::to_string(n_rules) + "\n"
+ " output: Dummy Output " + std::to_string(n_rules) + "\n"
+ " condition: " + f + "\n"
+ " desc: Dummy Desc " + std::to_string(n_rules) + "\n"
+ " priority: CRITICAL\n\n";
dummy_rules += "- rule: Dummy Rule " + std::to_string(n_rules) + "\n" +
" output: Dummy Output " + std::to_string(n_rules) + "\n" +
" condition: " + f + "\n" + " desc: Dummy Desc " +
std::to_string(n_rules) + "\n" + " priority: CRITICAL\n\n";
}
return dummy_rules;
}
TEST_F(test_falco_engine, engine_codes_syscalls_set)
{
TEST_F(test_falco_engine, engine_codes_syscalls_set) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
auto enabled_count = m_engine->num_rules_for_ruleset(s_sample_ruleset);
@@ -88,20 +79,37 @@ TEST_F(test_falco_engine, engine_codes_syscalls_set)
// test if event code names were extracted from each rule in test ruleset.
auto rules_event_set = m_engine->event_codes_for_ruleset(s_sample_source);
auto rules_event_names = libsinsp::events::event_set_to_names(rules_event_set);
ASSERT_NAMES_EQ(rules_event_names, strset_t({
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", "container", "asyncevent"}));
ASSERT_NAMES_EQ(rules_event_names,
strset_t({"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read",
"container",
"asyncevent"}));
// test if sc code names were extracted from each rule in test ruleset.
// note, this is not supposed to contain "container", as that's an event
// not mapped through the ppm_sc_code enumerative.
auto rules_sc_set = m_engine->sc_codes_for_ruleset(s_sample_source);
auto rules_sc_names = libsinsp::events::sc_set_to_event_names(rules_sc_set);
ASSERT_NAMES_EQ(rules_sc_names, strset_t({
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read"}));
ASSERT_NAMES_EQ(rules_sc_names,
strset_t({"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read"}));
}
TEST_F(test_falco_engine, preconditions_postconditions)
{
TEST_F(test_falco_engine, preconditions_postconditions) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s1;
@@ -131,8 +139,7 @@ TEST_F(test_falco_engine, preconditions_postconditions)
ASSERT_EQ(prev_selection_size, s1.selected_sc_set.size());
}
TEST_F(test_falco_engine, engine_codes_nonsyscalls_set)
{
TEST_F(test_falco_engine, engine_codes_nonsyscalls_set) {
auto filters = s_sample_filters;
filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end());
filters.insert(s_sample_nonsyscall_filters.begin(), s_sample_nonsyscall_filters.end());
@@ -149,22 +156,44 @@ TEST_F(test_falco_engine, engine_codes_nonsyscalls_set)
// PPME_GENERIC_E will cause all names of generic events to be added!
// This is a good example of information loss from ppm_event_code <-> ppm_sc_code.
auto generic_names = libsinsp::events::event_set_to_names({ppm_event_code::PPME_GENERIC_E});
auto expected_names = strset_t({
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", "container", // ruleset
"procexit", "switch", "pluginevent", "asyncevent"}); // from non-syscall event filters
auto expected_names = strset_t({"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read",
"container", // ruleset
"procexit",
"switch",
"pluginevent",
"asyncevent"}); // from non-syscall event filters
expected_names.insert(generic_names.begin(), generic_names.end());
ASSERT_NAMES_EQ(rules_event_names, expected_names);
auto rules_sc_set = m_engine->sc_codes_for_ruleset(s_sample_source);
auto rules_sc_names = libsinsp::events::sc_set_to_event_names(rules_sc_set);
ASSERT_NAMES_EQ(rules_sc_names, strset_t({
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read",
"procexit", "switch", "syncfs", "fanotify_init", // from generic event filters
}));
ASSERT_NAMES_EQ(rules_sc_names,
strset_t({
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read",
"procexit",
"switch",
"syncfs",
"fanotify_init", // from generic event filters
}));
}
TEST_F(test_falco_engine, selection_not_allevents)
{
TEST_F(test_falco_engine, selection_not_allevents) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s2;
@@ -184,10 +213,22 @@ TEST_F(test_falco_engine, selection_not_allevents)
ASSERT_GT(s2.selected_sc_set.size(), 1);
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s2.selected_sc_set);
auto expected_sc_names = strset_t({
// note: we expect the "read" syscall to have been erased
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", // from ruleset
"clone", "clone3", "fork", "vfork", // from sinsp state set (spawned_process)
"socket", "bind", "close" // from sinsp state set (network, files)
// note: we expect the "read" syscall to have been erased
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve", // from ruleset
"clone",
"clone3",
"fork",
"vfork", // from sinsp state set (spawned_process)
"socket",
"bind",
"close" // from sinsp state set (network, files)
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
@@ -199,8 +240,7 @@ TEST_F(test_falco_engine, selection_not_allevents)
// check that final selected set is exactly sinsp state + ruleset
auto rule_set = s2.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
auto state_set = libsinsp::events::sinsp_state_sc_set();
for (const auto &erased : ignored_set)
{
for(const auto& erased : ignored_set) {
rule_set.remove(erased);
state_set.remove(erased);
}
@@ -210,8 +250,7 @@ TEST_F(test_falco_engine, selection_not_allevents)
ASSERT_EQ(s2.selected_sc_set, union_set);
}
TEST_F(test_falco_engine, selection_allevents)
{
TEST_F(test_falco_engine, selection_allevents) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s3;
@@ -229,10 +268,23 @@ TEST_F(test_falco_engine, selection_allevents)
ASSERT_GT(s3.selected_sc_set.size(), 1);
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s3.selected_sc_set);
auto expected_sc_names = strset_t({
// note: we expect the "read" syscall to not be erased
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", // from ruleset
"clone", "clone3", "fork", "vfork", // from sinsp state set (spawned_process)
"socket", "bind", "close" // from sinsp state set (network, files)
// note: we expect the "read" syscall to not be erased
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read", // from ruleset
"clone",
"clone3",
"fork",
"vfork", // from sinsp state set (spawned_process)
"socket",
"bind",
"close" // from sinsp state set (network, files)
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
@@ -245,8 +297,7 @@ TEST_F(test_falco_engine, selection_allevents)
ASSERT_EQ(s3.selected_sc_set, union_set);
}
TEST_F(test_falco_engine, selection_generic_evts)
{
TEST_F(test_falco_engine, selection_generic_evts) {
falco::app::state s4;
// run app action with fake engine and without the `-A` option
s4.options.all_events = false;
@@ -262,14 +313,28 @@ TEST_F(test_falco_engine, selection_generic_evts)
ASSERT_GT(s4.selected_sc_set.size(), 1);
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s4.selected_sc_set);
auto expected_sc_names = strset_t({
// note: we expect the "read" syscall to not be erased
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", // from ruleset
"syncfs", "fanotify_init", // from ruleset (generic events)
"clone", "clone3", "fork", "vfork", // from sinsp state set (spawned_process)
"socket", "bind", "close" // from sinsp state set (network, files)
// note: we expect the "read" syscall to not be erased
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve", // from ruleset
"syncfs",
"fanotify_init", // from ruleset (generic events)
"clone",
"clone3",
"fork",
"vfork", // from sinsp state set (spawned_process)
"socket",
"bind",
"close" // from sinsp state set (network, files)
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
auto unexpected_sc_names =
libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
}
@@ -278,8 +343,7 @@ TEST_F(test_falco_engine, selection_generic_evts)
// (either default or custom positive set)
// - events in the custom negative set are removed from the selected set
// - if `-A` is not set, events from the IO set are removed from the selected set
TEST_F(test_falco_engine, selection_custom_base_set)
{
TEST_F(test_falco_engine, selection_custom_base_set) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s5;
@@ -295,17 +359,24 @@ TEST_F(test_falco_engine, selection_custom_base_set)
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
auto expected_sc_names = strset_t({
// note: `syncfs` has been added due to the custom base set, and `accept`
// has been remove due to the negative base set.
// note: `read` is not ignored due to the "-A" option being set.
// note: `accept` is not included even though it is matched by the rules,
// which means that the custom negation base set has precedence over the
// final selection set as a whole
// note(jasondellaluce): "accept4" should be added, however old versions
// of the ACCEPT4 event are actually named "accept" in the event table
"connect", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "procexit"
});
auto expected_sc_names =
strset_t({// note: `syncfs` has been added due to the custom base set, and `accept`
// has been remove due to the negative base set.
// note: `read` is not ignored due to the "-A" option being set.
// note: `accept` is not included even though it is matched by the rules,
// which means that the custom negation base set has precedence over the
// final selection set as a whole
// note(jasondellaluce): "accept4" should be added, however old versions
// of the ACCEPT4 event are actually named "accept" in the event table
"connect",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read",
"syncfs",
"procexit"});
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (both positive and negative with collision)
@@ -325,10 +396,18 @@ TEST_F(test_falco_engine, selection_custom_base_set)
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
expected_sc_names = strset_t({
// note: accept is not negated anymore
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "read", "syncfs", "procexit"
});
expected_sc_names = strset_t({// note: accept is not negated anymore
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"read",
"syncfs",
"procexit"});
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (only negative)
@@ -338,8 +417,8 @@ TEST_F(test_falco_engine, selection_custom_base_set)
ASSERT_EQ(result.errstr, "");
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
expected_sc_names = unordered_set_union(
libsinsp::events::sc_set_to_event_names(default_base_set),
strset_t({ "connect", "umount2", "open", "ptrace", "mmap", "execve", "read"}));
libsinsp::events::sc_set_to_event_names(default_base_set),
strset_t({"connect", "umount2", "open", "ptrace", "mmap", "execve", "read"}));
expected_sc_names.erase("accept");
// note(jasondellaluce): "accept4" should be included, however old versions
// of the ACCEPT4 event are actually named "accept" in the event table
@@ -353,18 +432,24 @@ TEST_F(test_falco_engine, selection_custom_base_set)
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
expected_sc_names = strset_t({
// note: read is both part of the custom base set and the rules set,
// but we expect the unset -A option to take precedence
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit"
});
expected_sc_names = strset_t({// note: read is both part of the custom base set and the rules
// set, but we expect the unset -A option to take precedence
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"procexit"});
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
auto unexpected_sc_names =
libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
}
TEST_F(test_falco_engine, selection_custom_base_set_repair)
{
TEST_F(test_falco_engine, selection_custom_base_set_repair) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s6;
@@ -383,18 +468,29 @@ TEST_F(test_falco_engine, selection_custom_base_set_repair)
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s6.selected_sc_set);
auto expected_sc_names = strset_t({
// note: expecting syscalls from mock rules and `sinsp_repair_state_sc_set` enforced syscalls
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit", \
"bind", "socket", "clone3", "close", "setuid"
});
auto expected_sc_names = strset_t({// note: expecting syscalls from mock rules and
// `sinsp_repair_state_sc_set` enforced syscalls
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"procexit",
"bind",
"socket",
"clone3",
"close",
"setuid"});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
auto unexpected_sc_names = libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
auto unexpected_sc_names =
libsinsp::events::sc_set_to_event_names(falco::app::ignored_sc_set());
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
}
TEST_F(test_falco_engine, selection_empty_custom_base_set_repair)
{
TEST_F(test_falco_engine, selection_empty_custom_base_set_repair) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s7;
@@ -410,23 +506,71 @@ TEST_F(test_falco_engine, selection_empty_custom_base_set_repair)
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s7.selected_sc_set);
auto expected_sc_names = strset_t({
// note: expecting syscalls from mock rules and `sinsp_repair_state_sc_set` enforced syscalls
"connect", "accept", "accept4", "umount2", "open", "ptrace", "mmap", "execve", "procexit", \
"bind", "socket", "clone3", "close", "setuid"
});
auto expected_sc_names = strset_t({// note: expecting syscalls from mock rules and
// `sinsp_repair_state_sc_set` enforced syscalls
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"procexit",
"bind",
"socket",
"clone3",
"close",
"setuid"});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
auto s7_state_set = libsinsp::events::sinsp_repair_state_sc_set(s7_rules_set);
ASSERT_EQ(s7.selected_sc_set, s7_state_set);
ASSERT_EQ(s7.selected_sc_set.size(), s7_state_set.size());
}
TEST(ConfigureInterestingSets, ignored_set_expected_size)
{
TEST_F(test_falco_engine, selection_base_syscalls_all) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s7;
s7.engine = m_engine;
// simulate empty custom set but repair option set.
s7.config->m_base_syscalls_custom_set = {};
s7.config->m_base_syscalls_repair = true;
s7.config->m_base_syscalls_all = true;
auto result = falco::app::actions::configure_interesting_sets(s7);
auto s7_rules_set = s7.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
auto selected_sc_names = libsinsp::events::sc_set_to_event_names(s7.selected_sc_set);
auto expected_sc_names = strset_t({// note: expecting syscalls from mock rules and
// `sinsp_repair_state_sc_set` enforced syscalls
"connect",
"accept",
"accept4",
"umount2",
"open",
"ptrace",
"mmap",
"execve",
"procexit",
"bind",
"socket",
"clone3",
"close",
"setuid"});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
auto s7_state_set = libsinsp::events::sinsp_repair_state_sc_set(s7_rules_set);
ASSERT_EQ(s7.selected_sc_set, s7_state_set);
ASSERT_EQ(s7.selected_sc_set.size(), s7_state_set.size());
}
TEST(ConfigureInterestingSets, ignored_set_expected_size) {
// unit test fence to make sure we don't have unexpected regressions
// in the ignored set, to be updated in the future
ASSERT_EQ(falco::app::ignored_sc_set().size(), 14);
ASSERT_EQ(falco::app::ignored_sc_set().size(), 12);
// we don't expect to ignore any syscall in the default base set
ASSERT_EQ(falco::app::ignored_sc_set().intersect(libsinsp::events::sinsp_state_sc_set()).size(), 0);
ASSERT_EQ(falco::app::ignored_sc_set().intersect(libsinsp::events::sinsp_state_sc_set()).size(),
0);
}

View File

@@ -17,13 +17,11 @@ limitations under the License.
#include "app_action_helpers.h"
TEST(ActionConfigureSyscallBufferNum, variable_number_of_CPUs)
{
TEST(ActionConfigureSyscallBufferNum, variable_number_of_CPUs) {
auto action = falco::app::actions::configure_syscall_buffer_num;
ssize_t online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
if(online_cpus <= 0)
{
if(online_cpus <= 0) {
FAIL() << "cannot get the number of online CPUs from the system\n";
}

View File

@@ -19,8 +19,7 @@ limitations under the License.
#include "falco_test_var.h"
#ifndef __EMSCRIPTEN__
TEST(ActionLoadConfig, check_kmod_engine_config)
{
TEST(ActionLoadConfig, check_kmod_engine_config) {
falco::app::state s = {};
s.options.conf_filename = TEST_ENGINE_KMOD_CONFIG;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));
@@ -47,8 +46,7 @@ TEST(ActionLoadConfig, check_kmod_engine_config)
EXPECT_TRUE(s.config->m_gvisor.m_root.empty());
}
TEST(ActionLoadConfig, check_modern_engine_config)
{
TEST(ActionLoadConfig, check_modern_engine_config) {
falco::app::state s = {};
s.options.conf_filename = TEST_ENGINE_MODERN_CONFIG;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));

View File

@@ -17,85 +17,82 @@ limitations under the License.
#include "app_action_helpers.h"
TEST(ActionSelectEventSources, pre_post_conditions)
{
auto action = falco::app::actions::select_event_sources;
TEST(ActionSelectEventSources, pre_post_conditions) {
auto action = falco::app::actions::select_event_sources;
// requires sources to be already loaded
{
falco::app::state s;
EXPECT_ACTION_FAIL(action(s));
}
// requires sources to be already loaded
{
falco::app::state s;
EXPECT_ACTION_FAIL(action(s));
}
// ignore source selection in capture mode
{
falco::app::state s;
s.config->m_engine_mode = engine_kind_t::REPLAY;
EXPECT_TRUE(s.is_capture_mode());
EXPECT_ACTION_OK(action(s));
}
// ignore source selection in capture mode
{
falco::app::state s;
s.config->m_engine_mode = engine_kind_t::REPLAY;
EXPECT_TRUE(s.is_capture_mode());
EXPECT_ACTION_OK(action(s));
}
// enable all loaded sources by default, even with multiple calls
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.loaded_sources.size(), s.enabled_sources.size());
for (const auto& v : s.loaded_sources)
{
ASSERT_TRUE(s.enabled_sources.find(v) != s.enabled_sources.end());
}
s.loaded_sources.push_back("another_source");
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.loaded_sources.size(), s.enabled_sources.size());
for (const auto& v : s.loaded_sources)
{
ASSERT_TRUE(s.enabled_sources.find(v) != s.enabled_sources.end());
}
}
// enable all loaded sources by default, even with multiple calls
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.loaded_sources.size(), s.enabled_sources.size());
for(const auto& v : s.loaded_sources) {
ASSERT_TRUE(s.enabled_sources.find(v) != s.enabled_sources.end());
}
s.loaded_sources.push_back("another_source");
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.loaded_sources.size(), s.enabled_sources.size());
for(const auto& v : s.loaded_sources) {
ASSERT_TRUE(s.enabled_sources.find(v) != s.enabled_sources.end());
}
}
// enable only selected sources
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.enable_sources = {"syscall"};
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.enabled_sources.size(), 1);
EXPECT_EQ(*s.enabled_sources.begin(), "syscall");
}
// enable only selected sources
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.enable_sources = {"syscall"};
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.enabled_sources.size(), 1);
EXPECT_EQ(*s.enabled_sources.begin(), "syscall");
}
// enable all loaded sources expect the disabled ones
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.disable_sources = {"syscall"};
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.enabled_sources.size(), 1);
EXPECT_EQ(*s.enabled_sources.begin(), "some_source");
}
// enable all loaded sources expect the disabled ones
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.disable_sources = {"syscall"};
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.enabled_sources.size(), 1);
EXPECT_EQ(*s.enabled_sources.begin(), "some_source");
}
// enable unknown sources
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.enable_sources = {"some_other_source"};
EXPECT_ACTION_FAIL(action(s));
}
// enable unknown sources
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.enable_sources = {"some_other_source"};
EXPECT_ACTION_FAIL(action(s));
}
// disable unknown sources
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.disable_sources = {"some_other_source"};
EXPECT_ACTION_FAIL(action(s));
}
// disable unknown sources
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.disable_sources = {"some_other_source"};
EXPECT_ACTION_FAIL(action(s));
}
// mix enable and disable sources options
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.disable_sources = {"syscall"};
s.options.enable_sources = {"syscall"};
EXPECT_ACTION_FAIL(action(s));
}
// mix enable and disable sources options
{
falco::app::state s;
s.loaded_sources = {"syscall", "some_source"};
s.options.disable_sources = {"syscall"};
s.options.enable_sources = {"syscall"};
EXPECT_ACTION_FAIL(action(s));
}
}

View File

@@ -25,13 +25,11 @@ limitations under the License.
#include <memory>
#include <vector>
TEST(AtomicSignalHandler, lock_free_implementation)
{
TEST(AtomicSignalHandler, lock_free_implementation) {
ASSERT_TRUE(falco::atomic_signal_handler().is_lock_free());
}
TEST(AtomicSignalHandler, handle_once_wait_consistency)
{
TEST(AtomicSignalHandler, handle_once_wait_consistency) {
constexpr const auto thread_num = 10;
constexpr const std::chrono::seconds thread_wait_sec{2};
constexpr const std::chrono::seconds handler_wait_sec{1};
@@ -40,33 +38,27 @@ TEST(AtomicSignalHandler, handle_once_wait_consistency)
falco::atomic_signal_handler handler;
// launch a bunch of threads all syncing on the same handler
struct task_result_t
{
struct task_result_t {
bool handled;
std::chrono::seconds duration_secs;
};
std::vector<std::future<task_result_t>> futures;
for (int i = 0; i < thread_num; i++)
{
futures.emplace_back(std::async(std::launch::async,
[&handler, thread_wait_sec]() {
auto start = std::chrono::high_resolution_clock::now();
task_result_t res;
res.handled = false;
while (!handler.handled())
{
if (handler.triggered())
{
res.handled = handler.handle([thread_wait_sec]() {
std::this_thread::sleep_for(thread_wait_sec);
});
}
for(int i = 0; i < thread_num; i++) {
futures.emplace_back(std::async(std::launch::async, [&handler, thread_wait_sec]() {
auto start = std::chrono::high_resolution_clock::now();
task_result_t res;
res.handled = false;
while(!handler.handled()) {
if(handler.triggered()) {
res.handled = handler.handle(
[thread_wait_sec]() { std::this_thread::sleep_for(thread_wait_sec); });
}
auto diff = std::chrono::high_resolution_clock::now() - start;
res.duration_secs = std::chrono::duration_cast<std::chrono::seconds>(diff);
return res;
}));
}
auto diff = std::chrono::high_resolution_clock::now() - start;
res.duration_secs = std::chrono::duration_cast<std::chrono::seconds>(diff);
return res;
}));
}
// wait a bit, then trigger the signal handler from the main thread
@@ -74,12 +66,10 @@ TEST(AtomicSignalHandler, handle_once_wait_consistency)
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(handler_wait_sec);
handler.trigger();
for (int i = 0; i < thread_num; i++)
{
for(int i = 0; i < thread_num; i++) {
// wait for all threads to finish and get the results from the futures
auto res = futures[i].get();
if (res.handled)
{
if(res.handled) {
total_handled++;
}
ASSERT_GE(res.duration_secs, thread_wait_sec);
@@ -94,9 +84,8 @@ TEST(AtomicSignalHandler, handle_once_wait_consistency)
ASSERT_EQ(total_handled, 1);
}
TEST(AtomicSignalHandler, handle_and_reset)
{
auto do_nothing = []{};
TEST(AtomicSignalHandler, handle_and_reset) {
auto do_nothing = [] {};
falco::atomic_signal_handler handler;
ASSERT_FALSE(handler.triggered());

View File

@@ -19,20 +19,19 @@ limitations under the License.
#include <falco/configuration.h>
static std::string sample_yaml =
"base_value:\n"
" id: 1\n"
" name: 'sample_name'\n"
" subvalue:\n"
" subvalue2:\n"
" boolean: true\n"
"base_value_2:\n"
" sample_list:\n"
" - elem1\n"
" - elem2\n"
" - elem3\n";
"base_value:\n"
" id: 1\n"
" name: 'sample_name'\n"
" subvalue:\n"
" subvalue2:\n"
" boolean: true\n"
"base_value_2:\n"
" sample_list:\n"
" - elem1\n"
" - elem2\n"
" - elem3\n";
TEST(Configuration, configuration_exceptions)
{
TEST(Configuration, configuration_exceptions) {
yaml_helper conf;
/* Broken YAML */
@@ -43,8 +42,7 @@ TEST(Configuration, configuration_exceptions)
EXPECT_NO_THROW(conf.load_from_string(sample_yaml));
}
TEST(Configuration, configuration_reload)
{
TEST(Configuration, configuration_reload) {
yaml_helper conf;
/* Clear and reload config */
@@ -56,8 +54,7 @@ TEST(Configuration, configuration_reload)
ASSERT_TRUE(conf.is_defined("base_value"));
}
TEST(Configuration, read_yaml_fields)
{
TEST(Configuration, read_yaml_fields) {
yaml_helper conf;
conf.load_from_string(sample_yaml);
@@ -72,9 +69,12 @@ TEST(Configuration, read_yaml_fields)
ASSERT_EQ(conf.get_scalar<bool>("base_value.subvalue.subvalue2.boolean", false), true);
/* get list field elements */
ASSERT_STREQ(conf.get_scalar<std::string>("base_value_2.sample_list[0]", "none").c_str(), "elem1");
ASSERT_STREQ(conf.get_scalar<std::string>("base_value_2.sample_list[1]", "none").c_str(), "elem2");
ASSERT_STREQ(conf.get_scalar<std::string>("base_value_2.sample_list[2]", "none").c_str(), "elem3");
ASSERT_STREQ(conf.get_scalar<std::string>("base_value_2.sample_list[0]", "none").c_str(),
"elem1");
ASSERT_STREQ(conf.get_scalar<std::string>("base_value_2.sample_list[1]", "none").c_str(),
"elem2");
ASSERT_STREQ(conf.get_scalar<std::string>("base_value_2.sample_list[2]", "none").c_str(),
"elem3");
/* get sequence */
std::vector<std::string> seq;
@@ -85,100 +85,100 @@ TEST(Configuration, read_yaml_fields)
ASSERT_STREQ(seq[2].c_str(), "elem3");
}
TEST(Configuration, modify_yaml_fields)
{
TEST(Configuration, modify_yaml_fields) {
std::string key = "base_value.subvalue.subvalue2.boolean";
yaml_helper conf;
/* Get original value */
conf.load_from_string(sample_yaml);
/* Get original value */
conf.load_from_string(sample_yaml);
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
/* Modify the original value */
conf.set_scalar<bool>(key, false);
/* Modify the original value */
conf.set_scalar<bool>(key, false);
ASSERT_EQ(conf.get_scalar<bool>(key, true), false);
/* Modify it again */
conf.set_scalar<bool>(key, true);
/* Modify it again */
conf.set_scalar<bool>(key, true);
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
}
TEST(Configuration, configuration_webserver_ip)
{
falco_configuration falco_config;
TEST(Configuration, configuration_webserver_ip) {
falco_configuration falco_config;
std::vector<std::string> valid_addresses = {"127.0.0.1",
"1.127.0.1",
"1.1.127.1",
"1.1.1.127",
"::",
"::1",
"1200:0000:AB00:1234:0000:2552:7777:1313",
"1200::AB00:1234:0000:2552:7777:1313",
"1200:0000:AB00:1234::2552:7777:1313",
"21DA:D3:0:2F3B:2AA:FF:FE28:9C5A",
"FE80:0000:0000:0000:0202:B3FF:FE1E:8329",
"0.0.0.0",
"9.255.255.255",
"11.0.0.0",
"126.255.255.255",
"129.0.0.0",
"169.253.255.255",
"169.255.0.0",
"172.15.255.255",
"172.32.0.0",
"191.0.1.255",
"192.88.98.255",
"192.88.100.0",
"192.167.255.255",
"192.169.0.0",
"198.17.255.255",
"223.255.255.255"};
std::vector<std::string> valid_addresses = {"127.0.0.1",
"1.127.0.1",
"1.1.127.1",
"1.1.1.127",
"::",
"::1",
"1200:0000:AB00:1234:0000:2552:7777:1313",
"1200::AB00:1234:0000:2552:7777:1313",
"1200:0000:AB00:1234::2552:7777:1313",
"21DA:D3:0:2F3B:2AA:FF:FE28:9C5A",
"FE80:0000:0000:0000:0202:B3FF:FE1E:8329",
"0.0.0.0",
"9.255.255.255",
"11.0.0.0",
"126.255.255.255",
"129.0.0.0",
"169.253.255.255",
"169.255.0.0",
"172.15.255.255",
"172.32.0.0",
"191.0.1.255",
"192.88.98.255",
"192.88.100.0",
"192.167.255.255",
"192.169.0.0",
"198.17.255.255",
"223.255.255.255"};
for (const std::string &address: valid_addresses) {
std::string option = "webserver.listen_address=";
option.append(address);
for(const std::string &address : valid_addresses) {
std::string option = "webserver.listen_address=";
option.append(address);
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back(option);
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back(option);
EXPECT_NO_THROW(falco_config.init_from_content("", cmdline_config_options));
EXPECT_NO_THROW(falco_config.init_from_content("", cmdline_config_options));
ASSERT_EQ(falco_config.m_webserver_config.m_listen_address, address);
}
ASSERT_EQ(falco_config.m_webserver_config.m_listen_address, address);
}
std::vector<std::string> invalid_addresses = {"327.0.0.1",
"1.327.0.1",
"1.1.327.1",
"1.1.1.327",
"12 7.0.0.1",
"127. 0.0.1",
"127.0. 0.1",
"127.0.0. 1",
"!27.0.0.1",
"1200: 0000:AB00:1234:0000:2552:7777:1313",
"1200:0000: AB00:1234:0000:2552:7777:1313",
"1200:0000:AB00: 1234:0000:2552:7777:1313",
"1200:0000:AB00:1234: 0000:2552:7777:1313",
"1200:0000:AB00:1234:0000: 2552:7777:1313",
"1200:0000:AB00:1234:0000:2552: 7777:1313",
"1200:0000:AB00:1234:0000:2552:7777: 1313",
"1200:0000:AB00:1234:0000:2552:7777:131G",
"1200:0000:AB00:1234:0000:2552:77Z7:1313",
"1200:0000:AB00:1234:0000:2G52:7777:1313",
"1200:0000:AB00:1234:0O00:2552:7777:1313",
"1200:0000:AB00:H234:0000:2552:7777:1313",
"1200:0000:IB00:1234:0000:2552:7777:1313",
"1200:0O00:AB00:1234:0000:2552:7777:1313",
"12O0:0000:AB00:1234:0000:2552:7777:1313",};
std::vector<std::string> invalid_addresses = {
"327.0.0.1",
"1.327.0.1",
"1.1.327.1",
"1.1.1.327",
"12 7.0.0.1",
"127. 0.0.1",
"127.0. 0.1",
"127.0.0. 1",
"!27.0.0.1",
"1200: 0000:AB00:1234:0000:2552:7777:1313",
"1200:0000: AB00:1234:0000:2552:7777:1313",
"1200:0000:AB00: 1234:0000:2552:7777:1313",
"1200:0000:AB00:1234: 0000:2552:7777:1313",
"1200:0000:AB00:1234:0000: 2552:7777:1313",
"1200:0000:AB00:1234:0000:2552: 7777:1313",
"1200:0000:AB00:1234:0000:2552:7777: 1313",
"1200:0000:AB00:1234:0000:2552:7777:131G",
"1200:0000:AB00:1234:0000:2552:77Z7:1313",
"1200:0000:AB00:1234:0000:2G52:7777:1313",
"1200:0000:AB00:1234:0O00:2552:7777:1313",
"1200:0000:AB00:H234:0000:2552:7777:1313",
"1200:0000:IB00:1234:0000:2552:7777:1313",
"1200:0O00:AB00:1234:0000:2552:7777:1313",
"12O0:0000:AB00:1234:0000:2552:7777:1313",
};
for (const std::string &address: invalid_addresses) {
std::string option = "webserver.listen_address=";
option.append(address);
for(const std::string &address : invalid_addresses) {
std::string option = "webserver.listen_address=";
option.append(address);
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back(option);
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back(option);
EXPECT_ANY_THROW(falco_config.init_from_content("", cmdline_config_options));
}
EXPECT_ANY_THROW(falco_config.init_from_content("", cmdline_config_options));
}
}

View File

@@ -18,23 +18,23 @@ limitations under the License.
#include <gtest/gtest.h>
#include <falco/configuration.h>
TEST(Configuration, configuration_config_files_secondary_fail)
{
/* Test that a secondary config file is not able to include anything, triggering an exception. */
const std::string main_conf_yaml =
yaml_helper::configs_key + ":\n"
" - conf_2.yaml\n"
" - conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
yaml_helper::configs_key + ":\n"
" - conf_4.yaml\n"
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
TEST(Configuration, configuration_config_files_secondary_fail) {
/* Test that a secondary config file is not able to include anything, triggering an exception.
*/
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - conf_2.yaml\n"
" - conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 = yaml_helper::configs_key +
":\n"
" - conf_4.yaml\n"
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -52,29 +52,28 @@ TEST(Configuration, configuration_config_files_secondary_fail)
std::filesystem::remove("conf_2.yaml");
}
TEST(Configuration, configuration_config_files_ok)
{
TEST(Configuration, configuration_config_files_ok) {
/* Test that every included config file was correctly parsed */
const std::string main_conf_yaml =
yaml_helper::configs_key + ":\n"
" - conf_2.yaml\n"
" - conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - conf_2.yaml\n"
" - conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"foo3: bar3\n"
"base_value_3:\n"
" id: 3\n"
" name: foo3\n";
"foo3: bar3\n"
"base_value_3:\n"
" id: 3\n"
" name: foo3\n";
const std::string conf_yaml_4 =
"base_value_4:\n"
" id: 4\n";
"base_value_4:\n"
" id: 4\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -117,7 +116,7 @@ TEST(Configuration, configuration_config_files_ok)
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_3.id", 0), 3);
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_3.name"));
ASSERT_EQ(falco_config.m_config.get_scalar<std::string>("base_value_3.name", ""), "foo3");
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_4.id")); // conf_4 is not included
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_4.id")); // conf_4 is not included
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
@@ -125,9 +124,7 @@ TEST(Configuration, configuration_config_files_ok)
std::filesystem::remove("conf_4.yaml");
}
TEST(Configuration, configuration_config_files_relative_main)
{
TEST(Configuration, configuration_config_files_relative_main) {
/*
* Test that relative path are treated as relative to cwd and not to main config folder,
* and that absolute includes are ok too.
@@ -135,24 +132,25 @@ TEST(Configuration, configuration_config_files_relative_main)
const auto temp_main = std::filesystem::temp_directory_path() / "main.yaml";
// So, conf_2 will be looked up in the same folder as main config file,
// while conf_3, since is absolute, will be looked up in the absolute path (and found!).
const std::string main_conf_yaml =
yaml_helper::configs_key + ":\n"
" - conf_2.yaml\n"
" - " +
std::filesystem::current_path().string() + "/conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - conf_2.yaml\n"
" - " +
std::filesystem::current_path().string() +
"/conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"foo3: bar3\n"
"base_value_3:\n"
" id: 3\n"
" name: foo3\n";
"foo3: bar3\n"
"base_value_3:\n"
" id: 3\n"
" name: foo3\n";
std::ofstream outfile(temp_main.string());
outfile << main_conf_yaml;
@@ -192,24 +190,23 @@ TEST(Configuration, configuration_config_files_relative_main)
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_override)
{
TEST(Configuration, configuration_config_files_override) {
/* Test that included config files are able to override configs from main file */
const std::string main_conf_yaml =
yaml_helper::configs_key + ":\n"
" - conf_2.yaml\n"
" - conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - conf_2.yaml\n"
" - conf_3.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"base_value:\n"
" id: 3\n";
"base_value:\n"
" id: 3\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -234,28 +231,28 @@ TEST(Configuration, configuration_config_files_override)
ASSERT_TRUE(falco_config.m_config.is_defined("foo"));
ASSERT_EQ(falco_config.m_config.get_scalar<std::string>("foo", ""), "bar");
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined("base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined(
"base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_TRUE(falco_config.m_config.is_defined("foo2"));
ASSERT_EQ(falco_config.m_config.get_scalar<std::string>("foo2", ""), "bar2");
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_unexistent)
{
TEST(Configuration, configuration_config_files_unexistent) {
/* Test that including an unexistent file just skips it */
const std::string main_conf_yaml =
yaml_helper::configs_key + ":\n"
" - conf_5.yaml\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - conf_5.yaml\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -277,19 +274,19 @@ TEST(Configuration, configuration_config_files_unexistent)
std::filesystem::remove("main.yaml");
}
TEST(Configuration, configuration_config_files_scalar_config_files)
{
/* Test that a single file can be included as a scalar (thanks to get_sequence_from_node magic) */
const std::string main_conf_yaml =
yaml_helper::configs_key + ": conf_2.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
TEST(Configuration, configuration_config_files_scalar_config_files) {
/* Test that a single file can be included as a scalar (thanks to get_sequence_from_node magic)
*/
const std::string main_conf_yaml = yaml_helper::configs_key +
": conf_2.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -322,15 +319,14 @@ TEST(Configuration, configuration_config_files_scalar_config_files)
std::filesystem::remove("conf_2.yaml");
}
TEST(Configuration, configuration_config_files_empty_config_files)
{
TEST(Configuration, configuration_config_files_empty_config_files) {
/* Test that empty includes list is accepted */
const std::string main_conf_yaml =
yaml_helper::configs_key + ":\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -354,15 +350,14 @@ TEST(Configuration, configuration_config_files_empty_config_files)
std::filesystem::remove("main.yaml");
}
TEST(Configuration, configuration_config_files_self)
{
TEST(Configuration, configuration_config_files_self) {
/* Test that main config file cannot include itself */
const std::string main_conf_yaml =
yaml_helper::configs_key + ": main.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key +
": main.yaml\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -375,31 +370,30 @@ TEST(Configuration, configuration_config_files_self)
std::filesystem::remove("main.yaml");
}
TEST(Configuration, configuration_config_files_directory)
{
TEST(Configuration, configuration_config_files_directory) {
/*
* Test that when main config file includes a config directory,
* the config directory is parsed in lexicographic order,
* and only regular files are parsed.
*/
// Main config includes whole temp directory
const std::string main_conf_yaml =
yaml_helper::configs_key + ": " + std::filesystem::temp_directory_path().string() + "/test\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string main_conf_yaml = yaml_helper::configs_key + ": " +
std::filesystem::temp_directory_path().string() +
"/test\n"
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"foo2: bar3\n"
"base_value_3:\n"
" id: 3\n"
" name: foo3\n";
const std::string conf_yaml_4 =
"foo4: bar4\n";
"foo2: bar3\n"
"base_value_3:\n"
" id: 3\n"
" name: foo3\n";
const std::string conf_yaml_4 = "foo4: bar4\n";
std::filesystem::create_directory(std::filesystem::temp_directory_path() / "test");
@@ -407,17 +401,17 @@ TEST(Configuration, configuration_config_files_directory)
outfile << main_conf_yaml;
outfile.close();
outfile.open(std::filesystem::temp_directory_path()/"test/conf_2.yaml");
outfile.open(std::filesystem::temp_directory_path() / "test/conf_2.yaml");
outfile << conf_yaml_2;
outfile.close();
outfile.open(std::filesystem::temp_directory_path()/"test/conf_3.yaml");
outfile.open(std::filesystem::temp_directory_path() / "test/conf_3.yaml");
outfile << conf_yaml_3;
outfile.close();
// Create a directory and create a config inside it. We will later check that it was not parsed
std::filesystem::create_directory(std::filesystem::temp_directory_path() / "test" / "foo");
outfile.open(std::filesystem::temp_directory_path()/"test/foo/conf_4.yaml");
outfile.open(std::filesystem::temp_directory_path() / "test/foo/conf_4.yaml");
outfile << conf_yaml_4;
outfile.close();
@@ -445,21 +439,20 @@ TEST(Configuration, configuration_config_files_directory)
ASSERT_FALSE(falco_config.m_config.is_defined("foo4"));
std::filesystem::remove("main");
std::filesystem::remove_all(std::filesystem::temp_directory_path()/"test");
std::filesystem::remove_all(std::filesystem::temp_directory_path() / "test");
}
TEST(Configuration, configuration_config_files_cmdline)
{
TEST(Configuration, configuration_config_files_cmdline) {
/* Test that we support including configs files from cmdline option */
const std::string main_conf_yaml =
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
"foo: bar\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
"foo2: bar2\n"
"base_value_2:\n"
" id: 2\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
@@ -471,7 +464,7 @@ TEST(Configuration, configuration_config_files_cmdline)
// Pass "config_files=..." cmdline option
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back((yaml_helper::configs_key+"=conf_2.yaml"));
cmdline_config_options.push_back((yaml_helper::configs_key + "=conf_2.yaml"));
falco_configuration falco_config;
config_loaded_res res;
@@ -493,4 +486,4 @@ TEST(Configuration, configuration_config_files_cmdline)
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
}
}

View File

@@ -24,8 +24,7 @@ limitations under the License.
#define SET_ENV_VAR(env_var_name, env_var_value) setenv(env_var_name, env_var_value, 1)
#endif
TEST(Configuration, configuration_environment_variables)
{
TEST(Configuration, configuration_environment_variables) {
// Set an environment variable for testing purposes
std::string env_var_value = "envVarValue";
std::string env_var_name = "ENV_VAR";
@@ -49,38 +48,38 @@ TEST(Configuration, configuration_environment_variables)
std::string default_value = "default";
std::string env_var_sample_yaml =
"base_value:\n"
" id: $ENV_VAR\n"
" name: '${ENV_VAR}'\n"
" string: my_string\n"
" invalid: $${ENV_VAR}\n"
" invalid_env: $$ENV_VAR\n"
" invalid_double_env: $${ENV_VAR}$${ENV_VAR}\n"
" invalid_embedded_env: $${${ENV_VAR}}\n"
" invalid_valid_env: $${ENV_VAR}${ENV_VAR}\n"
" escaped: \"${ENV_VAR}\"\n"
" subvalue:\n"
" subvalue2:\n"
" boolean: ${UNSED_XX_X_X_VAR}\n"
"base_value_2:\n"
" sample_list:\n"
" - ${ENV_VAR}\n"
" - ' ${ENV_VAR}'\n"
" - '${ENV_VAR} '\n"
" - $UNSED_XX_X_X_VAR\n"
"paths:\n"
" - ${ENV_VAR}/foo\n"
" - $ENV_VAR/foo\n"
" - /foo/${ENV_VAR}/\n"
" - /${ENV_VAR}/${ENV_VAR}${ENV_VAR}/foo\n"
" - ${ENV_VAR_EMBEDDED}/foo\n"
"is_test: ${ENV_VAR_BOOL}\n"
"num_test: ${ENV_VAR_INT}\n"
"empty_test: ${ENV_VAR_EMPTY}\n"
"plugins:\n"
" - name: k8saudit\n"
" library_path: /foo/${ENV_VAR}/libk8saudit.so\n"
" open_params: ${ENV_VAR_INT}\n";
"base_value:\n"
" id: $ENV_VAR\n"
" name: '${ENV_VAR}'\n"
" string: my_string\n"
" invalid: $${ENV_VAR}\n"
" invalid_env: $$ENV_VAR\n"
" invalid_double_env: $${ENV_VAR}$${ENV_VAR}\n"
" invalid_embedded_env: $${${ENV_VAR}}\n"
" invalid_valid_env: $${ENV_VAR}${ENV_VAR}\n"
" escaped: \"${ENV_VAR}\"\n"
" subvalue:\n"
" subvalue2:\n"
" boolean: ${UNSED_XX_X_X_VAR}\n"
"base_value_2:\n"
" sample_list:\n"
" - ${ENV_VAR}\n"
" - ' ${ENV_VAR}'\n"
" - '${ENV_VAR} '\n"
" - $UNSED_XX_X_X_VAR\n"
"paths:\n"
" - ${ENV_VAR}/foo\n"
" - $ENV_VAR/foo\n"
" - /foo/${ENV_VAR}/\n"
" - /${ENV_VAR}/${ENV_VAR}${ENV_VAR}/foo\n"
" - ${ENV_VAR_EMBEDDED}/foo\n"
"is_test: ${ENV_VAR_BOOL}\n"
"num_test: ${ENV_VAR_INT}\n"
"empty_test: ${ENV_VAR_EMPTY}\n"
"plugins:\n"
" - name: k8saudit\n"
" library_path: /foo/${ENV_VAR}/libk8saudit.so\n"
" open_params: ${ENV_VAR_INT}\n";
yaml_helper conf;
conf.load_from_string(env_var_sample_yaml);
@@ -95,84 +94,112 @@ TEST(Configuration, configuration_environment_variables)
auto base_value_string = conf.get_scalar<std::string>("base_value.string", default_value);
ASSERT_EQ(base_value_string, "my_string");
/* Test fetching of escaped environment variable format. Should return the string as-is after stripping the leading `$` */
/* Test fetching of escaped environment variable format. Should return the string as-is after
* stripping the leading `$` */
auto base_value_invalid = conf.get_scalar<std::string>("base_value.invalid", default_value);
ASSERT_EQ(base_value_invalid, "${ENV_VAR}");
/* Test fetching of invalid escaped environment variable format. Should return the string as-is */
auto base_value_invalid_env = conf.get_scalar<std::string>("base_value.invalid_env", default_value);
/* Test fetching of invalid escaped environment variable format. Should return the string as-is
*/
auto base_value_invalid_env =
conf.get_scalar<std::string>("base_value.invalid_env", default_value);
ASSERT_EQ(base_value_invalid_env, "$$ENV_VAR");
/* Test fetching of 2 escaped environment variables side by side. Should return the string as-is after stripping the leading `$` */
auto base_value_double_invalid = conf.get_scalar<std::string>("base_value.invalid_double_env", default_value);
/* Test fetching of 2 escaped environment variables side by side. Should return the string as-is
* after stripping the leading `$` */
auto base_value_double_invalid =
conf.get_scalar<std::string>("base_value.invalid_double_env", default_value);
ASSERT_EQ(base_value_double_invalid, "${ENV_VAR}${ENV_VAR}");
/*
* Test fetching of escaped environment variable format with inside an env variable.
* Should return the string as-is after stripping the leading `$` with the resolved env variable within
* Test fetching of escaped environment variable format with inside an env variable.
* Should return the string as-is after stripping the leading `$` with the resolved env variable
* within
*/
auto base_value_embedded_invalid = conf.get_scalar<std::string>("base_value.invalid_embedded_env", default_value);
auto base_value_embedded_invalid =
conf.get_scalar<std::string>("base_value.invalid_embedded_env", default_value);
ASSERT_EQ(base_value_embedded_invalid, "${" + env_var_value + "}");
/*
* Test fetching of an escaped env variable plus an env variable side by side.
* Should return the escaped one trimming the leading `$` plus the second one resolved.
* Test fetching of an escaped env variable plus an env variable side by side.
* Should return the escaped one trimming the leading `$` plus the second one resolved.
*/
auto base_value_valid_invalid = conf.get_scalar<std::string>("base_value.invalid_valid_env", default_value);
auto base_value_valid_invalid =
conf.get_scalar<std::string>("base_value.invalid_valid_env", default_value);
ASSERT_EQ(base_value_valid_invalid, "${ENV_VAR}" + env_var_value);
/* Test fetching of strings that contain environment variables */
auto base_value_id = conf.get_scalar<std::string>("base_value.id", default_value);
ASSERT_EQ(base_value_id, "$ENV_VAR"); // Does not follow the `${VAR}` format, so it should be treated as a regular string
ASSERT_EQ(base_value_id, "$ENV_VAR"); // Does not follow the `${VAR}` format, so it should be
// treated as a regular string
auto base_value_name = conf.get_scalar<std::string>("base_value.name", default_value);
ASSERT_EQ(base_value_name, env_var_value); // Proper environment variable format
ASSERT_EQ(base_value_name, env_var_value); // Proper environment variable format
auto base_value_escaped = conf.get_scalar<std::string>("base_value.escaped", default_value);
ASSERT_EQ(base_value_escaped, env_var_value); // Environment variable within quotes
ASSERT_EQ(base_value_escaped, env_var_value); // Environment variable within quotes
/* Test fetching of an undefined environment variable. Resolves to empty string. */
auto unknown_boolean = conf.get_scalar<std::string>("base_value.subvalue.subvalue2.boolean", default_value);
auto unknown_boolean =
conf.get_scalar<std::string>("base_value.subvalue.subvalue2.boolean", default_value);
ASSERT_EQ(unknown_boolean, "");
/* Test fetching of environment variables from a list */
auto base_value_2_list_0 = conf.get_scalar<std::string>("base_value_2.sample_list[0]", default_value);
ASSERT_EQ(base_value_2_list_0, env_var_value); // Proper environment variable format
auto base_value_2_list_0 =
conf.get_scalar<std::string>("base_value_2.sample_list[0]", default_value);
ASSERT_EQ(base_value_2_list_0, env_var_value); // Proper environment variable format
auto base_value_2_list_1 = conf.get_scalar<std::string>("base_value_2.sample_list[1]", default_value);
ASSERT_EQ(base_value_2_list_1, " " + env_var_value); // Environment variable preceded by a space, still extracted env var with leading space
auto base_value_2_list_1 =
conf.get_scalar<std::string>("base_value_2.sample_list[1]", default_value);
ASSERT_EQ(base_value_2_list_1,
" " + env_var_value); // Environment variable preceded by a space, still extracted
// env var with leading space
auto base_value_2_list_2 = conf.get_scalar<std::string>("base_value_2.sample_list[2]", default_value);
ASSERT_EQ(base_value_2_list_2, env_var_value + " "); // Environment variable followed by a space, still extracted env var with trailing space
auto base_value_2_list_2 =
conf.get_scalar<std::string>("base_value_2.sample_list[2]", default_value);
ASSERT_EQ(base_value_2_list_2,
env_var_value + " "); // Environment variable followed by a space, still extracted
// env var with trailing space
auto base_value_2_list_3 = conf.get_scalar<std::string>("base_value_2.sample_list[3]", default_value);
ASSERT_EQ(base_value_2_list_3, "$UNSED_XX_X_X_VAR"); // Does not follow the `${VAR}` format, so should be treated as a regular string
auto base_value_2_list_3 =
conf.get_scalar<std::string>("base_value_2.sample_list[3]", default_value);
ASSERT_EQ(base_value_2_list_3, "$UNSED_XX_X_X_VAR"); // Does not follow the `${VAR}` format, so
// should be treated as a regular string
/* Test expansion of environment variables within strings */
auto path_list_0 = conf.get_scalar<std::string>("paths[0]", default_value);
ASSERT_EQ(path_list_0, env_var_value + "/foo"); // Even if env var is part of bigger string, it gets expanded
ASSERT_EQ(
path_list_0,
env_var_value + "/foo"); // Even if env var is part of bigger string, it gets expanded
auto path_list_1 = conf.get_scalar<std::string>("paths[1]", default_value);
ASSERT_EQ(path_list_1, "$ENV_VAR/foo"); // Does not follow the `${VAR}` format, so should be treated as a regular string
ASSERT_EQ(path_list_1, "$ENV_VAR/foo"); // Does not follow the `${VAR}` format, so should be
// treated as a regular string
auto path_list_2 = conf.get_scalar<std::string>("paths[2]", default_value);
ASSERT_EQ(path_list_2, "/foo/" + env_var_value + "/"); // Even when env var is in the middle of a string. it gets expanded
ASSERT_EQ(path_list_2,
"/foo/" + env_var_value +
"/"); // Even when env var is in the middle of a string. it gets expanded
auto path_list_3 = conf.get_scalar<std::string>("paths[3]", default_value);
ASSERT_EQ(path_list_3, "/" + env_var_value + "/" + env_var_value + env_var_value + "/foo"); // Even when the string contains multiple env vars they are correctly expanded
ASSERT_EQ(path_list_3,
"/" + env_var_value + "/" + env_var_value + env_var_value +
"/foo"); // Even when the string contains multiple env vars they are
// correctly expanded
auto path_list_4 = conf.get_scalar<std::string>("paths[4]", default_value);
ASSERT_EQ(path_list_4, env_var_value + "/foo"); // Even when the env var contains another env var, it gets correctly double-expanded
ASSERT_EQ(path_list_4, env_var_value + "/foo"); // Even when the env var contains another env
// var, it gets correctly double-expanded
/* Check that variable expansion is type-aware */
auto boolean = conf.get_scalar<bool>("is_test", false);
ASSERT_EQ(boolean, true); // `true` can be parsed to bool.
ASSERT_EQ(boolean, true); // `true` can be parsed to bool.
auto boolean_as_str = conf.get_scalar<std::string>("is_test", "false");
ASSERT_EQ(boolean_as_str, "true"); // `true` can be parsed to string.
ASSERT_EQ(boolean_as_str, "true"); // `true` can be parsed to string.
auto boolean_as_int = conf.get_scalar<int32_t>("is_test", 0);
ASSERT_EQ(boolean_as_int, 0); // `true` cannot be parsed to integer.
ASSERT_EQ(boolean_as_int, 0); // `true` cannot be parsed to integer.
auto integer = conf.get_scalar<int32_t>("num_test", -1);
ASSERT_EQ(integer, 12);
@@ -182,9 +209,11 @@ TEST(Configuration, configuration_environment_variables)
ASSERT_EQ(empty_default_str, "");
std::list<falco_configuration::plugin_config> plugins;
conf.get_sequence<std::list<falco_configuration::plugin_config>>(plugins, std::string("plugins"));
std::vector<falco_configuration::plugin_config> m_plugins{ std::make_move_iterator(std::begin(plugins)),
std::make_move_iterator(std::end(plugins)) };
conf.get_sequence<std::list<falco_configuration::plugin_config>>(plugins,
std::string("plugins"));
std::vector<falco_configuration::plugin_config> m_plugins{
std::make_move_iterator(std::begin(plugins)),
std::make_move_iterator(std::end(plugins))};
ASSERT_EQ(m_plugins[0].m_name, "k8saudit");
ASSERT_EQ(m_plugins[0].m_library_path, "/foo/" + env_var_value + "/libk8saudit.so");
ASSERT_EQ(m_plugins[0].m_open_params, "12");

View File

@@ -18,8 +18,7 @@ limitations under the License.
#include <gtest/gtest.h>
#include <falco/configuration.h>
TEST(ConfigurationRuleOutputOptions, parse_yaml)
{
TEST(ConfigurationRuleOutputOptions, parse_yaml) {
falco_configuration falco_config;
ASSERT_NO_THROW(falco_config.init_from_content(R"(
append_output:
@@ -44,7 +43,8 @@ append_output:
- ka.verb
- static_field: "static content"
)", {}));
)",
{}));
EXPECT_EQ(falco_config.m_append_output.size(), 3);
@@ -53,17 +53,22 @@ append_output:
EXPECT_EQ(falco_config.m_append_output[0].m_tags.count("persistence"), 1);
EXPECT_EQ(falco_config.m_append_output[0].m_rule, "some rule name");
EXPECT_EQ(falco_config.m_append_output[0].m_formatted_fields.size(), 0);
EXPECT_EQ(falco_config.m_append_output[0].m_format, "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[0].m_format,
"gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_tags.size(), 2);
EXPECT_EQ(falco_config.m_append_output[1].m_tags.count("persistence"), 1);
EXPECT_EQ(falco_config.m_append_output[1].m_tags.count("execution"), 1);
EXPECT_EQ(falco_config.m_append_output[1].m_format, "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_format,
"gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields.size(), 3);
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[2]"], "%proc.aname[2]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[3]"], "%proc.aname[3]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[4]"], "%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[2]"],
"%proc.aname[2]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[3]"],
"%proc.aname[3]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[4]"],
"%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[2].m_source, "k8s_audit");
@@ -74,15 +79,15 @@ append_output:
EXPECT_EQ(falco_config.m_append_output[2].m_raw_fields.count("ka.verb"), 1);
}
TEST(ConfigurationRuleOutputOptions, cli_options)
{
TEST(ConfigurationRuleOutputOptions, cli_options) {
falco_configuration falco_config;
ASSERT_NO_THROW(falco_config.init_from_content("",
std::vector<std::string>{
R"(append_output[]={"match": {"source": "syscall", "tags": ["persistence"], "rule": "some rule name"}, "extra_output": "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]"})",
R"(append_output[]={"match": {"tags": ["persistence", "execution"]}, "extra_fields": [{"proc.aname[2]": "%proc.aname[2]"}, {"proc.aname[3]": "%proc.aname[3]"}, {"proc.aname[4]": "%proc.aname[4]"}], "extra_output": "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]"})",
R"(append_output[]={"match": {"source": "k8s_audit"}, "extra_fields": ["ka.verb", {"static_field": "static content"}]})"}));
ASSERT_NO_THROW(falco_config.init_from_content(
"",
std::vector<std::string>{
R"(append_output[]={"match": {"source": "syscall", "tags": ["persistence"], "rule": "some rule name"}, "extra_output": "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]"})",
R"(append_output[]={"match": {"tags": ["persistence", "execution"]}, "extra_fields": [{"proc.aname[2]": "%proc.aname[2]"}, {"proc.aname[3]": "%proc.aname[3]"}, {"proc.aname[4]": "%proc.aname[4]"}], "extra_output": "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]"})",
R"(append_output[]={"match": {"source": "k8s_audit"}, "extra_fields": ["ka.verb", {"static_field": "static content"}]})"}));
EXPECT_EQ(falco_config.m_append_output.size(), 3);
@@ -91,17 +96,22 @@ TEST(ConfigurationRuleOutputOptions, cli_options)
EXPECT_EQ(falco_config.m_append_output[0].m_tags.count("persistence"), 1);
EXPECT_EQ(falco_config.m_append_output[0].m_rule, "some rule name");
EXPECT_EQ(falco_config.m_append_output[0].m_formatted_fields.size(), 0);
EXPECT_EQ(falco_config.m_append_output[0].m_format, "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[0].m_format,
"gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_tags.size(), 2);
EXPECT_EQ(falco_config.m_append_output[1].m_tags.count("persistence"), 1);
EXPECT_EQ(falco_config.m_append_output[1].m_tags.count("execution"), 1);
EXPECT_EQ(falco_config.m_append_output[1].m_format, "gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_format,
"gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields.size(), 3);
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[2]"], "%proc.aname[2]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[3]"], "%proc.aname[3]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[4]"], "%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[2]"],
"%proc.aname[2]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[3]"],
"%proc.aname[3]");
EXPECT_EQ(falco_config.m_append_output[1].m_formatted_fields["proc.aname[4]"],
"%proc.aname[4]");
EXPECT_EQ(falco_config.m_append_output[2].m_source, "k8s_audit");

View File

@@ -18,8 +18,7 @@ limitations under the License.
#include <gtest/gtest.h>
#include <falco/configuration.h>
TEST(ConfigurationRuleSelection, parse_yaml)
{
TEST(ConfigurationRuleSelection, parse_yaml) {
falco_configuration falco_config;
ASSERT_NO_THROW(falco_config.init_from_content(R"(
rules:
@@ -31,44 +30,57 @@ rules:
- enable:
rule: 'hello*'
)", {}));
)",
{}));
EXPECT_EQ(falco_config.m_rules_selection.size(), 3);
EXPECT_EQ(falco_config.m_rules_selection[0].m_op, falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[0].m_op,
falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[0].m_rule, "Terminal Shell in Container");
EXPECT_EQ(falco_config.m_rules_selection[1].m_op, falco_configuration::rule_selection_operation::disable);
EXPECT_EQ(falco_config.m_rules_selection[1].m_op,
falco_configuration::rule_selection_operation::disable);
EXPECT_EQ(falco_config.m_rules_selection[1].m_tag, "experimental");
EXPECT_EQ(falco_config.m_rules_selection[2].m_op, falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[2].m_op,
falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[2].m_rule, "hello*");
}
TEST(ConfigurationRuleSelection, cli_options)
{
TEST(ConfigurationRuleSelection, cli_options) {
falco_configuration falco_config;
ASSERT_NO_THROW(falco_config.init_from_content("", std::vector<std::string>{"rules[].disable.tag=maturity_incubating", "rules[].enable.rule=Adding ssh keys to authorized_keys"}));
ASSERT_NO_THROW(falco_config.init_from_content(
"",
std::vector<std::string>{"rules[].disable.tag=maturity_incubating",
"rules[].enable.rule=Adding ssh keys to authorized_keys"}));
EXPECT_EQ(falco_config.m_rules_selection.size(), 2);
EXPECT_EQ(falco_config.m_rules_selection[0].m_op, falco_configuration::rule_selection_operation::disable);
EXPECT_EQ(falco_config.m_rules_selection[0].m_op,
falco_configuration::rule_selection_operation::disable);
EXPECT_EQ(falco_config.m_rules_selection[0].m_tag, "maturity_incubating");
EXPECT_EQ(falco_config.m_rules_selection[1].m_op, falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[1].m_op,
falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[1].m_rule, "Adding ssh keys to authorized_keys");
}
TEST(ConfigurationRuleSelection, cli_options_object)
{
TEST(ConfigurationRuleSelection, cli_options_object) {
falco_configuration falco_config;
ASSERT_NO_THROW(falco_config.init_from_content("", std::vector<std::string>{R"(rules[]={"disable": {"tag": "maturity_incubating"}})", R"(rules[]={"enable": {"rule": "Adding ssh keys to authorized_keys"}})"}));
ASSERT_NO_THROW(falco_config.init_from_content(
"",
std::vector<std::string>{
R"(rules[]={"disable": {"tag": "maturity_incubating"}})",
R"(rules[]={"enable": {"rule": "Adding ssh keys to authorized_keys"}})"}));
EXPECT_EQ(falco_config.m_rules_selection.size(), 2);
EXPECT_EQ(falco_config.m_rules_selection[0].m_op, falco_configuration::rule_selection_operation::disable);
EXPECT_EQ(falco_config.m_rules_selection[0].m_op,
falco_configuration::rule_selection_operation::disable);
EXPECT_EQ(falco_config.m_rules_selection[0].m_tag, "maturity_incubating");
EXPECT_EQ(falco_config.m_rules_selection[1].m_op, falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[1].m_op,
falco_configuration::rule_selection_operation::enable);
EXPECT_EQ(falco_config.m_rules_selection[1].m_rule, "Adding ssh keys to authorized_keys");
}

View File

@@ -18,94 +18,142 @@ limitations under the License.
#include <gtest/gtest.h>
#include <falco/configuration.h>
#include <falco_test_var.h>
#include <nlohmann/json.hpp>
#define EXPECT_VALIDATION_STATUS(res, status) \
do { \
for(const auto& pair : res) { \
auto validation_status = pair.second; \
#define EXPECT_VALIDATION_STATUS(res, status) \
do { \
for(const auto& pair : res) { \
auto validation_status = pair.second; \
EXPECT_TRUE(sinsp_utils::startswith(validation_status, status)) << validation_status; \
} \
} \
while (0)
} \
} while(0)
// Read Falco config from current repo-path
TEST(Configuration, schema_validate_config)
{
TEST(Configuration, schema_validate_config) {
falco_configuration falco_config;
config_loaded_res res;
if (!std::filesystem::exists(TEST_FALCO_CONFIG))
{
if(!std::filesystem::exists(TEST_FALCO_CONFIG)) {
GTEST_SKIP() << "Falco config not present under " << TEST_FALCO_CONFIG;
}
EXPECT_NO_THROW(res = falco_config.init_from_file(TEST_FALCO_CONFIG, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
}
TEST(Configuration, schema_ok)
{
TEST(Configuration, schema_ok) {
falco_configuration falco_config;
config_loaded_res res;
/* OK YAML */
std::string config =
"falco_libs:\n"
" thread_table_size: 50\n";
"falco_libs:\n"
" thread_table_size: 50\n";
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
}
TEST(Configuration, schema_wrong_key)
{
TEST(Configuration, schema_wrong_key) {
falco_configuration falco_config;
config_loaded_res res;
/* Miss-typed key YAML */
std::string config =
"falco_libss:\n"
" thread_table_size: 50\n";
"falco_libss:\n"
" thread_table_size: 50\n";
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_failed);
}
TEST(Configuration, schema_wrong_type)
{
TEST(Configuration, schema_wrong_type) {
falco_configuration falco_config;
/* Wrong value type YAML */
std::string config =
"falco_libs: 512\n";
std::string config = "falco_libs: 512\n";
// We expect an exception since `falco_configuration::load_yaml()`
// will fail to parse `falco_libs` node.
ASSERT_ANY_THROW(falco_config.init_from_content(config, {}));
}
TEST(Configuration, schema_wrong_embedded_key)
{
TEST(Configuration, schema_wrong_embedded_key) {
falco_configuration falco_config;
config_loaded_res res;
/* Miss-typed sub-key YAML */
std::string config =
"falco_libs:\n"
" thread_table_sizeee: 50\n";
"falco_libs:\n"
" thread_table_sizeee: 50\n";
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_failed);
}
TEST(Configuration, schema_yaml_helper_validator)
{
TEST(Configuration, plugin_init_config) {
falco_configuration falco_config;
config_loaded_res res;
std::string config = R"(
plugins:
- name: k8saudit
library_path: libk8saudit.so
init_config:
maxEventSize: 262144
sslCertificate: /etc/falco/falco.pem
)";
auto plugin_config_json = nlohmann::json::parse(
R"({"maxEventSize": 262144, "sslCertificate": "/etc/falco/falco.pem"})");
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
auto parsed_init_config = nlohmann::json::parse(falco_config.m_plugins[0].m_init_config);
EXPECT_EQ(parsed_init_config, plugin_config_json);
config = R"(
plugins:
- name: k8saudit
library_path: libk8saudit.so
init_config: '{"maxEventSize": 262144, "sslCertificate": "/etc/falco/falco.pem"}'
)";
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
parsed_init_config = nlohmann::json::parse(falco_config.m_plugins[0].m_init_config);
EXPECT_EQ(parsed_init_config, plugin_config_json);
config = R"(
plugins:
- name: k8saudit
library_path: libk8saudit.so
init_config: ""
)";
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
EXPECT_EQ(falco_config.m_plugins[0].m_init_config, "");
config = R"(
plugins:
- name: k8saudit
library_path: libk8saudit.so
init_config: null
)";
EXPECT_NO_THROW(res = falco_config.init_from_content(config, {}));
EXPECT_VALIDATION_STATUS(res, yaml_helper::validation_ok);
EXPECT_EQ(falco_config.m_plugins[0].m_init_config, "");
}
TEST(Configuration, schema_yaml_helper_validator) {
yaml_helper conf;
falco_configuration falco_config;
/* Broken YAML */
std::string sample_yaml =
"falco_libs:\n"
" thread_table_size: 50\n";
"falco_libs:\n"
" thread_table_size: 50\n";
// Ok, we don't ask for any validation
EXPECT_NO_THROW(conf.load_from_string(sample_yaml));
@@ -121,4 +169,4 @@ TEST(Configuration, schema_yaml_helper_validator)
// We pass everything
EXPECT_NO_THROW(conf.load_from_string(sample_yaml, falco_config.m_config_schema, &validation));
EXPECT_EQ(validation[0], yaml_helper::validation_ok);
}
}

View File

@@ -1,7 +1,6 @@
#include "test_falco_engine.h"
test_falco_engine::test_falco_engine()
{
test_falco_engine::test_falco_engine() {
// create a falco engine ready to load the ruleset
m_filter_factory = std::make_shared<sinsp_filter_factory>(&m_inspector, m_filterlist);
m_formatter_factory = std::make_shared<sinsp_evt_formatter_factory>(&m_inspector, m_filterlist);
@@ -9,8 +8,8 @@ test_falco_engine::test_falco_engine()
m_engine->add_source(m_sample_source, m_filter_factory, m_formatter_factory);
}
bool test_falco_engine::load_rules(const std::string& rules_content, const std::string& rules_filename)
{
bool test_falco_engine::load_rules(const std::string& rules_content,
const std::string& rules_filename) {
bool ret = false;
falco::load_result::rules_contents_t rc = {{rules_filename, rules_content}};
m_load_result = m_engine->load_rules(rules_content, rules_filename);
@@ -18,8 +17,7 @@ bool test_falco_engine::load_rules(const std::string& rules_content, const std::
m_load_result_json = m_load_result->as_json(rc);
ret = m_load_result->successful();
if (ret)
{
if(ret) {
m_engine->enable_rule("", true, m_sample_ruleset);
}
@@ -27,30 +25,24 @@ bool test_falco_engine::load_rules(const std::string& rules_content, const std::
}
// This must be kept in line with the (private) falco_engine::s_default_ruleset
uint64_t test_falco_engine::num_rules_for_ruleset(const std::string& ruleset)
{
uint64_t test_falco_engine::num_rules_for_ruleset(const std::string& ruleset) {
return m_engine->num_rules_for_ruleset(ruleset);
}
bool test_falco_engine::has_warnings() const
{
bool test_falco_engine::has_warnings() const {
return m_load_result->has_warnings();
}
bool test_falco_engine::check_warning_message(const std::string& warning_msg) const
{
if(!m_load_result->has_warnings())
{
bool test_falco_engine::check_warning_message(const std::string& warning_msg) const {
if(!m_load_result->has_warnings()) {
return false;
}
for(const auto &warn : m_load_result_json["warnings"])
{
for(const auto& warn : m_load_result_json["warnings"]) {
std::string msg = warn["message"];
// Debug:
// printf("msg: %s\n", msg.c_str());
if(msg.find(warning_msg) != std::string::npos)
{
if(msg.find(warning_msg) != std::string::npos) {
return true;
}
}
@@ -58,21 +50,17 @@ bool test_falco_engine::check_warning_message(const std::string& warning_msg) co
return false;
}
bool test_falco_engine::check_error_message(const std::string& error_msg) const
{
bool test_falco_engine::check_error_message(const std::string& error_msg) const {
// if the loading is successful there are no errors
if(m_load_result->successful())
{
if(m_load_result->successful()) {
return false;
}
for(const auto &err : m_load_result_json["errors"])
{
for(const auto& err : m_load_result_json["errors"]) {
std::string msg = err["message"];
// Debug:
// printf("msg: %s\n", msg.c_str());
if(msg.find(error_msg) != std::string::npos)
{
if(msg.find(error_msg) != std::string::npos) {
return true;
}
}
@@ -80,20 +68,20 @@ bool test_falco_engine::check_error_message(const std::string& error_msg) const
return false;
}
std::string test_falco_engine::get_compiled_rule_condition(std::string rule_name) const
{
std::string test_falco_engine::get_compiled_rule_condition(std::string rule_name) const {
auto rule_description = m_engine->describe_rule(&rule_name, {});
return rule_description["rules"][0]["details"]["condition_compiled"].template get<std::string>();
return rule_description["rules"][0]["details"]["condition_compiled"]
.template get<std::string>();
}
std::string test_falco_engine::get_compiled_rule_output(std::string rule_name) const
{
std::string test_falco_engine::get_compiled_rule_output(std::string rule_name) const {
auto rule_description = m_engine->describe_rule(&rule_name, {});
return rule_description["rules"][0]["details"]["output_compiled"].template get<std::string>();
}
std::unordered_map<std::string, std::string> test_falco_engine::get_compiled_rule_formatted_fields(std::string rule_name) const
{
std::unordered_map<std::string, std::string> test_falco_engine::get_compiled_rule_formatted_fields(
std::string rule_name) const {
auto rule_description = m_engine->describe_rule(&rule_name, {});
return rule_description["rules"][0]["details"]["extra_output_formatted_fields"].template get<std::unordered_map<std::string, std::string>>();
return rule_description["rules"][0]["details"]["extra_output_formatted_fields"]
.template get<std::unordered_map<std::string, std::string>>();
}

View File

@@ -8,8 +8,7 @@
#include <gtest/gtest.h>
#include <unordered_map>
class test_falco_engine : public testing::Test
{
class test_falco_engine : public testing::Test {
protected:
test_falco_engine();
@@ -21,7 +20,8 @@ protected:
bool check_error_message(const std::string& error_msg) const;
std::string get_compiled_rule_condition(std::string rule_name = "") const;
std::string get_compiled_rule_output(std::string rule_name = "") const;
std::unordered_map<std::string, std::string> get_compiled_rule_formatted_fields(std::string rule_name) const;
std::unordered_map<std::string, std::string> get_compiled_rule_formatted_fields(
std::string rule_name) const;
std::string m_sample_ruleset = "sample-ruleset";
std::string m_sample_source = falco_common::syscall_source;

View File

@@ -2,47 +2,40 @@
#
# Copyright (C) 2023 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
# 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.
# 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.
add_library(falco_engine STATIC
falco_common.cpp
falco_engine.cpp
falco_load_result.cpp
falco_utils.cpp
filter_ruleset.cpp
evttype_index_ruleset.cpp
formats.cpp
filter_details_resolver.cpp
filter_macro_resolver.cpp
filter_warning_resolver.cpp
logger.cpp
stats_manager.cpp
rule_loader.cpp
rule_loader_reader.cpp
rule_loader_collector.cpp
rule_loader_compiler.cpp
add_library(
falco_engine STATIC
falco_common.cpp
falco_engine.cpp
falco_load_result.cpp
falco_utils.cpp
filter_ruleset.cpp
evttype_index_ruleset.cpp
formats.cpp
filter_details_resolver.cpp
filter_macro_resolver.cpp
filter_warning_resolver.cpp
logger.cpp
stats_manager.cpp
rule_loader.cpp
rule_loader_reader.cpp
rule_loader_collector.cpp
rule_loader_compiler.cpp
)
if (EMSCRIPTEN)
if(EMSCRIPTEN)
target_compile_options(falco_engine PRIVATE "-sDISABLE_EXCEPTION_CATCHING=0")
endif()
target_include_directories(falco_engine
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${TBB_INCLUDE_DIR}
)
target_include_directories(falco_engine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${TBB_INCLUDE_DIR})
target_link_libraries(falco_engine
PUBLIC
sinsp
nlohmann_json::nlohmann_json
yaml-cpp
)
target_link_libraries(falco_engine PUBLIC sinsp nlohmann_json::nlohmann_json yaml-cpp)

View File

@@ -21,57 +21,43 @@ limitations under the License.
#include <algorithm>
evttype_index_ruleset::evttype_index_ruleset(
std::shared_ptr<sinsp_filter_factory> f):
m_filter_factory(f)
{
}
evttype_index_ruleset::evttype_index_ruleset(std::shared_ptr<sinsp_filter_factory> f):
m_filter_factory(f) {}
evttype_index_ruleset::~evttype_index_ruleset()
{
}
evttype_index_ruleset::~evttype_index_ruleset() {}
void evttype_index_ruleset::add(
const falco_rule& rule,
std::shared_ptr<sinsp_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition)
{
try
{
void evttype_index_ruleset::add(const falco_rule &rule,
std::shared_ptr<sinsp_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) {
try {
auto wrap = std::make_shared<evttype_index_wrapper>();
wrap->m_rule = rule;
wrap->m_filter = filter;
if(rule.source == falco_common::syscall_source)
{
if(rule.source == falco_common::syscall_source) {
wrap->m_sc_codes = libsinsp::filter::ast::ppm_sc_codes(condition.get());
wrap->m_event_codes = libsinsp::filter::ast::ppm_event_codes(condition.get());
}
else
{
} else {
wrap->m_sc_codes = {};
wrap->m_event_codes = {ppm_event_code::PPME_PLUGINEVENT_E};
}
wrap->m_event_codes.insert(ppm_event_code::PPME_ASYNCEVENT_E);
add_wrapper(wrap);
}
catch (const sinsp_exception& e)
{
} catch(const sinsp_exception &e) {
throw falco_exception(std::string(e.what()));
}
}
void evttype_index_ruleset::on_loading_complete()
{
void evttype_index_ruleset::on_loading_complete() {
print_enabled_rules_falco_logger();
}
bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt, filter_wrapper_list &wrappers, uint16_t ruleset_id, falco_rule &match)
{
for(auto &wrap : wrappers)
{
if(wrap->m_filter->run(evt))
{
bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt,
filter_wrapper_list &wrappers,
uint16_t ruleset_id,
falco_rule &match) {
for(auto &wrap : wrappers) {
if(wrap->m_filter->run(evt)) {
match = wrap->m_rule;
return true;
}
@@ -80,14 +66,14 @@ bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt, filter_wrapper_list &wr
return false;
}
bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt, filter_wrapper_list &wrappers, uint16_t ruleset_id, std::vector<falco_rule> &matches)
{
bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt,
filter_wrapper_list &wrappers,
uint16_t ruleset_id,
std::vector<falco_rule> &matches) {
bool match_found = false;
for(auto &wrap : wrappers)
{
if(wrap->m_filter->run(evt))
{
for(auto &wrap : wrappers) {
if(wrap->m_filter->run(evt)) {
matches.push_back(wrap->m_rule);
match_found = true;
}
@@ -96,16 +82,15 @@ bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt, filter_wrapper_list &wr
return match_found;
}
void evttype_index_ruleset::print_enabled_rules_falco_logger()
{
void evttype_index_ruleset::print_enabled_rules_falco_logger() {
falco_logger::log(falco_logger::level::DEBUG, "Enabled rules:\n");
auto logger = [](std::shared_ptr<evttype_index_wrapper> wrap)
{
auto logger = [](std::shared_ptr<evttype_index_wrapper> wrap) {
falco_logger::log(falco_logger::level::DEBUG, std::string(" ") + wrap->name() + "\n");
};
uint64_t num_filters = iterate(logger);
falco_logger::log(falco_logger::level::DEBUG, "(" + std::to_string(num_filters) + ") enabled rules in total\n");
falco_logger::log(falco_logger::level::DEBUG,
"(" + std::to_string(num_filters) + ") enabled rules in total\n");
}

View File

@@ -24,12 +24,11 @@ limitations under the License.
#include <vector>
/*!
\brief A filter_ruleset that indexes enabled rules by event type,
and performs linear search on each event type bucket
\brief A filter_ruleset that indexes enabled rules by event type,
and performs linear search on each event type bucket
*/
struct evttype_index_wrapper
{
struct evttype_index_wrapper {
const std::string &name() { return m_rule.name; }
const std::set<std::string> &tags() { return m_rule.tags; }
const libsinsp::events::set<ppm_sc_code> &sc_codes() { return m_sc_codes; }
@@ -41,23 +40,27 @@ struct evttype_index_wrapper
std::shared_ptr<sinsp_filter> m_filter;
};
class evttype_index_ruleset : public indexable_ruleset<evttype_index_wrapper>
{
class evttype_index_ruleset : public indexable_ruleset<evttype_index_wrapper> {
public:
explicit evttype_index_ruleset(std::shared_ptr<sinsp_filter_factory> factory);
virtual ~evttype_index_ruleset();
// From filter_ruleset
void add(
const falco_rule& rule,
std::shared_ptr<sinsp_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) override;
void add(const falco_rule &rule,
std::shared_ptr<sinsp_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) override;
void on_loading_complete() override;
// From indexable_ruleset
bool run_wrappers(sinsp_evt *evt, filter_wrapper_list &wrappers, uint16_t ruleset_id, falco_rule &match) override;
bool run_wrappers(sinsp_evt *evt, filter_wrapper_list &wrappers, uint16_t ruleset_id, std::vector<falco_rule> &matches) override;
bool run_wrappers(sinsp_evt *evt,
filter_wrapper_list &wrappers,
uint16_t ruleset_id,
falco_rule &match) override;
bool run_wrappers(sinsp_evt *evt,
filter_wrapper_list &wrappers,
uint16_t ruleset_id,
std::vector<falco_rule> &matches) override;
// Print each enabled rule when running Falco with falco logger
// log_level=debug; invoked within on_loading_complete()
@@ -67,15 +70,12 @@ private:
std::shared_ptr<sinsp_filter_factory> m_filter_factory;
};
class evttype_index_ruleset_factory: public filter_ruleset_factory
{
class evttype_index_ruleset_factory : public filter_ruleset_factory {
public:
inline explicit evttype_index_ruleset_factory(
std::shared_ptr<sinsp_filter_factory> factory
): m_filter_factory(factory) { }
inline explicit evttype_index_ruleset_factory(std::shared_ptr<sinsp_filter_factory> factory):
m_filter_factory(factory) {}
inline std::shared_ptr<filter_ruleset> new_ruleset() override
{
inline std::shared_ptr<filter_ruleset> new_ruleset() override {
return std::make_shared<evttype_index_ruleset>(m_filter_factory);
}

View File

@@ -17,83 +17,57 @@ limitations under the License.
#include "falco_common.h"
static std::vector<std::string> priority_names = {
"Emergency",
"Alert",
"Critical",
"Error",
"Warning",
"Notice",
"Informational",
"Debug"
};
static std::vector<std::string> priority_names =
{"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debug"};
static std::vector<std::string> rule_matching_names = {
"first",
"all"
};
static std::vector<std::string> rule_matching_names = {"first", "all"};
bool falco_common::parse_priority(const std::string& v, priority_type& out)
{
for (size_t i = 0; i < priority_names.size(); i++)
{
bool falco_common::parse_priority(const std::string& v, priority_type& out) {
for(size_t i = 0; i < priority_names.size(); i++) {
// note: for legacy reasons, "Info" and "Informational" has been used
// interchangeably and ambiguously, so this is the only edge case for
// which we can't apply strict equality check
if (!strcasecmp(v.c_str(), priority_names[i].c_str())
|| (i == PRIORITY_INFORMATIONAL && !strcasecmp(v.c_str(), "info")))
{
out = (priority_type) i;
if(!strcasecmp(v.c_str(), priority_names[i].c_str()) ||
(i == PRIORITY_INFORMATIONAL && !strcasecmp(v.c_str(), "info"))) {
out = (priority_type)i;
return true;
}
}
return false;
}
falco_common::priority_type falco_common::parse_priority(const std::string& v)
{
falco_common::priority_type falco_common::parse_priority(const std::string& v) {
falco_common::priority_type out;
if (!parse_priority(v, out))
{
if(!parse_priority(v, out)) {
throw falco_exception("Unknown priority value: " + v);
}
return out;
}
bool falco_common::format_priority(priority_type v, std::string& out, bool shortfmt)
{
if ((size_t) v < priority_names.size())
{
if (v == PRIORITY_INFORMATIONAL && shortfmt)
{
bool falco_common::format_priority(priority_type v, std::string& out, bool shortfmt) {
if((size_t)v < priority_names.size()) {
if(v == PRIORITY_INFORMATIONAL && shortfmt) {
out = "Info";
}
else
{
out = priority_names[(size_t) v];
} else {
out = priority_names[(size_t)v];
}
return true;
}
return false;
}
std::string falco_common::format_priority(priority_type v, bool shortfmt)
{
std::string falco_common::format_priority(priority_type v, bool shortfmt) {
std::string out;
if(!format_priority(v, out, shortfmt))
{
if(!format_priority(v, out, shortfmt)) {
throw falco_exception("Unknown priority enum value: " + std::to_string(v));
}
return out;
}
bool falco_common::parse_rule_matching(const std::string& v, rule_matching& out)
{
for (size_t i = 0; i < rule_matching_names.size(); i++)
{
if (!strcasecmp(v.c_str(), rule_matching_names[i].c_str()))
{
out = (rule_matching) i;
bool falco_common::parse_rule_matching(const std::string& v, rule_matching& out) {
for(size_t i = 0; i < rule_matching_names.size(); i++) {
if(!strcasecmp(v.c_str(), rule_matching_names[i].c_str())) {
out = (rule_matching)i;
return true;
}
}

View File

@@ -36,41 +36,34 @@ limitations under the License.
// be of this type.
//
struct falco_exception : std::runtime_error
{
struct falco_exception : std::runtime_error {
using std::runtime_error::runtime_error;
};
namespace falco_common
{
namespace falco_common {
const std::string syscall_source = sinsp_syscall_event_source_name;
const std::string syscall_source = sinsp_syscall_event_source_name;
// Same as numbers/indices into the above vector
enum priority_type
{
PRIORITY_EMERGENCY = 0,
PRIORITY_ALERT = 1,
PRIORITY_CRITICAL = 2,
PRIORITY_ERROR = 3,
PRIORITY_WARNING = 4,
PRIORITY_NOTICE = 5,
PRIORITY_INFORMATIONAL = 6,
PRIORITY_DEBUG = 7
};
bool parse_priority(const std::string& v, priority_type& out);
priority_type parse_priority(const std::string& v);
bool format_priority(priority_type v, std::string& out, bool shortfmt=false);
std::string format_priority(priority_type v, bool shortfmt=false);
enum rule_matching
{
FIRST = 0,
ALL = 1
};
bool parse_rule_matching(const std::string& v, rule_matching& out);
// Same as numbers/indices into the above vector
enum priority_type {
PRIORITY_EMERGENCY = 0,
PRIORITY_ALERT = 1,
PRIORITY_CRITICAL = 2,
PRIORITY_ERROR = 3,
PRIORITY_WARNING = 4,
PRIORITY_NOTICE = 5,
PRIORITY_INFORMATIONAL = 6,
PRIORITY_DEBUG = 7
};
bool parse_priority(const std::string& v, priority_type& out);
priority_type parse_priority(const std::string& v);
bool format_priority(priority_type v, std::string& out, bool shortfmt = false);
std::string format_priority(priority_type v, bool shortfmt = false);
enum rule_matching { FIRST = 0, ALL = 1 };
bool parse_rule_matching(const std::string& v, rule_matching& out);
}; // namespace falco_common
typedef std::unordered_map<std::string, std::pair<std::string, bool>> extra_output_field_t;

File diff suppressed because it is too large Load Diff

View File

@@ -41,10 +41,9 @@ limitations under the License.
// handled in a separate class falco_outputs.
//
class falco_engine
{
class falco_engine {
public:
explicit falco_engine(bool seed_rng=true);
explicit falco_engine(bool seed_rng = true);
virtual ~falco_engine();
// A given engine has a version which identifies the fields
@@ -55,10 +54,9 @@ public:
// Engine version used to be represented as a simple progressive
// number. With the new semver schema, the number now represents
// the semver minor number. This function converts the legacy version
// the semver minor number. This function converts the legacy version
// number to the new semver schema.
static inline sinsp_version get_implicit_version(uint32_t minor)
{
static inline sinsp_version get_implicit_version(uint32_t minor) {
return rule_loader::reader::get_implicit_engine_version(minor);
}
@@ -80,7 +78,8 @@ public:
//
// Load rules and returns a result object.
//
std::unique_ptr<falco::load_result> load_rules(const std::string &rules_content, const std::string &name);
std::unique_ptr<falco::load_result> load_rules(const std::string &rules_content,
const std::string &name);
//
// Enable/Disable any rules matching the provided substring.
@@ -91,30 +90,42 @@ public:
// for different sets of rules being active at once.
// The rules are matched against the rulesets of all the defined sources.
//
void enable_rule(const std::string &substring, bool enabled, const std::string &ruleset = s_default_ruleset);
void enable_rule(const std::string &substring,
bool enabled,
const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule(const std::string &substring, bool enabled, const uint16_t ruleset_id);
// Like enable_rule, but the rule name must be an exact match.
void enable_rule_exact(const std::string &rule_name, bool enabled, const std::string &ruleset = s_default_ruleset);
void enable_rule_exact(const std::string &rule_name,
bool enabled,
const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule_exact(const std::string &rule_name, bool enabled, const uint16_t ruleset_id);
// Like enable_rule, but wildcards are supported and substrings are not matched
void enable_rule_wildcard(const std::string &rule_name, bool enabled, const std::string &ruleset = s_default_ruleset);
void enable_rule_wildcard(const std::string &rule_name,
bool enabled,
const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule_wildcard(const std::string &rule_name, bool enabled, const uint16_t ruleset_id);
void enable_rule_wildcard(const std::string &rule_name,
bool enabled,
const uint16_t ruleset_id);
//
// Enable/Disable any rules with any of the provided tags (set, exact matches only)
//
void enable_rule_by_tag(const std::set<std::string> &tags, bool enabled, const std::string &ruleset = s_default_ruleset);
void enable_rule_by_tag(const std::set<std::string> &tags,
bool enabled,
const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule_by_tag(const std::set<std::string> &tags, bool enabled, const uint16_t ruleset_id);
void enable_rule_by_tag(const std::set<std::string> &tags,
bool enabled,
const uint16_t ruleset_id);
//
// Must be called after the engine has been configured and all rulesets
@@ -147,12 +158,13 @@ public:
// Print details on the given rule. If rule is NULL, print
// details on all rules.
//
nlohmann::json describe_rule(std::string *rule_name, const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
nlohmann::json describe_rule(std::string *rule_name,
const std::vector<std::shared_ptr<sinsp_plugin>> &plugins) const;
//
// Return const /ref to rules stored in the Falco engine.
//
inline const indexed_vector<falco_rule>& get_rules() const { return m_rules; }
inline const indexed_vector<falco_rule> &get_rules() const { return m_rules; }
//
// Print statistics on how many events matched each rule.
@@ -160,9 +172,10 @@ public:
void print_stats() const;
//
// Return const /ref to stats_manager to access current rules stats (how many events matched each rule so far).
// Return const /ref to stats_manager to access current rules stats (how many events matched
// each rule so far).
//
const stats_manager& get_rule_stats_manager() const;
const stats_manager &get_rule_stats_manager() const;
//
// Set the sampling ratio, which can affect which events are
@@ -183,33 +196,27 @@ public:
// add k8s/container information to outputs when
// available.
//
void add_extra_output_format(
const std::string &format,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule,
bool replace_container_info
);
void add_extra_output_format(const std::string &format,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule,
bool replace_container_info);
// You can optionally add fields that will only show up in the object
// output (e.g. json, gRPC) alongside other output_fields
// and not in the text message output.
// You can add two types of fields: formatted which will act like
// an additional output format that appears in the output field
void add_extra_output_formatted_field(
const std::string &key,
const std::string &format,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule
);
void add_extra_output_formatted_field(const std::string &key,
const std::string &format,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule);
void add_extra_output_raw_field(
const std::string &key,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule
);
void add_extra_output_raw_field(const std::string &key,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule);
// Represents the result of matching an event against a set of
// rules.
@@ -249,7 +256,9 @@ public:
// concurrently with the same source_idx would inherently cause data races
// and lead to undefined behavior.
std::unique_ptr<std::vector<rule_result>> process_event(std::size_t source_idx,
sinsp_evt *ev, uint16_t ruleset_id, falco_common::rule_matching strategy);
sinsp_evt *ev,
uint16_t ruleset_id,
falco_common::rule_matching strategy);
//
// Wrapper assuming the default ruleset.
@@ -257,7 +266,8 @@ public:
// This inherits the same thread-safety guarantees.
//
std::unique_ptr<std::vector<rule_result>> process_event(std::size_t source_idx,
sinsp_evt *ev, falco_common::rule_matching strategy);
sinsp_evt *ev,
falco_common::rule_matching strategy);
//
// Configure the engine to support events with the provided
@@ -265,17 +275,17 @@ public:
// Return source index for fast lookup.
//
std::size_t add_source(const std::string &source,
std::shared_ptr<sinsp_filter_factory> filter_factory,
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory);
std::shared_ptr<sinsp_filter_factory> filter_factory,
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory);
//
// Equivalent to above, but allows specifying a ruleset factory
// for the newly added source.
//
std::size_t add_source(const std::string &source,
std::shared_ptr<sinsp_filter_factory> filter_factory,
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory,
std::shared_ptr<filter_ruleset_factory> ruleset_factory);
std::shared_ptr<sinsp_filter_factory> filter_factory,
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory,
std::shared_ptr<filter_ruleset_factory> ruleset_factory);
// Return whether or not there is a valid filter/formatter
// factory for this source.
@@ -285,25 +295,27 @@ public:
// Given a source, return a formatter factory that can create
// filters for events of that source.
//
std::shared_ptr<sinsp_filter_factory> filter_factory_for_source(const std::string& source);
std::shared_ptr<sinsp_filter_factory> filter_factory_for_source(const std::string &source);
std::shared_ptr<sinsp_filter_factory> filter_factory_for_source(std::size_t source_idx);
//
// Given a source, return a formatter factory that can create
// formatters for an event.
//
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory_for_source(const std::string& source);
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory_for_source(std::size_t source_idx);
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory_for_source(
const std::string &source);
std::shared_ptr<sinsp_evt_formatter_factory> formatter_factory_for_source(
std::size_t source_idx);
//
// Given a source, return a ruleset factory that can create
// rulesets for that source.
//
std::shared_ptr<filter_ruleset_factory> ruleset_factory_for_source(const std::string& source);
std::shared_ptr<filter_ruleset_factory> ruleset_factory_for_source(const std::string &source);
std::shared_ptr<filter_ruleset_factory> ruleset_factory_for_source(std::size_t source_idx);
// Return the filter_ruleset used for a given source.
std::shared_ptr<filter_ruleset> ruleset_for_source(const std::string& source);
std::shared_ptr<filter_ruleset> ruleset_for_source(const std::string &source);
std::shared_ptr<filter_ruleset> ruleset_for_source(std::size_t source_idx);
//
@@ -314,24 +326,24 @@ public:
// todo(jasondellaluce): remove this in future code refactors
//
void evttypes_for_ruleset(const std::string &source,
std::set<uint16_t> &evttypes,
const std::string &ruleset = s_default_ruleset);
std::set<uint16_t> &evttypes,
const std::string &ruleset = s_default_ruleset);
//
// Given an event source and ruleset, return the set of ppm_sc_codes
// for which this ruleset can run and match events.
//
libsinsp::events::set<ppm_sc_code> sc_codes_for_ruleset(
const std::string &source,
const std::string &ruleset = s_default_ruleset);
const std::string &source,
const std::string &ruleset = s_default_ruleset);
//
// Given an event source and ruleset, return the set of ppm_event_codes
// for which this ruleset can run and match events.
//
libsinsp::events::set<ppm_event_code> event_codes_for_ruleset(
const std::string &source,
const std::string &ruleset = s_default_ruleset);
const std::string &source,
const std::string &ruleset = s_default_ruleset);
//
// Given a source and output string, return an
@@ -339,7 +351,7 @@ public:
// event.
//
std::shared_ptr<sinsp_evt_formatter> create_formatter(const std::string &source,
const std::string &output) const;
const std::string &output) const;
// The rule loader definition is aliased as it is exactly what we need
typedef rule_loader::plugin_version_info::requirement plugin_version_requirement;
@@ -351,49 +363,42 @@ public:
// the name of the plugin and the second element is its version.
// If false is returned, err is filled with error causing the check failure.
//
bool check_plugin_requirements(
const std::vector<plugin_version_requirement>& plugins,
std::string& err) const;
bool check_plugin_requirements(const std::vector<plugin_version_requirement> &plugins,
std::string &err) const;
nlohmann::json m_rule_schema;
private:
// Create a ruleset using the provided factory and set the
// engine state funcs for it.
std::shared_ptr<filter_ruleset> create_ruleset(std::shared_ptr<filter_ruleset_factory>& ruleset_factory);
std::shared_ptr<filter_ruleset> create_ruleset(
std::shared_ptr<filter_ruleset_factory> &ruleset_factory);
// Functions to retrieve state from this engine
void fill_engine_state_funcs(filter_ruleset::engine_state_funcs& engine_state);
void fill_engine_state_funcs(filter_ruleset::engine_state_funcs &engine_state);
filter_ruleset::engine_state_funcs m_engine_state;
// Throws falco_exception if the file can not be read
void read_file(const std::string& filename, std::string& contents);
void read_file(const std::string &filename, std::string &contents);
indexed_vector<falco_source> m_sources;
inline const falco_source* find_source(std::size_t index)
{
inline const falco_source *find_source(std::size_t index) {
const falco_source *source;
if(index == m_syscall_source_idx)
{
if(m_syscall_source == NULL)
{
if(index == m_syscall_source_idx) {
if(m_syscall_source == NULL) {
m_syscall_source = m_sources.at(m_syscall_source_idx);
if(!m_syscall_source)
{
if(!m_syscall_source) {
throw falco_exception("Unknown event source index " + std::to_string(index));
}
}
source = m_syscall_source;
}
else
{
} else {
source = m_sources.at(index);
if(!source)
{
if(!source) {
throw falco_exception("Unknown event source index " + std::to_string(index));
}
}
@@ -401,11 +406,9 @@ private:
return source;
}
inline const falco_source* find_source(const std::string& name) const
{
inline const falco_source *find_source(const std::string &name) const {
auto ret = m_sources.at(name);
if(!ret)
{
if(!ret) {
throw falco_exception("Unknown event source " + name);
}
return ret;
@@ -414,7 +417,7 @@ private:
// To allow the engine to be extremely fast for syscalls (can
// be > 1M events/sec), we save the syscall source/source_idx
// separately and check it explicitly in process_event()
const falco_source* m_syscall_source;
const falco_source *m_syscall_source;
std::atomic<size_t> m_syscall_source_idx;
//
@@ -425,31 +428,26 @@ private:
inline bool should_drop_evt() const;
// Retrieve json details from rules, macros, lists
void get_json_details(
nlohmann::json& out,
const falco_rule& r,
const rule_loader::rule_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_details(
nlohmann::json& out,
const falco_macro& m,
const rule_loader::macro_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_details(
nlohmann::json& out,
const falco_list& l,
const rule_loader::list_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_evt_types(
nlohmann::json& out,
const std::string& source,
libsinsp::filter::ast::expr* ast) const;
void get_json_used_plugins(
nlohmann::json& out,
const std::string& source,
const std::unordered_set<std::string>& evttypes,
const std::unordered_set<std::string>& fields,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_details(nlohmann::json &out,
const falco_rule &r,
const rule_loader::rule_info &info,
const std::vector<std::shared_ptr<sinsp_plugin>> &plugins) const;
void get_json_details(nlohmann::json &out,
const falco_macro &m,
const rule_loader::macro_info &info,
const std::vector<std::shared_ptr<sinsp_plugin>> &plugins) const;
void get_json_details(nlohmann::json &out,
const falco_list &l,
const rule_loader::list_info &info,
const std::vector<std::shared_ptr<sinsp_plugin>> &plugins) const;
void get_json_evt_types(nlohmann::json &out,
const std::string &source,
libsinsp::filter::ast::expr *ast) const;
void get_json_used_plugins(nlohmann::json &out,
const std::string &source,
const std::unordered_set<std::string> &evttypes,
const std::unordered_set<std::string> &fields,
const std::vector<std::shared_ptr<sinsp_plugin>> &plugins) const;
indexed_vector<falco_rule> m_rules;
std::shared_ptr<rule_loader::reader> m_rule_reader;

View File

@@ -20,18 +20,20 @@ limitations under the License.
// The version of this Falco engine
#define FALCO_ENGINE_VERSION_MAJOR 0
#define FALCO_ENGINE_VERSION_MINOR 43
#define FALCO_ENGINE_VERSION_MINOR 46
#define FALCO_ENGINE_VERSION_PATCH 0
#define FALCO_ENGINE_VERSION \
__FALCO_ENGINE_STRINGIFY(FALCO_ENGINE_VERSION_MAJOR) "." \
__FALCO_ENGINE_STRINGIFY(FALCO_ENGINE_VERSION_MINOR) "." \
__FALCO_ENGINE_STRINGIFY(FALCO_ENGINE_VERSION_PATCH)
#define FALCO_ENGINE_VERSION \
__FALCO_ENGINE_STRINGIFY(FALCO_ENGINE_VERSION_MAJOR) \
"." __FALCO_ENGINE_STRINGIFY(FALCO_ENGINE_VERSION_MINOR) "." __FALCO_ENGINE_STRINGIFY( \
FALCO_ENGINE_VERSION_PATCH)
// This is the result of running the following command:
// FALCO="falco -c ./falco.yaml"
// echo $($FALCO --version | grep 'Engine:' | awk '{print $2}') $(echo $($FALCO --version | grep 'Schema version:' | awk '{print $3}') $($FALCO --list --markdown | grep '^`' | sort) $($FALCO --list-events | sort) | sha256sum)
// echo $($FALCO --version | grep 'Engine:' | awk '{print $2}') $(echo $($FALCO --version | grep
// 'Schema version:' | awk '{print $3}') $($FALCO --list --markdown | grep '^`' | sort) $($FALCO
// --list-events | sort) | sha256sum)
// It represents the fields supported by this version of Falco,
// the event types, and the underlying driverevent schema. It's used to
// detetect changes in engine version in our CI jobs.
#define FALCO_ENGINE_CHECKSUM "8a7f383c1e7682c484096bb6a5cb68c29b818acbe65fa2854acbcc98277fd7e0"
#define FALCO_ENGINE_CHECKSUM "24861acb14c5b9f7d293dd37d1623949135e1a865f2d813cbd660212b71ada33"

View File

@@ -17,113 +17,110 @@ limitations under the License.
#include "falco_load_result.h"
static const std::string error_codes[] = {
"LOAD_ERR_FILE_READ",
"LOAD_ERR_YAML_PARSE",
"LOAD_ERR_YAML_VALIDATE",
"LOAD_ERR_COMPILE_CONDITION",
"LOAD_ERR_COMPILE_OUTPUT",
"LOAD_ERR_VALIDATE",
"LOAD_ERR_EXTENSION"
};
static const std::string error_codes[] = {"LOAD_ERR_FILE_READ",
"LOAD_ERR_YAML_PARSE",
"LOAD_ERR_YAML_VALIDATE",
"LOAD_ERR_COMPILE_CONDITION",
"LOAD_ERR_COMPILE_OUTPUT",
"LOAD_ERR_VALIDATE",
"LOAD_ERR_EXTENSION"};
const std::string& falco::load_result::error_code_str(error_code ec)
{
const std::string& falco::load_result::error_code_str(error_code ec) {
return error_codes[ec];
}
static const std::string error_strings[] = {
"File read error",
"YAML parse error",
"Error validating internal structure of YAML file",
"Error compiling condition",
"Error compiling output",
"Error validating rule/macro/list/exception objects",
"Error in extension item"
};
static const std::string error_strings[] = {"File read error",
"YAML parse error",
"Error validating internal structure of YAML file",
"Error compiling condition",
"Error compiling output",
"Error validating rule/macro/list/exception objects",
"Error in extension item"};
const std::string& falco::load_result::error_str(error_code ec)
{
const std::string& falco::load_result::error_str(error_code ec) {
return error_strings[ec];
}
static const std::string error_descs[] = {
"This occurs when falco can not read a given file. Check permissions and whether the file exists.",
"This occurs when the rules content is not valid YAML.",
"This occurs when the internal structure of the YAML file is incorrect. Examples include not consisting of a sequence of maps, a given rule/macro/list item not having required keys, values not having the right type (e.g. the items property of a list not being a sequence), etc.",
"This occurs when a condition string can not be compiled to a filter object.",
"This occurs when an output string can not be compiled to an output object.",
"This occurs when a rule/macro/list item is incorrect. Examples include a condition field referring to an undefined macro, falco engine/plugin version mismatches, items with append without any existing item, exception fields/comps having different lengths, etc.",
"This occurs when there is an error in an extension item"
};
"This occurs when falco can not read a given file. Check permissions and whether the file "
"exists.",
"This occurs when the rules content is not valid YAML.",
"This occurs when the internal structure of the YAML file is incorrect. Examples include "
"not consisting of a sequence of maps, a given rule/macro/list item not having required "
"keys, values not having the right type (e.g. the items property of a list not being a "
"sequence), etc.",
"This occurs when a condition string can not be compiled to a filter object.",
"This occurs when an output string can not be compiled to an output object.",
"This occurs when a rule/macro/list item is incorrect. Examples include a condition field "
"referring to an undefined macro, falco engine/plugin version mismatches, items with "
"append without any existing item, exception fields/comps having different lengths, etc.",
"This occurs when there is an error in an extension item"};
const std::string& falco::load_result::error_desc(error_code ec)
{
const std::string& falco::load_result::error_desc(error_code ec) {
return error_strings[ec];
}
static const std::string warning_codes[] = {
"LOAD_UNKNOWN_SOURCE",
"LOAD_UNSAFE_NA_CHECK",
"LOAD_NO_EVTTYPE",
"LOAD_UNKNOWN_FILTER",
"LOAD_UNUSED_MACRO",
"LOAD_UNUSED_LIST",
"LOAD_UNKNOWN_ITEM",
"LOAD_DEPRECATED_ITEM",
"LOAD_WARNING_EXTENSION",
"LOAD_APPEND_NO_VALUES",
"LOAD_EXCEPTION_NAME_NOT_UNIQUE",
"LOAD_INVALID_MACRO_NAME",
"LOAD_INVALID_LIST_NAME",
"LOAD_COMPILE_CONDITION"
};
static const std::string warning_codes[] = {"LOAD_UNKNOWN_SOURCE",
"LOAD_UNSAFE_NA_CHECK",
"LOAD_NO_EVTTYPE",
"LOAD_UNKNOWN_FILTER",
"LOAD_UNUSED_MACRO",
"LOAD_UNUSED_LIST",
"LOAD_UNKNOWN_ITEM",
"LOAD_DEPRECATED_ITEM",
"LOAD_WARNING_EXTENSION",
"LOAD_APPEND_NO_VALUES",
"LOAD_EXCEPTION_NAME_NOT_UNIQUE",
"LOAD_INVALID_MACRO_NAME",
"LOAD_INVALID_LIST_NAME",
"LOAD_COMPILE_CONDITION"};
const std::string& falco::load_result::warning_code_str(warning_code wc)
{
const std::string& falco::load_result::warning_code_str(warning_code wc) {
return warning_codes[wc];
}
static const std::string warning_strings[] = {
"Unknown event source",
"Unsafe <NA> comparison in condition",
"Condition has no event-type restriction",
"Unknown field or event-type in condition or output",
"Unused macro",
"Unused list",
"Unknown rules file item",
"Used deprecated item",
"Warning in extension item",
"Overriding/appending with no values",
"Multiple exceptions defined with the same name",
"Invalid macro name",
"Invalid list name",
"Warning in rule condition"
};
static const std::string warning_strings[] = {"Unknown event source",
"Unsafe <NA> comparison in condition",
"Condition has no event-type restriction",
"Unknown field or event-type in condition or output",
"Unused macro",
"Unused list",
"Unknown rules file item",
"Used deprecated item",
"Warning in extension item",
"Overriding/appending with no values",
"Multiple exceptions defined with the same name",
"Invalid macro name",
"Invalid list name",
"Warning in rule condition"};
const std::string& falco::load_result::warning_str(warning_code wc)
{
const std::string& falco::load_result::warning_str(warning_code wc) {
return warning_strings[wc];
}
static const std::string warning_descs[] = {
"A rule has a unknown event source. This can occur when reading rules content without having a corresponding plugin loaded, etc. The rule will be silently ignored.",
"Comparing a field value with <NA> is unsafe and can lead to unpredictable behavior of the rule condition. If you need to check for the existence of a field, consider using the 'exists' operator instead.",
"A rule condition matches too many evt.type values. This has a significant performance penalty. Make the condition more specific by adding an evt.type field or further restricting the number of evt.type values in the condition.",
"A rule condition or output refers to a field or evt.type that does not exist. This is normally an error, but if a rule has a skip-if-unknown-filter property, the error is downgraded to a warning.",
"A macro is defined in the rules content but is not used by any other macro or rule.",
"A list is defined in the rules content but is not used by any other list, macro, or rule.",
"An unknown top-level object is in the rules content. It will be ignored.",
"A deprecated item is employed by lists, macros, or rules.",
"An extension item has a warning",
"A rule exception is overriding/appending with no values",
"A rule is defining multiple exceptions with the same name",
"A macro is defined with an invalid name",
"A list is defined with an invalid name",
"A rule condition or output have been parsed with a warning"
};
"A rule has a unknown event source. This can occur when reading rules content without "
"having a corresponding plugin loaded, etc. The rule will be silently ignored.",
"Comparing a field value with <NA> is unsafe and can lead to unpredictable behavior of the "
"rule condition. If you need to check for the existence of a field, consider using the "
"'exists' operator instead.",
"A rule condition matches too many evt.type values. This has a significant performance "
"penalty. Make the condition more specific by adding an evt.type field or further "
"restricting the number of evt.type values in the condition.",
"A rule condition or output refers to a field or evt.type that does not exist. This is "
"normally an error, but if a rule has a skip-if-unknown-filter property, the error is "
"downgraded to a warning.",
"A macro is defined in the rules content but is not used by any other macro or rule.",
"A list is defined in the rules content but is not used by any other list, macro, or rule.",
"An unknown top-level object is in the rules content. It will be ignored.",
"A deprecated item is employed by lists, macros, or rules.",
"An extension item has a warning",
"A rule exception is overriding/appending with no values",
"A rule is defining multiple exceptions with the same name",
"A macro is defined with an invalid name",
"A list is defined with an invalid name",
"A rule condition or output have been parsed with a warning"};
const std::string& falco::load_result::warning_desc(warning_code wc)
{
const std::string& falco::load_result::warning_desc(warning_code wc) {
return warning_descs[wc];
}

View File

@@ -21,13 +21,11 @@ limitations under the License.
#include <string>
#include <nlohmann/json.hpp>
namespace falco
{
namespace falco {
// Represents the result of loading a rules file.
class load_result {
public:
enum error_code {
LOAD_ERR_FILE_READ = 0,
LOAD_ERR_YAML_PARSE,
@@ -121,4 +119,4 @@ public:
virtual const nlohmann::json& as_json(const rules_contents_t& contents) = 0;
};
} // namespace falco
} // namespace falco

View File

@@ -24,18 +24,22 @@ limitations under the License.
#include <libsinsp/filter/ast.h>
/*!
\brief Represents a list in the Falco Engine.
The rule ID must be unique across all the lists loaded in the engine.
\brief Represents a list in the Falco Engine.
The rule ID must be unique across all the lists loaded in the engine.
*/
struct falco_list
{
falco_list(): used(false), id(0) { }
struct falco_list {
falco_list(): used(false), id(0) {}
falco_list(falco_list&&) = default;
falco_list& operator = (falco_list&&) = default;
falco_list& operator=(falco_list&&) = default;
falco_list(const falco_list&) = default;
falco_list& operator = (const falco_list&) = default;
falco_list& operator=(const falco_list&) = default;
~falco_list() = default;
bool operator==(const falco_list& rhs) const {
return (this->used == rhs.used && this->id == rhs.id && this->name == rhs.name &&
this->items == rhs.items);
}
bool used;
std::size_t id;
std::string name;
@@ -43,18 +47,25 @@ struct falco_list
};
/*!
\brief Represents a macro in the Falco Engine.
The rule ID must be unique across all the macros loaded in the engine.
\brief Represents a macro in the Falco Engine.
The rule ID must be unique across all the macros loaded in the engine.
*/
struct falco_macro
{
falco_macro(): used(false), id(0) { }
struct falco_macro {
falco_macro(): used(false), id(0) {}
falco_macro(falco_macro&&) = default;
falco_macro& operator = (falco_macro&&) = default;
falco_macro& operator=(falco_macro&&) = default;
falco_macro(const falco_macro&) = default;
falco_macro& operator = (const falco_macro&) = default;
falco_macro& operator=(const falco_macro&) = default;
~falco_macro() = default;
bool operator==(const falco_macro& rhs) const {
// Note this only ensures that the shared_ptrs are
// pointing to the same underlying memory, not that
// they are logically equal.
return (this->used == rhs.used && this->id == rhs.id && this->name == rhs.name &&
this->condition.get() == rhs.condition.get());
}
bool used;
std::size_t id;
std::string name;
@@ -62,18 +73,28 @@ struct falco_macro
};
/*!
\brief Represents a rule in the Falco Engine.
The rule ID must be unique across all the rules loaded in the engine.
\brief Represents a rule in the Falco Engine.
The rule ID must be unique across all the rules loaded in the engine.
*/
struct falco_rule
{
struct falco_rule {
falco_rule(): id(0), priority(falco_common::PRIORITY_DEBUG) {}
falco_rule(falco_rule&&) = default;
falco_rule& operator = (falco_rule&&) = default;
falco_rule& operator=(falco_rule&&) = default;
falco_rule(const falco_rule&) = default;
falco_rule& operator = (const falco_rule&) = default;
falco_rule& operator=(const falco_rule&) = default;
~falco_rule() = default;
bool operator==(const falco_rule& rhs) const {
// Note this only ensures that the shared_ptrs are
// pointing to the same underlying memory, not that
// they are logically equal.
return (this->id == rhs.id && this->source == rhs.source && this->name == rhs.name &&
this->description == rhs.description && this->output == rhs.output &&
this->tags == rhs.tags && this->exception_fields == rhs.exception_fields &&
this->priority == rhs.priority && this->condition.get() == rhs.condition.get() &&
this->filter.get() == rhs.filter.get());
}
std::size_t id;
std::string source;
std::string name;

View File

@@ -21,23 +21,21 @@ limitations under the License.
#include "filter_ruleset.h"
/*!
\brief Represents a given data source used by the engine.
The ruleset of a source should be created through the ruleset factory
of the same data source.
\brief Represents a given data source used by the engine.
The ruleset of a source should be created through the ruleset factory
of the same data source.
*/
struct falco_source
{
struct falco_source {
falco_source() = default;
falco_source(falco_source&&) = default;
falco_source& operator = (falco_source&&) = default;
falco_source& operator=(falco_source&&) = default;
falco_source(const falco_source& s):
name(s.name),
ruleset(s.ruleset),
ruleset_factory(s.ruleset_factory),
filter_factory(s.filter_factory),
formatter_factory(s.formatter_factory) { };
falco_source& operator = (const falco_source& s)
{
name(s.name),
ruleset(s.ruleset),
ruleset_factory(s.ruleset_factory),
filter_factory(s.filter_factory),
formatter_factory(s.formatter_factory) {};
falco_source& operator=(const falco_source& s) {
name = s.name;
ruleset = s.ruleset;
ruleset_factory = s.ruleset_factory;
@@ -56,24 +54,19 @@ struct falco_source
// matches an event.
mutable std::vector<falco_rule> m_rules;
inline bool is_valid_lhs_field(const std::string& field) const
{
inline bool is_valid_lhs_field(const std::string& field) const {
// if there's at least one parenthesis we may be parsing a field
// wrapped inside one or more transformers. In those cases, the most
// rigorous analysis we can do is compiling a simple filter using
// the field as left-hand side of a comparison, and see if any error
// occurs.
if (field.find('(') != std::string::npos)
{
try
{
if(field.find('(') != std::string::npos) {
try {
auto filter = field;
filter.append(" exists");
sinsp_filter_compiler(filter_factory, filter).compile();
return true;
}
catch (...)
{
} catch(...) {
return false;
}
}

View File

@@ -23,26 +23,29 @@ limitations under the License.
#include <re2/re2.h>
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
#include <openssl/sha.h>
#include <openssl/evp.h>
#endif
#include <cstring>
#include <fstream>
#include <iomanip>
#include <thread>
#define RGX_PROMETHEUS_TIME_DURATION "^((?P<y>[0-9]+)y)?((?P<w>[0-9]+)w)?((?P<d>[0-9]+)d)?((?P<h>[0-9]+)h)?((?P<m>[0-9]+)m)?((?P<s>[0-9]+)s)?((?P<ms>[0-9]+)ms)?$"
#define RGX_PROMETHEUS_TIME_DURATION \
"^((?P<y>[0-9]+)y)?((?P<w>[0-9]+)w)?((?P<d>[0-9]+)d)?((?P<h>[0-9]+)h)?((?P<m>[0-9]+)m)?((?P<" \
"s>[0-9]+)s)?((?P<ms>[0-9]+)ms)?$"
// using pre-compiled regex
static re2::RE2 s_rgx_prometheus_time_duration(RGX_PROMETHEUS_TIME_DURATION);
// Prometheus time durations: https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations
#define PROMETHEUS_UNIT_Y "y" ///> assuming a year has always 365d
#define PROMETHEUS_UNIT_W "w" ///> assuming a week has always 7d
#define PROMETHEUS_UNIT_D "d" ///> assuming a day has always 24h
#define PROMETHEUS_UNIT_H "h" ///> hour
#define PROMETHEUS_UNIT_M "m" ///> minute
#define PROMETHEUS_UNIT_S "s" ///> second
#define PROMETHEUS_UNIT_MS "ms" ///> millisecond
// Prometheus time durations:
// https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations
#define PROMETHEUS_UNIT_Y "y" ///> assuming a year has always 365d
#define PROMETHEUS_UNIT_W "w" ///> assuming a week has always 7d
#define PROMETHEUS_UNIT_D "d" ///> assuming a day has always 24h
#define PROMETHEUS_UNIT_H "h" ///> hour
#define PROMETHEUS_UNIT_M "m" ///> minute
#define PROMETHEUS_UNIT_S "s" ///> second
#define PROMETHEUS_UNIT_MS "ms" ///> millisecond
// standard time unit conversions to milliseconds
#define ONE_MS_TO_MS 1UL
@@ -53,20 +56,17 @@ static re2::RE2 s_rgx_prometheus_time_duration(RGX_PROMETHEUS_TIME_DURATION);
#define ONE_WEEK_TO_MS ONE_DAY_TO_MS * 7UL
#define ONE_YEAR_TO_MS ONE_DAY_TO_MS * 365UL
namespace falco
{
namespace falco {
namespace utils
{
namespace utils {
uint64_t parse_prometheus_interval(std::string interval_str)
{
uint64_t parse_prometheus_interval(std::string interval_str) {
uint64_t interval = 0;
/* Sanitize user input, remove possible whitespaces. */
interval_str.erase(remove_if(interval_str.begin(), interval_str.end(), isspace), interval_str.end());
interval_str.erase(remove_if(interval_str.begin(), interval_str.end(), isspace),
interval_str.end());
if(!interval_str.empty())
{
if(!interval_str.empty()) {
re2::StringPiece input(interval_str);
std::string args[14];
re2::RE2::Arg arg0(&args[0]);
@@ -83,34 +83,52 @@ uint64_t parse_prometheus_interval(std::string interval_str)
re2::RE2::Arg arg11(&args[11]);
re2::RE2::Arg arg12(&args[12]);
re2::RE2::Arg arg13(&args[13]);
const re2::RE2::Arg* const matches[14] = {&arg0, &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, &arg8, &arg9, &arg10, &arg11, &arg12, &arg13};
const re2::RE2::Arg* const matches[14] = {&arg0,
&arg1,
&arg2,
&arg3,
&arg4,
&arg5,
&arg6,
&arg7,
&arg8,
&arg9,
&arg10,
&arg11,
&arg12,
&arg13};
const std::map<std::string, int>& named_groups = s_rgx_prometheus_time_duration.NamedCapturingGroups();
const std::map<std::string, int>& named_groups =
s_rgx_prometheus_time_duration.NamedCapturingGroups();
int num_groups = s_rgx_prometheus_time_duration.NumberOfCapturingGroups();
re2::RE2::FullMatchN(input, s_rgx_prometheus_time_duration, matches, num_groups);
static const char* all_prometheus_units[7] = {
PROMETHEUS_UNIT_Y, PROMETHEUS_UNIT_W, PROMETHEUS_UNIT_D, PROMETHEUS_UNIT_H,
PROMETHEUS_UNIT_M, PROMETHEUS_UNIT_S, PROMETHEUS_UNIT_MS };
static const char* all_prometheus_units[7] = {PROMETHEUS_UNIT_Y,
PROMETHEUS_UNIT_W,
PROMETHEUS_UNIT_D,
PROMETHEUS_UNIT_H,
PROMETHEUS_UNIT_M,
PROMETHEUS_UNIT_S,
PROMETHEUS_UNIT_MS};
static const uint64_t all_prometheus_time_conversions[7] = {
ONE_YEAR_TO_MS, ONE_WEEK_TO_MS, ONE_DAY_TO_MS, ONE_HOUR_TO_MS,
ONE_MINUTE_TO_MS, ONE_SECOND_TO_MS, ONE_MS_TO_MS };
static const uint64_t all_prometheus_time_conversions[7] = {ONE_YEAR_TO_MS,
ONE_WEEK_TO_MS,
ONE_DAY_TO_MS,
ONE_HOUR_TO_MS,
ONE_MINUTE_TO_MS,
ONE_SECOND_TO_MS,
ONE_MS_TO_MS};
for(size_t i = 0; i < sizeof(all_prometheus_units) / sizeof(const char*); i++)
{
for(size_t i = 0; i < sizeof(all_prometheus_units) / sizeof(const char*); i++) {
std::string cur_interval_str;
uint64_t cur_interval = 0;
const auto &group_it = named_groups.find(all_prometheus_units[i]);
if(group_it != named_groups.end())
{
const auto& group_it = named_groups.find(all_prometheus_units[i]);
if(group_it != named_groups.end()) {
cur_interval_str = args[group_it->second - 1];
if(!cur_interval_str.empty())
{
if(!cur_interval_str.empty()) {
cur_interval = std::stoull(cur_interval_str, nullptr, 0);
}
if(cur_interval > 0)
{
if(cur_interval > 0) {
interval += cur_interval * all_prometheus_time_conversions[i];
}
}
@@ -120,63 +138,52 @@ uint64_t parse_prometheus_interval(std::string interval_str)
}
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
std::string calculate_file_sha256sum(const std::string& filename)
{
std::string calculate_file_sha256sum(const std::string& filename) {
std::ifstream file(filename, std::ios::binary);
if (!file.is_open())
{
if(!file.is_open()) {
return "";
}
SHA256_CTX sha256_context;
SHA256_Init(&sha256_context);
std::unique_ptr<EVP_MD_CTX, decltype(&EVP_MD_CTX_free)> ctx(EVP_MD_CTX_new(), EVP_MD_CTX_free);
EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr);
constexpr size_t buffer_size = 4096;
char buffer[buffer_size];
while (file.read(buffer, buffer_size))
{
SHA256_Update(&sha256_context, buffer, buffer_size);
while(file.read(buffer, buffer_size)) {
EVP_DigestUpdate(ctx.get(), buffer, buffer_size);
}
SHA256_Update(&sha256_context, buffer, file.gcount());
EVP_DigestUpdate(ctx.get(), buffer, file.gcount());
unsigned char digest[SHA256_DIGEST_LENGTH];
SHA256_Final(digest, &sha256_context);
std::vector<uint8_t> digest(EVP_MD_size(EVP_sha256()));
EVP_DigestFinal_ex(ctx.get(), digest.data(), nullptr);
std::stringstream ss;
for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i)
{
ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned>(digest[i]);
std::ostringstream ss;
for(auto& c : digest) {
ss << std::hex << std::setw(2) << std::setfill('0') << (int)c;
}
return ss.str();
}
#endif
std::string sanitize_rule_name(const std::string& name)
{
std::string sanitize_rule_name(const std::string& name) {
std::string sanitized_name = name;
RE2::GlobalReplace(&sanitized_name, "[^a-zA-Z0-9_:]", "_");
RE2::GlobalReplace(&sanitized_name, "_+", "_");
if (!sanitized_name.empty() && sanitized_name.back() == '_')
{
if(!sanitized_name.empty() && sanitized_name.back() == '_') {
sanitized_name.pop_back();
}
return sanitized_name;
}
std::string wrap_text(const std::string& in, uint32_t indent, uint32_t line_len)
{
std::string wrap_text(const std::string& in, uint32_t indent, uint32_t line_len) {
std::istringstream is(in);
std::ostringstream os;
std::string word;
uint32_t len = 0;
while (is >> word)
{
if((len + word.length() + 1) <= (line_len-indent))
{
while(is >> word) {
if((len + word.length() + 1) <= (line_len - indent)) {
len += word.length() + 1;
}
else
{
} else {
os << std::endl;
os << std::left << std::setw(indent) << " ";
len = word.length() + 1;
@@ -186,18 +193,15 @@ std::string wrap_text(const std::string& in, uint32_t indent, uint32_t line_len)
return os.str();
}
uint32_t hardware_concurrency()
{
uint32_t hardware_concurrency() {
auto hc = std::thread::hardware_concurrency();
return hc ? hc : 1;
}
void readfile(const std::string& filename, std::string& data)
{
void readfile(const std::string& filename, std::string& data) {
std::ifstream file(filename, std::ios::in);
if(file.is_open())
{
if(file.is_open()) {
std::stringstream ss;
ss << file.rdbuf();
@@ -209,22 +213,18 @@ void readfile(const std::string& filename, std::string& data)
return;
}
bool matches_wildcard(const std::string &pattern, const std::string &s)
{
bool matches_wildcard(const std::string& pattern, const std::string& s) {
std::string::size_type star_pos = pattern.find("*");
if(star_pos == std::string::npos)
{
if(star_pos == std::string::npos) {
// regular match (no wildcards)
return pattern == s;
}
if(star_pos == 0)
{
if(star_pos == 0) {
// wildcard at the beginning "*something*..."
std::string::size_type next_pattern_start = pattern.find_first_not_of("*");
if(next_pattern_start == std::string::npos)
{
if(next_pattern_start == std::string::npos) {
// pattern was just a sequence of stars *, **, ***, ... . This always matches.
return true;
}
@@ -232,18 +232,16 @@ bool matches_wildcard(const std::string &pattern, const std::string &s)
std::string next_pattern = pattern.substr(next_pattern_start);
std::string to_find = next_pattern.substr(0, next_pattern.find("*"));
std::string::size_type lit_pos = s.find(to_find);
if(lit_pos == std::string::npos)
{
if(lit_pos == std::string::npos) {
return false;
}
return matches_wildcard(next_pattern.substr(to_find.size()), s.substr(lit_pos + to_find.size()));
} else
{
return matches_wildcard(next_pattern.substr(to_find.size()),
s.substr(lit_pos + to_find.size()));
} else {
// wildcard at the end or in the middle "something*else*..."
if(pattern.substr(0, star_pos) != s.substr(0, star_pos))
{
if(pattern.substr(0, star_pos) != s.substr(0, star_pos)) {
return false;
}
@@ -251,12 +249,10 @@ bool matches_wildcard(const std::string &pattern, const std::string &s)
}
}
namespace network
{
bool is_unix_scheme(const std::string& url)
{
namespace network {
bool is_unix_scheme(const std::string& url) {
return sinsp_utils::startswith(url, UNIX_SCHEME);
}
} // namespace network
} // namespace utils
} // namespace falco
} // namespace network
} // namespace utils
} // namespace falco

View File

@@ -23,8 +23,7 @@ limitations under the License.
#include <cstdint>
#include <string>
namespace falco::utils
{
namespace falco::utils {
uint64_t parse_prometheus_interval(std::string interval_str);
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
@@ -39,11 +38,10 @@ void readfile(const std::string& filename, std::string& data);
uint32_t hardware_concurrency();
bool matches_wildcard(const std::string &pattern, const std::string &s);
bool matches_wildcard(const std::string& pattern, const std::string& s);
namespace network
{
namespace network {
static const std::string UNIX_SCHEME("unix://");
bool is_unix_scheme(const std::string& url);
} // namespace network
} // namespace falco::utils
} // namespace network
} // namespace falco::utils

View File

@@ -21,18 +21,15 @@ limitations under the License.
using namespace libsinsp::filter;
static inline std::string get_field_name(const std::string& name, const std::string& arg)
{
static inline std::string get_field_name(const std::string& name, const std::string& arg) {
std::string fld = name;
if (!arg.empty())
{
if(!arg.empty()) {
fld += "[" + arg + "]";
}
return fld;
}
void filter_details::reset()
{
void filter_details::reset() {
fields.clear();
macros.clear();
operators.clear();
@@ -41,114 +38,92 @@ void filter_details::reset()
transformers.clear();
}
void filter_details_resolver::run(ast::expr* filter, filter_details& details)
{
void filter_details_resolver::run(ast::expr* filter, filter_details& details) {
visitor v(details);
filter->accept(&v);
}
void filter_details_resolver::visitor::visit(ast::and_expr* e)
{
for(size_t i = 0; i < e->children.size(); i++)
{
void filter_details_resolver::visitor::visit(ast::and_expr* e) {
for(size_t i = 0; i < e->children.size(); i++) {
e->children[i]->accept(this);
}
}
void filter_details_resolver::visitor::visit(ast::or_expr* e)
{
for(size_t i = 0; i < e->children.size(); i++)
{
void filter_details_resolver::visitor::visit(ast::or_expr* e) {
for(size_t i = 0; i < e->children.size(); i++) {
e->children[i]->accept(this);
}
}
void filter_details_resolver::visitor::visit(ast::not_expr* e)
{
void filter_details_resolver::visitor::visit(ast::not_expr* e) {
e->child->accept(this);
}
void filter_details_resolver::visitor::visit(ast::list_expr* e)
{
if(m_expect_list)
{
for(const auto& item : e->values)
{
if(m_details.known_lists.find(item) != m_details.known_lists.end())
{
void filter_details_resolver::visitor::visit(ast::list_expr* e) {
if(m_expect_list) {
for(const auto& item : e->values) {
if(m_details.known_lists.find(item) != m_details.known_lists.end()) {
m_details.lists.insert(item);
}
}
}
if (m_expect_evtname)
{
for(const auto& item : e->values)
{
if(m_details.known_lists.find(item) == m_details.known_lists.end())
{
if(m_expect_evtname) {
for(const auto& item : e->values) {
if(m_details.known_lists.find(item) == m_details.known_lists.end()) {
m_details.evtnames.insert(item);
}
}
}
}
void filter_details_resolver::visitor::visit(ast::binary_check_expr* e)
{
void filter_details_resolver::visitor::visit(ast::binary_check_expr* e) {
m_last_node_field_name.clear();
m_expect_evtname = false;
m_expect_list = false;
e->left->accept(this);
if (m_last_node_field_name.empty())
{
if(m_last_node_field_name.empty()) {
throw std::runtime_error("can't find field info in binary check expression");
}
m_details.operators.insert(e->op);
m_expect_list = true;
m_expect_evtname = m_last_node_field_name == "evt.type" || m_last_node_field_name == "evt.asynctype";
m_expect_evtname =
m_last_node_field_name == "evt.type" || m_last_node_field_name == "evt.asynctype";
e->right->accept(this);
m_expect_evtname = false;
m_expect_list = false;
}
void filter_details_resolver::visitor::visit(ast::unary_check_expr* e)
{
void filter_details_resolver::visitor::visit(ast::unary_check_expr* e) {
m_last_node_field_name.clear();
e->left->accept(this);
if (m_last_node_field_name.empty())
{
if(m_last_node_field_name.empty()) {
throw std::runtime_error("can't find field info in unary check expression");
}
m_details.fields.insert(m_last_node_field_name);
m_details.operators.insert(e->op);
}
void filter_details_resolver::visitor::visit(ast::identifier_expr* e)
{
void filter_details_resolver::visitor::visit(ast::identifier_expr* e) {
// todo(jasondellaluce): maybe throw an error if we encounter an unknown macro?
if(m_details.known_macros.find(e->identifier) != m_details.known_macros.end())
{
if(m_details.known_macros.find(e->identifier) != m_details.known_macros.end()) {
m_details.macros.insert(e->identifier);
}
}
void filter_details_resolver::visitor::visit(ast::value_expr* e)
{
if (m_expect_evtname)
{
void filter_details_resolver::visitor::visit(ast::value_expr* e) {
if(m_expect_evtname) {
m_details.evtnames.insert(e->value);
}
}
void filter_details_resolver::visitor::visit(ast::field_expr* e)
{
void filter_details_resolver::visitor::visit(ast::field_expr* e) {
m_last_node_field_name = get_field_name(e->field, e->arg);
m_details.fields.insert(m_last_node_field_name);
}
void filter_details_resolver::visitor::visit(ast::field_transformer_expr* e)
{
void filter_details_resolver::visitor::visit(ast::field_transformer_expr* e) {
m_details.transformers.insert(e->transformer);
e->value->accept(this);
}

View File

@@ -22,8 +22,7 @@ limitations under the License.
#include <unordered_set>
#include <unordered_map>
struct filter_details
{
struct filter_details {
// input macros and lists
std::unordered_set<std::string> known_macros;
std::unordered_set<std::string> known_lists;
@@ -40,29 +39,26 @@ struct filter_details
};
/*!
\brief Helper class for getting details about rules' filters.
\brief Helper class for getting details about rules' filters.
*/
class filter_details_resolver
{
class filter_details_resolver {
public:
/*!
\brief Visits a filter AST and stores details about macros, lists,
fields and operators used.
\param filter The filter AST to be processed.
\param details Helper structure used to state known macros and
lists on input, and to store all the retrieved details as output.
\brief Visits a filter AST and stores details about macros, lists,
fields and operators used.
\param filter The filter AST to be processed.
\param details Helper structure used to state known macros and
lists on input, and to store all the retrieved details as output.
*/
void run(libsinsp::filter::ast::expr* filter,
filter_details& details);
void run(libsinsp::filter::ast::expr* filter, filter_details& details);
private:
struct visitor : public libsinsp::filter::ast::expr_visitor
{
explicit visitor(filter_details& details) :
m_details(details),
m_expect_list(false),
m_expect_evtname(false),
m_last_node_field_name() {}
struct visitor : public libsinsp::filter::ast::expr_visitor {
explicit visitor(filter_details& details):
m_details(details),
m_expect_list(false),
m_expect_evtname(false),
m_last_node_field_name() {}
visitor(visitor&&) = default;
visitor(const visitor&) = delete;

View File

@@ -20,8 +20,7 @@ limitations under the License.
using namespace libsinsp::filter;
bool filter_macro_resolver::run(std::shared_ptr<libsinsp::filter::ast::expr>& filter)
{
bool filter_macro_resolver::run(std::shared_ptr<libsinsp::filter::ast::expr>& filter) {
m_unknown_macros.clear();
m_resolved_macros.clear();
m_errors.clear();
@@ -29,110 +28,90 @@ bool filter_macro_resolver::run(std::shared_ptr<libsinsp::filter::ast::expr>& fi
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)
{
if(v.m_node_substitute) {
filter = std::move(v.m_node_substitute);
}
return !m_resolved_macros.empty();
}
void filter_macro_resolver::set_macro(
const std::string& name,
const std::shared_ptr<libsinsp::filter::ast::expr>& macro)
{
void filter_macro_resolver::set_macro(const std::string& name,
const std::shared_ptr<libsinsp::filter::ast::expr>& macro) {
m_macros[name] = macro;
}
const std::vector<filter_macro_resolver::value_info>& 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 std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_errors() 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
{
const std::vector<filter_macro_resolver::value_info>& filter_macro_resolver::get_resolved_macros()
const {
return m_resolved_macros;
}
void filter_macro_resolver::visitor::visit(ast::and_expr* e)
{
for (size_t i = 0; i < e->children.size(); i++)
{
void filter_macro_resolver::visitor::visit(ast::and_expr* e) {
for(size_t i = 0; i < e->children.size(); i++) {
e->children[i]->accept(this);
if (m_node_substitute)
{
if(m_node_substitute) {
e->children[i] = std::move(m_node_substitute);
}
}
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::or_expr* e)
{
for (size_t i = 0; i < e->children.size(); i++)
{
void filter_macro_resolver::visitor::visit(ast::or_expr* e) {
for(size_t i = 0; i < e->children.size(); i++) {
e->children[i]->accept(this);
if (m_node_substitute)
{
if(m_node_substitute) {
e->children[i] = std::move(m_node_substitute);
}
}
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::not_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::not_expr* e) {
e->child->accept(this);
if (m_node_substitute)
{
if(m_node_substitute) {
e->child = std::move(m_node_substitute);
}
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::list_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::list_expr* e) {
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::binary_check_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::binary_check_expr* e) {
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::unary_check_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::unary_check_expr* e) {
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::value_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::value_expr* e) {
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::field_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::field_expr* e) {
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::field_transformer_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::field_transformer_expr* e) {
m_node_substitute = nullptr;
}
void filter_macro_resolver::visitor::visit(ast::identifier_expr* e)
{
void filter_macro_resolver::visitor::visit(ast::identifier_expr* e) {
const auto& macro = m_macros.find(e->identifier);
if (macro != m_macros.end() && macro->second) // skip null-ptr macros
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())
{
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;
@@ -146,15 +125,12 @@ void filter_macro_resolver::visitor::visit(ast::identifier_expr* e)
new_node->accept(this);
// new_node might already have set a non-NULL m_node_substitute.
// if not, the right substituted is the newly-cloned node.
if (!m_node_substitute)
{
if(!m_node_substitute) {
m_node_substitute = std::move(new_node);
}
m_resolved_macros.push_back({e->identifier, e->get_pos()});
m_macros_path.pop_back();
}
else
{
} else {
m_node_substitute = nullptr;
m_unknown_macros.push_back({e->identifier, e->get_pos()});
}

View File

@@ -24,114 +24,107 @@ limitations under the License.
#include <memory>
/*!
\brief Helper class for substituting and resolving macro
references in parsed filters.
\brief Helper class for substituting and resolving macro
references in parsed filters.
*/
class filter_macro_resolver
{
public:
/*!
\brief Visits a filter AST and substitutes macro references
according with all the definitions added through set_macro(),
by replacing the reference with a clone of the macro AST.
\param filter The filter AST to be processed. Note that the pointer
is passed by reference and be transformed in order to apply
the substutions. In that case, the old pointer is owned by this
class and is deleted automatically.
\return true if at least one of the defined macros is resolved
*/
bool run(std::shared_ptr<libsinsp::filter::ast::expr>& filter);
class filter_macro_resolver {
public:
/*!
\brief Visits a filter AST and substitutes macro references
according with all the definitions added through set_macro(),
by replacing the reference with a clone of the macro AST.
\param filter The filter AST to be processed. Note that the pointer
is passed by reference and be transformed in order to apply
the substutions. In that case, the old pointer is owned by this
class and is deleted automatically.
\return true if at least one of the defined macros is resolved
*/
bool run(std::shared_ptr<libsinsp::filter::ast::expr>& filter);
/*!
\brief Defines a new macro to be substituted in filters. If called
multiple times for the same macro name, the previous definition
gets overridden. A macro can be undefined by setting a null
AST pointer.
\param name The name of the macro.
\param macro The AST of the macro.
*/
void set_macro(
const std::string& name,
const std::shared_ptr<libsinsp::filter::ast::expr>& macro);
/*!
\brief Defines a new macro to be substituted in filters. If called
multiple times for the same macro name, the previous definition
gets overridden. A macro can be undefined by setting a null
AST pointer.
\param name The name of the macro.
\param macro The AST of the macro.
*/
void set_macro(const std::string& name,
const std::shared_ptr<libsinsp::filter::ast::expr>& macro);
/*!
\brief used in get_{resolved,unknown}_macros and get_errors
to represent an identifier/string value along with an AST position.
*/
typedef std::pair<std::string,libsinsp::filter::ast::pos_info> value_info;
/*!
\brief used in get_{resolved,unknown}_macros and get_errors
to represent an identifier/string value along with an AST position.
*/
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 std::vector<value_info>& get_resolved_macros() const;
/*!
\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 std::vector<value_info>& get_resolved_macros() const;
/*!
\brief Returns a set containing the names of all the macros
that remained unresolved during the last invocation of run().
A macro remains unresolved if it is found inside the processed
filter but it was not defined with set_macro();
*/
const std::vector<value_info>& get_unknown_macros() const;
/*!
\brief Returns a set containing the names of all the macros
that remained unresolved during the last invocation of run().
A macro remains unresolved if it is found inside the processed
filter but it was not defined with set_macro();
*/
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;
/*!
\brief Returns a list of errors occurred during
the latest invocation of run().
*/
const std::vector<value_info>& get_errors() const;
/*!
\brief Clears the resolver by resetting all state related to
known macros and everything related to the previous resolution run.
*/
inline void clear()
{
m_errors.clear();
m_unknown_macros.clear();
m_resolved_macros.clear();
m_macros.clear();
}
/*!
\brief Clears the resolver by resetting all state related to
known macros and everything related to the previous resolution run.
*/
inline void clear() {
m_errors.clear();
m_unknown_macros.clear();
m_resolved_macros.clear();
m_macros.clear();
}
private:
typedef std::unordered_map<
std::string,
std::shared_ptr<libsinsp::filter::ast::expr>
> macro_defs;
private:
typedef std::unordered_map<std::string, std::shared_ptr<libsinsp::filter::ast::expr> >
macro_defs;
struct visitor : public libsinsp::filter::ast::expr_visitor
{
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) {}
struct visitor : public libsinsp::filter::ast::expr_visitor {
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) {}
std::vector<std::string> m_macros_path;
std::unique_ptr<libsinsp::filter::ast::expr> m_node_substitute;
std::vector<value_info>& m_errors;
std::vector<value_info>& m_unknown_macros;
std::vector<value_info>& m_resolved_macros;
macro_defs& m_macros;
std::vector<std::string> m_macros_path;
std::unique_ptr<libsinsp::filter::ast::expr> m_node_substitute;
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;
void visit(libsinsp::filter::ast::or_expr* e) override;
void visit(libsinsp::filter::ast::not_expr* e) override;
void visit(libsinsp::filter::ast::identifier_expr* e) override;
void visit(libsinsp::filter::ast::value_expr* e) override;
void visit(libsinsp::filter::ast::list_expr* e) override;
void visit(libsinsp::filter::ast::unary_check_expr* e) override;
void visit(libsinsp::filter::ast::binary_check_expr* e) override;
void visit(libsinsp::filter::ast::field_expr* e) override;
void visit(libsinsp::filter::ast::field_transformer_expr* e) override;
};
void visit(libsinsp::filter::ast::and_expr* e) override;
void visit(libsinsp::filter::ast::or_expr* e) override;
void visit(libsinsp::filter::ast::not_expr* e) override;
void visit(libsinsp::filter::ast::identifier_expr* e) override;
void visit(libsinsp::filter::ast::value_expr* e) override;
void visit(libsinsp::filter::ast::list_expr* e) override;
void visit(libsinsp::filter::ast::unary_check_expr* e) override;
void visit(libsinsp::filter::ast::binary_check_expr* e) override;
void visit(libsinsp::filter::ast::field_expr* e) override;
void visit(libsinsp::filter::ast::field_transformer_expr* e) override;
};
std::vector<value_info> m_errors;
std::vector<value_info> m_unknown_macros;
std::vector<value_info> m_resolved_macros;
macro_defs m_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;
};

View File

@@ -17,12 +17,10 @@ limitations under the License.
#include "filter_ruleset.h"
void filter_ruleset::set_engine_state(const filter_ruleset::engine_state_funcs& engine_state)
{
void filter_ruleset::set_engine_state(const filter_ruleset::engine_state_funcs& engine_state) {
m_engine_state = engine_state;
}
filter_ruleset::engine_state_funcs& filter_ruleset::get_engine_state()
{
filter_ruleset::engine_state_funcs& filter_ruleset::get_engine_state() {
return m_engine_state;
}

View File

@@ -25,25 +25,22 @@ limitations under the License.
#include <libsinsp/events/sinsp_events.h>
/*!
\brief Manages a set of rulesets. A ruleset is a set of
enabled rules that is able to process events and find matches for those rules.
\brief Manages a set of rulesets. A ruleset is a set of
enabled rules that is able to process events and find matches for those rules.
*/
class filter_ruleset
{
class filter_ruleset {
public:
// A set of functions that can be used to retrieve state from
// the falco engine that created this ruleset.
struct engine_state_funcs
{
using ruleset_retriever_func_t = std::function<bool(const std::string &, std::shared_ptr<filter_ruleset> &ruleset)>;
struct engine_state_funcs {
using ruleset_retriever_func_t =
std::function<bool(const std::string &, std::shared_ptr<filter_ruleset> &ruleset)>;
ruleset_retriever_func_t get_ruleset;
};
enum class match_type {
exact, substring, wildcard
};
enum class match_type { exact, substring, wildcard };
virtual ~filter_ruleset() = default;
@@ -51,198 +48,171 @@ public:
engine_state_funcs &get_engine_state();
/*!
\brief Adds a rule and its filtering filter + condition inside the manager.
\brief Adds a rule and its filtering filter + condition inside the manager.
This method only adds the rule inside the internal collection,
but does not enable it for any ruleset. The rule must be enabled
for one or more rulesets with the enable() or enable_tags() methods.
The ast representation of the rule's condition is provided to allow
the filter_ruleset object to parse the ast to obtain event types
or do other analysis/indexing of the condition.
\param rule The rule to be added
\param the filter representing the rule's filtering condition.
\param condition The AST representing the rule's filtering condition
but does not enable it for any ruleset. The rule must be enabled
for one or more rulesets with the enable() or enable_tags() methods.
The ast representation of the rule's condition is provided to allow
the filter_ruleset object to parse the ast to obtain event types
or do other analysis/indexing of the condition.
\param rule The rule to be added
\param the filter representing the rule's filtering condition.
\param condition The AST representing the rule's filtering condition
*/
virtual void add(
const falco_rule& rule,
std::shared_ptr<sinsp_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) = 0;
virtual void add(const falco_rule &rule,
std::shared_ptr<sinsp_filter> filter,
std::shared_ptr<libsinsp::filter::ast::expr> condition) = 0;
/*!
\brief Adds all rules contained in the provided
rule_loader::compile_output struct. Only
those rules with the provided source and those rules
with priority >= min_priority should be added. The
intent is that this replaces add(). However, we retain
add() for backwards compatibility. Any rules added via
add() are also added to this ruleset. The default
implementation iterates over rules and calls add(),
but can be overridden.
\param rule The compile output.
\param min_priority Only add rules with priority above this priority.
\param source Only add rules with source equal to this source.
\brief Adds all rules contained in the provided
rule_loader::compile_output struct. Only
those rules with the provided source and those rules
with priority >= min_priority should be added. The
intent is that this replaces add(). However, we retain
add() for backwards compatibility. Any rules added via
add() are also added to this ruleset. The default
implementation iterates over rules and calls add(),
but can be overridden.
\param rule The compile output.
\param min_priority Only add rules with priority above this priority.
\param source Only add rules with source equal to this source.
*/
virtual void add_compile_output(
const rule_loader::compile_output& compile_output,
falco_common::priority_type min_priority,
const std::string& source)
{
for (const auto& rule : compile_output.rules)
{
if(rule.priority <= min_priority &&
rule.source == source)
{
virtual void add_compile_output(const rule_loader::compile_output &compile_output,
falco_common::priority_type min_priority,
const std::string &source) {
for(const auto &rule : compile_output.rules) {
if(rule.priority <= min_priority && rule.source == source) {
add(rule, rule.filter, rule.condition);
}
}
};
/*!
\brief Erases the internal state. All rules are disabled in each
ruleset, and all the rules defined with add() are removed.
\brief Erases the internal state. All rules are disabled in each
ruleset, and all the rules defined with add() are removed.
*/
virtual void clear() = 0;
/*!
\brief This is meant to be called after all rules have been added
with add() and enabled on the given ruleset with enable()/enable_tags().
\brief This is meant to be called after all rules have been added
with add() and enabled on the given ruleset with enable()/enable_tags().
*/
virtual void on_loading_complete() = 0;
/*!
\brief Processes an event and tries to find a match in a given ruleset.
\return true if a match is found, false otherwise
\param evt The event to be processed
\param match If true is returned, this is filled-out with the first rule
that matched the event
\param ruleset_id The id of the ruleset to be used
\brief Processes an event and tries to find a match in a given ruleset.
\return true if a match is found, false otherwise
\param evt The event to be processed
\param match If true is returned, this is filled-out with the first rule
that matched the event
\param ruleset_id The id of the ruleset to be used
*/
virtual bool run(
sinsp_evt *evt,
falco_rule& match,
uint16_t ruleset_id) = 0;
/*!
\brief Processes an event and tries to find a match in a given ruleset.
\return true if a match is found, false otherwise
\param evt The event to be processed
\param matches If true is returned, this is filled-out with all the rules
that matched the event
\param ruleset_id The id of the ruleset to be used
*/
virtual bool run(
sinsp_evt *evt,
std::vector<falco_rule>& matches,
uint16_t ruleset_id) = 0;
virtual bool run(sinsp_evt *evt, falco_rule &match, uint16_t ruleset_id) = 0;
/*!
\brief Returns the number of rules enabled in a given ruleset
\param ruleset_id The id of the ruleset to be used
\brief Processes an event and tries to find a match in a given ruleset.
\return true if a match is found, false otherwise
\param evt The event to be processed
\param matches If true is returned, this is filled-out with all the rules
that matched the event
\param ruleset_id The id of the ruleset to be used
*/
virtual bool run(sinsp_evt *evt, std::vector<falco_rule> &matches, uint16_t ruleset_id) = 0;
/*!
\brief Returns the number of rules enabled in a given ruleset
\param ruleset_id The id of the ruleset to be used
*/
virtual uint64_t enabled_count(uint16_t ruleset_id) = 0;
/*!
\brief Returns the union of the evttypes of all the rules enabled
in a given ruleset
\param ruleset_id The id of the ruleset to be used
\deprecated Must use the new typing-improved `enabled_event_codes`
and `enabled_sc_codes` instead
\note todo(jasondellaluce): remove this in future refactors
\brief Returns the union of the evttypes of all the rules enabled
in a given ruleset
\param ruleset_id The id of the ruleset to be used
\deprecated Must use the new typing-improved `enabled_event_codes`
and `enabled_sc_codes` instead
\note todo(jasondellaluce): remove this in future refactors
*/
virtual void enabled_evttypes(
std::set<uint16_t> &evttypes,
uint16_t ruleset) = 0;
/*!
\brief Returns the all the ppm_sc_codes matching the rules
enabled in a given ruleset.
\param ruleset_id The id of the ruleset to be used
*/
virtual libsinsp::events::set<ppm_sc_code> enabled_sc_codes(
uint16_t ruleset) = 0;
/*!
\brief Returns the all the ppm_event_codes matching the rules
enabled in a given ruleset.
\param ruleset_id The id of the ruleset to be used
*/
virtual libsinsp::events::set<ppm_event_code> enabled_event_codes(
uint16_t ruleset) = 0;
virtual void enabled_evttypes(std::set<uint16_t> &evttypes, uint16_t ruleset) = 0;
/*!
\brief Find those rules matching the provided substring and enable
them in the provided ruleset.
\param pattern Pattern used to match rule names.
\param match How to match the pattern against rules:
- exact: rules that has the same exact name as the pattern are matched
- substring: rules having the pattern as a substring in the rule are matched.
An empty pattern matches all rules.
- wildcard: rules with names that satisfies a wildcard (*) pattern are matched.
A "*" pattern matches all rules.
Wildcards can appear anywhere in the pattern (e.g. "*hello*world*")
\param ruleset_id The id of the ruleset to be used
\brief Returns the all the ppm_sc_codes matching the rules
enabled in a given ruleset.
\param ruleset_id The id of the ruleset to be used
*/
virtual void enable(
const std::string &pattern,
match_type match,
uint16_t ruleset_id) = 0;
virtual libsinsp::events::set<ppm_sc_code> enabled_sc_codes(uint16_t ruleset) = 0;
/*!
\brief Find those rules matching the provided substring and disable
them in the provided ruleset.
\param pattern Pattern used to match rule names.
\param match How to match the pattern against rules:
- exact: rules that has the same exact name as the pattern are matched
- substring: rules having the pattern as a substring in the rule are matched.
An empty pattern matches all rules.
- wildcard: rules with names that satisfies a wildcard (*) pattern are matched.
A "*" pattern matches all rules.
Wildcards can appear anywhere in the pattern (e.g. "*hello*world*")
\param ruleset_id The id of the ruleset to be used
\brief Returns the all the ppm_event_codes matching the rules
enabled in a given ruleset.
\param ruleset_id The id of the ruleset to be used
*/
virtual void disable(
const std::string &pattern,
match_type match,
uint16_t ruleset_id) = 0;
virtual libsinsp::events::set<ppm_event_code> enabled_event_codes(uint16_t ruleset) = 0;
/*!
\brief Find those rules that have a tag in the set of tags and
enable them for the provided ruleset. Note that the enabled
status is on the rules, and not the tags--if a rule R has
tags (a, b), and you call enable_tags([a]) and then
disable_tags([b]), R will be disabled despite the
fact it has tag a and was enabled by the first call to
enable_tags.
\param substring Tags used to match ruless
\param ruleset_id The id of the ruleset to be used
\brief Find those rules matching the provided substring and enable
them in the provided ruleset.
\param pattern Pattern used to match rule names.
\param match How to match the pattern against rules:
- exact: rules that has the same exact name as the pattern are matched
- substring: rules having the pattern as a substring in the rule are matched.
An empty pattern matches all rules.
- wildcard: rules with names that satisfies a wildcard (*) pattern are matched.
A "*" pattern matches all rules.
Wildcards can appear anywhere in the pattern (e.g. "*hello*world*")
\param ruleset_id The id of the ruleset to be used
*/
virtual void enable_tags(
const std::set<std::string> &tags,
uint16_t ruleset_id) = 0;
virtual void enable(const std::string &pattern, match_type match, uint16_t ruleset_id) = 0;
/*!
\brief Find those rules that have a tag in the set of tags and
disable them for the provided ruleset. Note that the disabled
status is on the rules, and not the tags--if a rule R has
tags (a, b), and you call enable_tags([a]) and then
disable_tags([b]), R will be disabled despite the
fact it has tag a and was enabled by the first call to
enable_tags.
\param substring Tags used to match ruless
\param ruleset_id The id of the ruleset to be used
\brief Find those rules matching the provided substring and disable
them in the provided ruleset.
\param pattern Pattern used to match rule names.
\param match How to match the pattern against rules:
- exact: rules that has the same exact name as the pattern are matched
- substring: rules having the pattern as a substring in the rule are matched.
An empty pattern matches all rules.
- wildcard: rules with names that satisfies a wildcard (*) pattern are matched.
A "*" pattern matches all rules.
Wildcards can appear anywhere in the pattern (e.g. "*hello*world*")
\param ruleset_id The id of the ruleset to be used
*/
virtual void disable_tags(
const std::set<std::string> &tags,
uint16_t ruleset_id) = 0;
virtual void disable(const std::string &pattern, match_type match, uint16_t ruleset_id) = 0;
/*!
\brief Find those rules that have a tag in the set of tags and
enable them for the provided ruleset. Note that the enabled
status is on the rules, and not the tags--if a rule R has
tags (a, b), and you call enable_tags([a]) and then
disable_tags([b]), R will be disabled despite the
fact it has tag a and was enabled by the first call to
enable_tags.
\param substring Tags used to match ruless
\param ruleset_id The id of the ruleset to be used
*/
virtual void enable_tags(const std::set<std::string> &tags, uint16_t ruleset_id) = 0;
/*!
\brief Find those rules that have a tag in the set of tags and
disable them for the provided ruleset. Note that the disabled
status is on the rules, and not the tags--if a rule R has
tags (a, b), and you call enable_tags([a]) and then
disable_tags([b]), R will be disabled despite the
fact it has tag a and was enabled by the first call to
enable_tags.
\param substring Tags used to match ruless
\param ruleset_id The id of the ruleset to be used
*/
virtual void disable_tags(const std::set<std::string> &tags, uint16_t ruleset_id) = 0;
private:
engine_state_funcs m_engine_state;
};
/*!
\brief Represents a factory that creates filter_ruleset objects
\brief Represents a factory that creates filter_ruleset objects
*/
class filter_ruleset_factory
{
class filter_ruleset_factory {
public:
virtual ~filter_ruleset_factory() = default;

View File

@@ -22,22 +22,18 @@ using namespace falco;
static const char* no_value = "<NA>";
static inline bool is_unsafe_field(const std::string& f)
{
return !strncmp(f.c_str(), "ka.", strlen("ka."))
|| !strncmp(f.c_str(), "jevt.", strlen("jevt."));
static inline bool is_unsafe_field(const std::string& f) {
return !strncmp(f.c_str(), "ka.", strlen("ka.")) ||
!strncmp(f.c_str(), "jevt.", strlen("jevt."));
}
static inline bool is_equality_operator(const std::string& op)
{
return op == "==" || op == "=" || op == "!="
|| op == "in" || op == "intersects" || op == "pmatch";
static inline bool is_equality_operator(const std::string& op) {
return op == "==" || op == "=" || op == "!=" || op == "in" || op == "intersects" ||
op == "pmatch";
}
bool filter_warning_resolver::run(
libsinsp::filter::ast::expr* filter,
std::set<load_result::warning_code>& warnings) const
{
bool filter_warning_resolver::run(libsinsp::filter::ast::expr* filter,
std::set<load_result::warning_code>& warnings) const {
visitor v;
auto size = warnings.size();
v.m_is_equality_check = false;
@@ -46,40 +42,29 @@ bool filter_warning_resolver::run(
return warnings.size() > size;
}
void filter_warning_resolver::visitor::visit(
libsinsp::filter::ast::binary_check_expr* e)
{
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::binary_check_expr* e) {
m_last_node_is_unsafe_field = false;
e->left->accept(this);
if (m_last_node_is_unsafe_field && is_equality_operator(e->op))
{
if(m_last_node_is_unsafe_field && is_equality_operator(e->op)) {
m_is_equality_check = true;
e->right->accept(this);
m_is_equality_check = false;
}
}
void filter_warning_resolver::visitor::visit(
libsinsp::filter::ast::field_expr* e)
{
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::field_expr* e) {
m_last_node_is_unsafe_field = is_unsafe_field(e->field);
}
void filter_warning_resolver::visitor::visit(
libsinsp::filter::ast::value_expr* e)
{
if (m_is_equality_check && e->value == no_value)
{
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::value_expr* e) {
if(m_is_equality_check && e->value == no_value) {
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
}
}
void filter_warning_resolver::visitor::visit(
libsinsp::filter::ast::list_expr* e)
{
if (m_is_equality_check
&& std::find(e->values.begin(), e->values.end(), no_value) != e->values.end())
{
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::list_expr* e) {
if(m_is_equality_check &&
std::find(e->values.begin(), e->values.end(), no_value) != e->values.end()) {
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
}
}

Some files were not shown because too many files have changed in this diff Show More