Compare commits

...

323 Commits

Author SHA1 Message Date
Mark Stemm
5178f7e8fb Don't create rulesets a second time when loading rules
Currently, m_sources.ruleset is created twice:

1. When calling add_source()
2. When calling load_rules()

We shouldn't do this twice, so remove the second create.

Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
2023-06-02 14:02:02 -07:00
Melissa Kilby
e89f08ff3f cleanup(docs): adjust release.md
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-06-02 19:44:22 +02:00
Melissa Kilby
4f3a60f193 cleanup(docs): adjust release.md
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-06-02 19:44:22 +02:00
Melissa Kilby
f682a1dbb8 chore(config): adjust maturity level for modern_bpf.cpus_for_each_syscall_buffer
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-06-02 19:44:22 +02:00
Melissa Kilby
3a0cdd3cb7 cleanup(docs): update release.md w/ relevant info for modern_bpf driver
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-06-02 19:44:22 +02:00
Federico Di Pierro
03128368cf update(cmake): bumped libs to 0.11.0-rc5 and driver to 5.0.1.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-06-01 12:39:16 +02:00
dependabot[bot]
620c83d6a4 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `3471984` to `16fb709`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](3471984e0c...16fb709527)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-06-01 10:02:16 +02:00
Lorenzo Susini
9fda7dfb93 fix(userspace/engine): store alternatives as array in -L json output
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-31 16:16:31 +02:00
Melissa Kilby
017075c346 cleanup(docs): mention roadmap in readme
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 16:03:31 +02:00
Melissa Kilby
4338a8adec cleanup(docs): adjust readme
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 16:03:31 +02:00
Melissa Kilby
18345b1a1a cleanup(docs): adjust falco readme style and content
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 16:03:31 +02:00
Melissa Kilby
1e6d01621f fix formatting
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 15:48:32 +02:00
Melissa Kilby
aa8c13b4e4 cleanup(userspace): adjust stats n_drops_perc
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 15:48:32 +02:00
Melissa Kilby
efd0c7421e cleanup(userspace,config): apply reviewers suggestions
Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 15:48:32 +02:00
Melissa Kilby
b29f6f4b2f cleanup(config): add send_numeric_zero_values option to metrics
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 15:48:32 +02:00
Melissa Kilby
e775fc6f5b cleanup(userspace): improve metrics UX
add send_numeric_zero_values config to allow users to save space
when using metrics option, while still also allowing
to send all keys (especially because we don't document the schema)

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-31 15:48:32 +02:00
Daniel Wright
2e7a0b026f feat: add jq and curl to falco-no-driver docker image
To supoprt the use of outputs that are documented in the falco
examples (e.g. jq piped to curl) I would like to propose including
these tools in the falco-no-driver image. They add a very minimal
size and dependency to the image but would make things a lot easier
for users getting started.

Closes #2580

Signed-off-by: Daniel Wright <danielwright@bitgo.com>
2023-05-31 13:21:31 +02:00
Leonardo Grasso
25d23168f4 docs(proposals): roadamap mgt non-goals
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Co-authored-by: Massimiliano Giovagnoli <me@maxgio.it>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-05-30 15:51:30 +02:00
Leonardo Grasso
2f6f098b07 docs(proposals): apply suggestions from review
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-05-30 15:51:30 +02:00
Leonardo Grasso
daa53fb69b docs(proposals): scope of the WG for Falco roadmap
Co-authored-by: Luca Guerra <luca@guerra.sh>
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-05-30 15:51:30 +02:00
Leonardo Grasso
403ad1f5e2 docs(proposals): Falco roadmap management
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-05-30 15:51:30 +02:00
Lorenzo Susini
79b9d0ff21 fix(userspace/engine): store required engine version as string in -L json output
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-30 12:09:30 +02:00
Lorenzo Susini
6e12b95dd2 update(userspace/engine): address jasondellaluce comments
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-30 10:45:30 +02:00
Lorenzo Susini
0bd609d5a4 update(userspace/falco): update description of -l and -L flags
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-30 10:45:30 +02:00
Lorenzo Susini
cfb96d0562 update(userspace/engine): adding required_engine_version, required_plugin_versions and exception names to -L output
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-30 10:45:30 +02:00
Lorenzo Susini
75f556e3b7 update(userspace/engine): add required_engine_version to rule collector
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-30 10:45:30 +02:00
Jason Dellaluce
1263c67ac6 chore: apply codespell suggestions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-29 12:26:24 +02:00
Jason Dellaluce
a9ea18b99a fix(userspace/falco): report plugin deps rules issues in any case
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-29 12:26:24 +02:00
Daniel Wright
498b64b469 feat: add image source OCI label to docker images
Closes #2591

Signed-off-by: Daniel Wright <danielwright@bitgo.com>
2023-05-29 11:17:24 +02:00
Melissa Kilby
e9402b7606 cleanup(config): apply reviewers suggestions
* place falco plugins after falco rules config
* change metadata_download description
* minor formatting

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-29 11:09:24 +02:00
Melissa Kilby
08ac4ea975 cleanup(config): rephrase numerous configs for technical clarity + add more information
* rephrase descriptions for numerous config options
  without changing the original content, meaning changes
  reflect language improvements and minor extensions
  (such as adding justifications or what it is) only
* add Falco environment variables section
* add Guidance for Kubernetes container engine command-line args settings
* general rewrap formatting w/ IDE
* minor additional re-ordering of configs
* minor general language adjustments

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-29 11:09:24 +02:00
Melissa Kilby
f00b853fd4 cleanup(config): fine tune new configs ordering and organization
* incorporate reviewers suggestions re ordering and phrasing
* minor additional cleanups

Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-29 11:09:24 +02:00
Melissa Kilby
e269057c41 cleanup(config): improve config descriptions for the basic config options
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-29 11:09:24 +02:00
Melissa Kilby
b423754575 cleanup(config): re-arrange falco.yaml configs in logical categories
* add an index for logical categories
* move configs around without changing description content,
  solely add a uniform header to each config
* indicate "Stable" or "Experimental" for most configs
  to indicate current stability or maturity

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-29 11:09:24 +02:00
Jason Dellaluce
354c06567a update(cmake): bump libs to 0.11.0-rc3
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-25 17:43:11 +02:00
Jason Dellaluce
bc8b987c59 update(cmake): bump libs to latest dev version
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-25 17:43:11 +02:00
Jason Dellaluce
aed64b3076 update(cmake): bump plugins to latest dev versions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-25 17:43:11 +02:00
Jason Dellaluce
b58a373835 chore(userspace/falco): always print invalid syscalls from custom set
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-25 14:14:11 +02:00
Roberto Scolaro
2dadb05af6 fix(userspace/falco/app/actions): hotreload on wrong metrics
Signed-off-by: Roberto Scolaro <roberto.scolaro21@gmail.com>
Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-25 14:09:10 +02:00
Andrea Terzolo
1098b6f7ca cleanup: rename a file
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-05-25 10:23:10 +02:00
Andrea Terzolo
1a359f5806 fix: add a check on online CPUs
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-05-25 10:23:10 +02:00
dependabot[bot]
6713ace5c6 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `b2290ad` to `3471984`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](b2290adef9...3471984e0c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-24 19:53:07 +02:00
Jason Dellaluce
0943456ffe fix(userspace/falco): don't hang on terminating error when multi sourcing
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-24 19:12:06 +02:00
Luca Guerra
cc986b7749 update(build): bump libs to 0.11.0-rc2
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-24 15:52:06 +02:00
Luca Guerra
464bc0f4d3 update(build): bump falcoctl version
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-24 10:44:37 +02:00
dependabot[bot]
9f6b57f15a build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `3f52480` to `b2290ad`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](3f52480618...b2290adef9)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-24 10:14:36 +02:00
Jason Dellaluce
b40a6bc703 fix(userspace/falco): right boundary checks for strncat
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-23 16:53:35 +02:00
Jason Dellaluce
75720534d7 fix(userspace/falco): solve escape issues in grpc output
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-23 16:53:35 +02:00
Jason Dellaluce
00acd17ba1 fix(userspace/faclco): output drop perc metric only if drops are present
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-23 16:53:35 +02:00
Jason Dellaluce
d550552fc1 fix(userspace/falco): properly format numeric values in metrics
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-23 16:53:35 +02:00
Federico Di Pierro
8c5ebde6a5 cleanup(ci): cleaned up circleci workflow.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-23 10:26:34 +02:00
Luca Guerra
ca891ad9b2 update(ci): use repo instead of master branch for reusable workflows
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-23 10:03:34 +02:00
dependabot[bot]
2c291424e9 build(deps): Bump requests from 2.26.0 to 2.31.0 in /test
Bumps [requests](https://github.com/psf/requests) from 2.26.0 to 2.31.0.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.26.0...v2.31.0)

---
updated-dependencies:
- dependency-name: requests
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-23 10:02:34 +02:00
Melissa Kilby
d4c42814d6 cleanup(config): improve metrics config description for technical clarity
Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
eaa4354ddf cleanup(userspace/falco): new consistent metrics output fields classes falco. and scap.
* Ensure each metric field name more consistently adheres to the grammar used in Falco rules:
  * `falco.`: new field class representing userspace counters, statistics, resource utilization, or necessary information fields
  * `scap.`: new field class represents counters and statistics mostly obtained from Falco's kernel instrumentation before events are sent to userspace, but can include scap userspace stats as well
* minor cleanup

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
9b341b2c49 new(unit_tests): tests for prometheus compliant time durations
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
8e0c89d3b4 cleanup(userspace/engine): prometheus compliant regex parsing for metrics interval
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
698ff25f1e cleanup(config): improve config for new metrics
Co-authored-by: Stanley Chan <pocketgamer5000@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
fcecde845d cleanup(userspace): move parse_prometheus_interval to falco_utils
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
f2318a9ac5 cleanup(userspace/falco): address reviewers comments + cleanup
* prefix counters and stats belonging to kernel space w/ `k.` else `u.` for userspace
* add n_drops_perc from old stats writer schema
* revert one change: file output shall reflect exact same "output_fields" key as rule output, note that src is already part of the "output_fields" schema.

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Jason Dellaluce
5d35cda8dc update(userspace): minor polishing
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-23 09:58:34 +02:00
Jason Dellaluce
f117d5273c update(userspace): refactor metrics data flow and fix bugs
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
f0ac327f98 cleanup(userspace/falco): add more fields to metrics
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
e37027a1d0 cleanup(userspace/falco): address reviewers comments
* renaming to `metrics` for technical clarity
* adopt Prometheus like metrics interval settings

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
134d2630e9 new(userspace/falco): stats v2 config option to convert memory metrics to MB
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
010e45a4af new(userspace/falco): extend stats v2 configs w/ relevant env variables
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
78dbfab48f feat(userspace/falco)!: use new resource_utilization metrics / stats v2 schema for stats file ouput logs
These changes break the old stats file output schema and consolidates
them with the new schema.

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
4d24bcdd2f new(userspace/falco)!: introduce native support for resource_utilization metrics / stats v2
Intended to phase out previous stats writer settings and log schema.

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Melissa Kilby
44d9f99c72 new(userspace/falco)!: new stats v2 configs
Intended to phase out previous stats writer settings and log schema.

Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-05-23 09:58:34 +02:00
Jason Dellaluce
7248284b12 chore(userspace/falco/app): print all supported plugin caps
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-22 15:23:32 +02:00
Luca Guerra
f72489e431 fix(ci): get the manifest for the correct tag
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-22 10:57:31 +02:00
dependabot[bot]
2863ab3756 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `3f52480` to `6da15ae`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](3f52480618...6da15ae98c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-22 10:11:15 +02:00
Federico Di Pierro
8268c47160 fix(ci): properly use docker save to store images.
No buildx-docker does not support direct storing to tar.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-19 22:10:06 +02:00
Federico Di Pierro
e16cf2661e fix(ci): docker arg is named TARGETARCH.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-19 18:17:05 +02:00
Federico Di Pierro
a28347d150 fix(ci): properly pass TARGET_ARCH as build-arg to docker.
It gets automatically defined in buildx.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-19 16:48:05 +02:00
Lorenzo Susini
e47ece4de9 update(userspace/engine): address jasondellaluce comments
- avoiding inspector to be allocated for each rule
- use two boolean values for expecting macros and lists
- move items of lists alongside name, under info
- use snake case for json output, like we do for e.g alerts
- correctly retrieve evt names
- consider two levels of lists for exception operators

Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
a269866976 test(unit_tests/engine): test filter_details_resolver class
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
1195b1e7f0 update(userspace/engine): better modularize the code for getting json details
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
e11b4c4430 update(userspace/engine): add event codes to json output
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
46cbc3c589 update(userspace/engine): add info about all macros and lists in -L option
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
e30729555b update(userspace/engine): add enabled information to json output
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
727aed0c03 update(userspace/engine): avoid solving macros AST at each cycle when getting details of all rules
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
c1623771d8 update(userspace/engine): correctly use describe rule based on config
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
9947962cb8 update(userspace/engine): let describe_rule function print out json details when requested
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Lorenzo Susini
a6542a6487 new(userspace/engine): introduce new class to get details about rules
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-05-19 15:56:05 +02:00
Federico Di Pierro
35a8a2e4d3 chore(ci): fixed up missing '\' chars.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-05-19 14:55:05 +02:00
Federico Di Pierro
9b96b34445 fix(ci): use normal docker to build docker images, instead of buildx.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-19 14:55:05 +02:00
Jason Dellaluce
2818f0906e update(cmake): bump plugins to latest dev versions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
c603055acf fix(userspace/engine): don't count async event for evttype warning
Co-authored-by: Grzegorz Nosek <grzegorz.nosek@sysdig.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
2d53fed0b8 update(cmake): bump libs to 2e9e6346eefeddd0afce7b6a06cb42d4265615dd
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
4fab0d5e38 update(cmake): bump libs to 8f52cdc56fce7ff95adaaa58eeb706da244bf0ce
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
81c6564636 fix(ci): solve CI issues
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
0026471714 update(cmake): bump plugins to dev versions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
71e991b606 update(cmake): bump libs to b596458acb265028dbf0505ca45111e464470b4d
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
bb04892baf fix(userspace/falco): avoid double plugin initializations
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
9df72e0f2a fix(userspace/falco/app): properly populate filtercheck lists
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
4e8d1f025c fix(userspace/falco/app): skip unnecessary app steps
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
9bfce8cfae update(userspace): make sure that async event is always matched in rules
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
26d9448ba7 fix(ci): set cmake build type in Falco build jobs
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
fe299a0c9b update(cmake): bump driver to 5.0.0+driver
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
733ea88ab3 fix(userspace/falco): properly init configuration
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
b2615de062 new(userspace/falco/app): print a warning if multiple plugins for same source are loaded
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
0649be619b update(userspace/falco/app): support nodriver open mode and plugins sourcing system events
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
301c4efeb7 update(userspace/falco): support new plugin API definitions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
5175a04c6b update(userspace/engine): bump engine checksum
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
3681cacda1 new(userspace/falco): add new --nodriver option
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
6c7754729b update(CMakeLists): fix c++17 compilation issues
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Jason Dellaluce
0e4595596e update(cmake): bump libs and driver to 0b9ca98fee2453a16f4538db55dcfa34bc8f5aef
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-05-19 12:15:04 +02:00
Stanley Chan
3403225d8d cleanup(docs): remove extraneous whitespace in falco.yaml
Signed-off-by: Stanley Chan <pocketgamer5000@gmail.com>
2023-05-18 15:49:03 +02:00
Stanley Chan
1125b92fc3 docs: improve documentation and description of base_syscalls option
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Stanley Chan <pocketgamer5000@gmail.com>
2023-05-18 15:49:03 +02:00
Aizhamal Nurmamat kyzy
52fe77cf5c Update brand/README.md
Adding the proper link to the brand guides

Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Aizhamal Nurmamat kyzy <aizhamal@google.com>
2023-05-18 15:24:04 +02:00
Aizhamal Nurmamat kyzy
47cb32998e Adding back the information on Falco branding.
Signed-off-by: Aizhamal Nurmamat kyzy <aizhamal@sysdig.com>
2023-05-18 15:24:04 +02:00
Aizhamal Nurmamat kyzy
455e4346cd Update brand/README.md
Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Signed-off-by: Aizhamal Nurmamat kyzy <aizhamal@google.com>
2023-05-18 15:24:04 +02:00
Aizhamal Nurmamat kyzy
67993c8fa3 Updating Falco branding guidelines
Signed-off-by: Aizhamal Nurmamat kyzy <aizhamal@sysdig.com>
2023-05-18 15:24:04 +02:00
dependabot[bot]
6f198556be build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `f773578` to `6da15ae`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](f7735788b1...6da15ae98c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-18 09:11:03 +02:00
Andrea Terzolo
696fa43dc2 cleanup(actions): now modern bpf support -A flag
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-05-17 12:19:00 +02:00
Federico Di Pierro
7414c2d161 fix(ci): properly pass FALCO_VERSION loaded from extern to docker build for centos7 and arm64 builds.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-17 12:16:00 +02:00
Federico Di Pierro
9c483adafa fix(cmake): properly exclude prereleases when fetching latest tag from cmake.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-17 12:16:00 +02:00
Federico Di Pierro
577bccabd0 new(scripts): updated falco-driver-loader to properly support talos.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-16 16:49:55 +02:00
Luca Guerra
09b5cb7c7b fix(ci): load falco image before building falco-driver-loader
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-15 15:35:24 +02:00
Luca Guerra
92f884e070 new(ci): sign releases with cosign
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-12 16:03:43 +02:00
Luca Guerra
60a006f0b1 fix(ci): correctly tag slim manifest
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-12 14:27:42 +02:00
Luca Guerra
ea0b44dc56 fix(ci): simplify and fix multi-arch image publishing process
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-12 12:28:43 +02:00
Andrea Terzolo
e83dbe85f7 cleanup(config): modern bpf is no more experimental
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-05-12 12:27:45 +02:00
Luca Guerra
f5c7574eba update(ci): fail on non-semver release
Signed-off-by: Luca Guerra <luca@guerra.sh>
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-10 11:05:10 +02:00
Luca Guerra
b50ccd4cd1 update(ci): update needs for build docker
Signed-off-by: Luca Guerra <luca@guerra.sh>
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-10 11:05:10 +02:00
Luca Guerra
fb8205a2f7 update(ci): explicit branch name in action
Signed-off-by: Luca Guerra <luca@guerra.sh>
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
2023-05-10 11:05:10 +02:00
Luca Guerra
369f733a36 update(docs): clarify release checking in the readme
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-10 11:05:10 +02:00
Luca Guerra
7e5a578c89 update(readme): add pre-release instructions to RELEASE.md
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-10 11:05:10 +02:00
Luca Guerra
564eed2dee update(ci): move version computation logic to main jobs master/release
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-10 11:05:10 +02:00
Luca Guerra
24693a1e1e update(ci): move release outputs declaration
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-10 11:05:10 +02:00
Luca Guerra
33b0173657 update(ci): react to release publishing, rewire variables
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-10 11:05:10 +02:00
Luca Guerra
d4fa8d6d91 new(ci): add RC/prerelease support
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-10 11:05:10 +02:00
jabdr
f25c057ce8 Remove MAKEWRAPPER var
Signed-off-by: jabdr <jd@q321.de>
2023-05-04 13:14:32 +02:00
jabdr
e1492ae9df Use TMPDIR for falco-driver-loader
Signed-off-by: jabdr <jd@q321.de>
2023-05-04 13:14:32 +02:00
jabdr
b83b1e2578 falco-driver-loader add TMPDIR support
Closes 2517
Make wrapper now uses $TMPDIR if set.

Signed-off-by: jabdr <jd@q321.de>
2023-05-04 13:14:32 +02:00
dependabot[bot]
c18d545259 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `1bd7e4a` to `f773578`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](1bd7e4ac3a...f7735788b1)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-04 10:01:30 +02:00
Luca Guerra
b47ea18736 fix(ci): configure ECR public region
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-04 09:48:32 +02:00
Luca Guerra
253100ab75 fix(ci): falco images directory, ecr login
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-03 18:26:27 +02:00
Luca Guerra
293d4c51f1 fix(ci): separate rpm/bin/bin-static/deb packages before publication, rename bin-static
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-03 15:22:27 +02:00
dependabot[bot]
f006f2e01a build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `3f52480` to `1bd7e4a`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](3f52480618...1bd7e4ac3a)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-03 11:56:27 +02:00
Luca Guerra
5237aa196c fix(ci): add Cloudfront Distribution ID
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-02 14:25:07 +02:00
Luca Guerra
4e25367350 fix(ci): escape heredoc
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-05-02 09:47:30 +02:00
Federico Di Pierro
593404e79e chore(ci): build-musl-package does not need to wait for build-packages anymore.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-28 14:53:17 +02:00
Luca Guerra
6650a4f31f fix(ci): only add the secret key to env when necessary
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-04-28 13:21:17 +02:00
Luca Guerra
d1e6452ad7 fix(ci): download artifacts one by one
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-04-28 13:21:17 +02:00
Luca Guerra
6d0aff7463 fix(ci): update fetch-version steps
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-04-28 13:21:17 +02:00
Federico Di Pierro
a193a46981 chore(ci): properly document new reusable_build_packages step.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-04-28 10:14:16 +02:00
Federico Di Pierro
f448023a8f fix(ci): properly fetch Falco version in a single step, then force-use it in subsequent steps, in reusable build packages.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-28 10:14:16 +02:00
Federico Di Pierro
c225819186 chore(ci): build recent git from source in centos7 reusable build packages workflow.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-28 10:14:16 +02:00
Federico Di Pierro
a5efbc9483 fix(ci): try to fix Falco version.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-28 10:14:16 +02:00
Federico Di Pierro
ad75c87e21 chore(ci): properly install recent version of git (needed >= 2.18 by checkout action) to fix Falco versioning.
Moreover, fixed path to output packages from Falco `make package` target.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 20:14:15 +02:00
Luca Guerra
fb105c4b04 fix(ci): enable toolset before every make command
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-04-27 16:32:14 +02:00
Luca Guerra
fe8899c90a fix(ci): remove unnecessary mv
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-04-27 15:47:14 +02:00
Luca Guerra
2de8c06bb1 fix(ci): bucket -> bucket_suffix
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-04-27 15:03:14 +02:00
Federico Di Pierro
86d33ae5ab chore(ci): improved GPG_KEY management through an env.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
9d6a7d8ca3 chore(ci): use Noelware/docker-manifest-action pinned version to latest tag.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
d27828a0d2 chore(ci): added some comments.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
89f29e6d4b chore(ci): renamed bucket to bucket_suffix.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
2a22189222 chore(ci): added AWS ECR login to reusable_publish_docker.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Luca Guerra <luca@guerra.sh>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
a5620b81b2 chore(ci): reusable_public_packages needs proper permissions.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
b9c0ca3abe chore(ci): avoid publishing images in reusable_build_docker.yaml workflow.
Instead, store image tarballs as artifact and download them in `reusable_publish_docker.yaml` workflow,
to be finally merged in multi-arch images and pushed.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
008d908ee0 cleanup(ci): dropped test jobs in CI.yml.
Some small fixes in other workflows.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
2f11d9f506 chore(ci): install awscli in reusable_build_docker workflow.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
60d8c49772 fix(ci): do not use inputs.tagname. Instead, rely on github.ref_name.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
3693cd0685 chore(ci): test reusable_build_docker from PR CI.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
31da4b4c3d chore(ci): run reusable_build_docker workflow without any container.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
9551e9f277 chore(ci): added aws credentials role to the reusable_publish_packages workflow.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
2af7fd9f0f fix(ci): fixed reusable_build_packages to properly install git before invoking checkout action, to download full repo.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
1c3aa7a83b chore(ci): multiple fixes to new master and release ci jobs.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
18372323d9 cleanup(ci): dropped test arm64 job from pull_request CI, since it is now working.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
be13ee044e chore(ci): fixed up master and release yamls.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
ac4e27ccde update(ci): add an arm test CI job.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
d5b72f89f0 chore(ci): commented out circleCI master and release jobs.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
cafb804c11 chore(ci): disable on push: master trigger for ci.yml.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
6bf6a34a59 chore(ci): add proper concurrency groups for master and release CI.
Renamed `dev.yaml` to `master.yaml`.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
b138e4c9e1 new(ci): added github action workflows for dev and release CI (packages + docker images publish).
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 14:25:14 +02:00
Federico Di Pierro
53c9f3a743 fix(scripts): fix falco-driver-loader for some debian kernels.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-27 11:46:14 +02:00
Jason Dellaluce
1f4919bfe1 update: improve control and UX of ignored events
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-27 11:10:14 +02:00
Jason Dellaluce
4d24a02ad6 fix(userspace/falco): preserve config's plugin loading order
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-26 12:59:13 +02:00
Jason Dellaluce
8926022035 update: adapt Falco to new sinsp event source management
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-26 12:59:13 +02:00
Jason Dellaluce
95fa953398 update(cmake): bump libs and driver to ffcd702cf22e99d4d999c278be0cc3d713c6375c
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-26 12:59:13 +02:00
Federico Di Pierro
0d73f9624d update(scripts): updated falco-driver-loader to support al2022 and al2023.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-14 20:00:08 +02:00
dependabot[bot]
0f1f413221 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `5857874` to `1bd7e4a`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](5857874e95...1bd7e4ac3a)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-11 10:30:16 +02:00
dependabot[bot]
a77a58b2a9 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `694adf5` to `5857874`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](694adf59e0...5857874e95)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-06 12:51:56 +02:00
Jason Dellaluce
91cca0bd0e update(cmake): bump libs and drivers to 5b4dd9e2ae0cd2efeaf9da37d8c29631241d448c9ce5b0e35d8dd7f81d814034
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-04 19:39:53 +02:00
Jason Dellaluce
06d36d6e1b test(userspace/falco): leverage new sc_set_to_event_names API and solve last few todos
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-04 19:39:53 +02:00
Jason Dellaluce
3b64052832 update(userspace/falco): leverage new sc_set_to_event_names API
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-04-04 19:39:53 +02:00
Leonardo Grasso
88b9537618 chore(userspace/falco): remove Mesos support
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-04-04 18:31:52 +02:00
Leonardo Grasso
5c0cd6a170 update!: remove --mesos-api,-pmesos, and -pm command-line flags
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2023-04-04 18:31:52 +02:00
Melissa Kilby
306d76d06b cleanup(unit_tests): try making test_configure_interesting_sets more robust
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-04-04 17:55:52 +02:00
Federico Di Pierro
597f07ccae update(ci): only set concurrency group for PRs.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Mauro Ezequiel Moltrasio <mmoltras@redhat.com>
2023-04-04 17:09:53 +02:00
Federico Di Pierro
de23899e49 cleanup(ci): properly set a concurrency for CI workflows.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-04-04 17:09:53 +02:00
dependabot[bot]
2b29ff7ee6 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `e0646a0` to `694adf5`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](e0646a024f...694adf59e0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-04-03 20:05:46 +02:00
Melissa Kilby
0b6e243582 cleanup(app_acions): fine-tune base_syscalls.repair behavior
Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
e178174a93 update(cmake,userspace): bumped to libs master
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
dad382edd6 cleanup(config): adjust description for base_syscalls option
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
78daafb56c cleanup(app_actions): finalize base_syscalls.repair option
Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Jason Dellaluce
2b93a79521 refactor: apply review suggestions
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
3e0f0d3692 cleanup(unit_tests): revert some test extensions in interim
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
ea3571564b cleanup(unit_tests): add selection_custom_base_set_repair tests
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
e360175c15 fix(app_actions): enforce PPM_SC_SCHED_PROCESS_EXIT for base_syscalls.custom_set
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
692abf71eb new(app_actions): add base_syscalls.repair option
See https://github.com/falcosecurity/falco/issues/2433

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Melissa Kilby
1d66eb4d6d cleanup(app_actions): add warnings for invalid syscalls in user base_syscalls set
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-30 19:08:33 +02:00
Aldo Lacuku
31335d3c3b new(falco/config): add new configuration for http_output
Support for user provided CA certificate that can verify the remote server. Users
can provide path to the CA certiface store by providing a path to the dir or to the
CA store file. If needed users can decide to tell Falco to not verify the server.

Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2023-03-30 17:11:33 +02:00
dependabot[bot]
7f4fb624dd build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `0b0f50f` to `e0646a0`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](0b0f50fdf6...e0646a024f)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 21:31:31 +02:00
Federico Di Pierro
0b7ca2823e chore(userspace): apply review suggestions.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Jason Dellaluca <jasondellaluce@gmail.com>
2023-03-28 19:01:30 +02:00
Federico Di Pierro
b2e03b1938 chore(userspace): syscall_drop_failed -> syscall_drop_failed_exit.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-28 19:01:30 +02:00
Federico Di Pierro
70c6c93389 chore(userspace): improved wording.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-03-28 19:01:30 +02:00
Federico Di Pierro
bd13ba70e3 update(cmake): bumped to latest libs/driver.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-03-28 19:01:30 +02:00
Federico Di Pierro
f8f7e73a7f update(docs): properly document new option in config file.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-03-28 19:01:30 +02:00
Federico Di Pierro
bf5e340833 new(userspace/falco): added syscall_drop_failed option to drop failed syscalls exit events.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-03-28 19:01:30 +02:00
Federico Di Pierro
804e6fc122 update(cmake): bumped libs to latest master.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-03-28 19:01:30 +02:00
dependabot[bot]
4836978ba9 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `3f52480` to `0b0f50f`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](3f52480618...0b0f50fdf6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-23 10:50:12 +01:00
Federico Di Pierro
e6078c8d16 chore(userspace): updated fields checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-03-22 11:17:07 +01:00
Federico Di Pierro
17b170b4f9 update(cmake,userspace): bumped to libs master.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-03-22 11:17:07 +01:00
dependabot[bot]
e4d575b10d build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `dab4474` to `3f52480`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](dab44746af...3f52480618)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-21 12:24:44 +01:00
rabbitstack
03285f4140 define Windows equivalent for srandom and random functions
Signed-off-by: rabbitstack <nedim.sabic@sysdig.com>
2023-03-17 10:23:26 +01:00
dependabot[bot]
9c5d643a90 build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `5b6e2c0` to `dab4474`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](5b6e2c0241...dab44746af)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-17 10:20:26 +01:00
Jason Dellaluce
93ae6bb609 chore(userspace/falco): fix codespell typos
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
e07e3abfb5 update(userspace/falco): implement debouncing logic in restart handler
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
3f69d46f9a update(userspace/falco): minor compilation improvements
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
647441c06c fix(userspace/falco): solve gettid compilation issues
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
cd155ed6f5 refactor(userspace/falco): update actions to use new hot restarter utility with dry-run safetyc checks
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
561022ebb6 new(userspace/falco): add utility for handling hot app restarts
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
af46833ad3 update(userspace/falco): make cmdline options simpler and copyable
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
e40369648c fix(userspace/falco): solve minor compilation flaws
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
ee7fa1cb06 new(usersapce/falco): add an app option for dry-run
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-15 17:54:49 +01:00
Jason Dellaluce
f976aa8400 update(cmake): bump libs and driver to 6ca2fc1fa9a9f5482dc92468a0a6e3404ae46723
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 18:03:14 +01:00
dependabot[bot]
8b8f42667f build(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `c558fc7` to `5b6e2c0`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](c558fc7d2d...5b6e2c0241)

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

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-09 11:57:13 +01:00
Jason Dellaluce
85729f3006 update(cmake): bump libs and driver to 652d6d134d5c2b355467de5be922135e53053412
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
c41665f12c update(cmake): bump libs and driver to a513c696b68676b872c2ea59636e659960ac38c6
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
e8b776a9cb update(userspace/engine): bump engine version to 17
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
3285ead22f update(cmake): bump libs and driver to 172043999fbf3d04c2c40f98cc77957badbbd43e
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
b32c0b9283 fix(unit_tests): adapt to connect4 corner cases
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
8fe474088d update(cmake): bump libs and drivers to c2e227697b2a410eeca47fef260f575375154a58
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
09ab9db423 chore(userspace/falco): apply review suggestion
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
61a7f32982 chore(userspace/falco): apply review suggestions
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
3ab7c7d753 chore: fix typos
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
aeef99e173 update(cmake): bump libs and driver versions to f0468f32d8d730d0e70d8e103d57f97d74dd374f
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
b225549679 test(unit_test): adapt and grow tests on configure_intertesting_sets
The test now take in accoint pre/post-conditions of the actions,
usage of the -A option, and the newly-introduced base_syscall
user configuration. This also makes sure that the event selection
properly handles generic events and options/configs precedence.

Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
a7f521b4b8 chore(unit_tests): move existing test in right directory
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
2645f6640c chore(userspace/falco): rename source file using its action name
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
fb37d8f365 refactor(userspace/falco): adapt event set selection to only use ppm_sc and new engine features
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
19ffadc763 update(userspace/engine): support searching ppm_sc events in rulesets
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-09 09:39:12 +01:00
Jason Dellaluce
07980b7822 new(.github): add dependabot configuration for updating git submodules
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-03-08 19:03:09 +01:00
m.nabokikh
49cef071cf Add Deckhouse to Falco adopters
Signed-off-by: m.nabokikh <maksim.nabokikh@flant.com>
2023-03-08 12:39:07 +01:00
Melissa Kilby
0de9af9ed0 fix(app_actions): base_syscalls check for empty string
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-24 11:43:43 +01:00
Melissa Kilby
58dc60e58d cleanup(app_actions): address reviewers comments
* Plus minor adjustments to ensure correct state_event_set for all configurations
* Ensure valid check_for_rules_unsupported_events for all configurations
* Remove user input validation warning -> re-introduce in follow up PR

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-24 11:43:43 +01:00
Melissa Kilby
b6f6195725 cleanup(app_actions): include activated syscalls in LOG_DEBUG logs
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-24 11:43:43 +01:00
Melissa Kilby
d6421d4e67 new(config): add base_syscalls option to config
See https://github.com/falcosecurity/falco/issues/2373

Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Co-authored-by: Stanley Chan <pocketgamer5000@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-24 11:43:43 +01:00
Melissa Kilby
76a3c8d7ee new(app_actions): introduce base_syscalls
See https://github.com/falcosecurity/falco/issues/2373

Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-24 11:43:43 +01:00
Jason Dellaluce
7d67fbbfe7 chore(userspace/falco): apply review suggestions
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
31d06a5532 update(cmake): bump libs to e1d0fd9b043f1c7dfd91c9d030c11cfe2c062931
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
b9d03e8f2b update(cmake): bump driver and libs to c592f4f230e48f36a50c1716fd94e7e279b67513
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
5ed5c63202 refactor: adapt event set configuration changes to new libs definition
Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
01faeecee7 update(cmake): bump driver to 8a8d2389e4eea9e89efef9e3b06a70aa2a0bf5d0
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
4706cd8b4e cleanup: solve std namespace issues and remove unused imports
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
010f6c6a9e update(userspace/engine): bump fields checksum
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
1485dc5d68 refactor(userspace/falco): adapt app actions to new event definitions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
e7d76ca722 refactor(userspace/falco): use new event definitions in app state
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
6c38ecaf0e update(userspace/engine): adapt engine classes to new libsinsp event definitions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
34ea7a8245 cleanup(userspace/engine): drop filtr_evttype_resolver
Its logic was ported into libsinsp in:
3d8550e70e

Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
e54eda16f7 fix(test/plugins): solve compilation issues
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
4c72f36748 update(cmake): bump libs to 8a8d2389e4eea9e89efef9e3b06a70aa2a0bf5d0
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
3b5633a3e5 cleanup(unit_tests): remove some rebase leftovers
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
d89f4b4904 cleanup(app_actions): adjust ignored events
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
16aa36291a fix rebase
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
72439b2eed cleanup(app_actions): adjust configure_interesting_sets
* address reviewers feedback
* improve clarity around new -A and -i behavior
* additional cleanup (e.g. use generic set operations only)
* extend unit tests

Note: sinsp ppm sc API is undergoing a refactor, therefore current lookups are interim
and will subsequently be refactored as well.

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
f77f8667a1 cleanup(tests): add unit tests for configure_interesting_sets
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
30fe065446 cleanup(app_actions): configure -A w/ new default behavior
Define new -A behavior in configure_interesting_sets

* default: all syscalls in rules included, sinsp state enforcement without high volume I/O syscalls
* -A flag set: all syscalls in rules included, sinsp state enforcement and allowing high volume I/O syscalls

Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Melissa Kilby
91c185a178 cleanup(app_actions): include evttypes from rules in configure_interesting_sets
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2023-02-21 14:31:28 +01:00
Jason Dellaluce
34ed5a5fc9 chore: fix typos
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 11:09:29 +01:00
Jason Dellaluce
f34ef41e8a test(userspace/falco): add tests for atomic signal handler
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 11:09:29 +01:00
Jason Dellaluce
70c22c7d2e refactor(userspace/falco): adapt actions to new signal handler constructs
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 11:09:29 +01:00
Jason Dellaluce
eb3bf7260d refactor(userspace/falco): add an ad-hoc concurrent object for signal handlers
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 11:09:29 +01:00
Jason Dellaluce
5470a88b61 fix(userspace/falco): add missing constructors/methods on falco semaphore
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-21 11:09:29 +01:00
Luca Guerra
e19f536514 new(docs): add security audit from January 2023
Signed-off-by: Luca Guerra <luca@guerra.sh>
2023-02-21 08:23:28 +01:00
Aldo Lacuku
7a0ca9f534 new(docs): update Changelog for 0.34.1
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2023-02-20 14:45:17 +01:00
Aldo Lacuku
bdca1ce0a6 update(cmake): bumped libs to 0.10.4
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2023-02-17 16:40:44 +01:00
Jason Dellaluce
94882f3fd2 test(unit_tests): add tests for select_event_sources action
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-15 10:51:35 +01:00
Jason Dellaluce
9fd6bbf2bf update(unit_tests): link test suite to falco app cmake target
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-15 10:51:35 +01:00
Jason Dellaluce
bf5b8f5c83 new(userspace/falco): add intermediate cmake target for falco app
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-15 10:51:35 +01:00
Jason Dellaluce
a7ef45852c fix(unit_tests): invert libraries and dependencies in CMakeLists
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-15 10:51:35 +01:00
Jason Dellaluce
c45bf3eb17 chore(userspace/falco): rename falco_init into falco_run
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
149544d7ab chore(userspace/falco): fix spacing and license
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
1eb915bf2f fix(userspace/falco): solve issues with minimal build
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
3d6393ae62 fix: solve unit test issues
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
5d35dff2a7 refactor(userspace/falco/app): standalone sources for action helpers
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
799557f7f7 refactor(userspace/falco/app): make run and teardown actions consistent
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
fe859bda2d refactor(userspace/engine): turn app methods into simple functions
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
374136be18 refactor(userspace/engine): add standalone sources for app signals and options
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
623d27ef77 refactor(userspace/engine): create standalone sources for app state and run result
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
0f402d01d0 fix(userspace/falco): add missing pragma once
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Jason Dellaluce
ff68311629 fix(userspace/engine): add missing include
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 17:33:31 +01:00
Lorenzo Susini
88ac30650c fix(userspace/engine): correctly bump engine version after introduction of new fields
Signed-off-by: Lorenzo Susini <susinilorenzo1@gmail.com>
2023-02-14 13:03:06 +01:00
Jason Dellaluce
6ecc708e2b fix(unit_tests): adapt new evttype resolvers to gtest
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 12:47:07 +01:00
Jason Dellaluce
79b3f81a02 chore: fix typos
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 12:47:07 +01:00
Jason Dellaluce
2495827e0c fix(userspace/engine): correctly handle evttype indexing corner cases
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-14 12:47:07 +01:00
Federico Di Pierro
e8a62f6800 new(ci): added new workflow to automatic tag and publish new builder and tester images upon changes.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-14 09:49:05 +01:00
Federico Di Pierro
75dc8c050c new(userspace,tests): add proper support for generic events indexing.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-13 14:54:03 +01:00
Federico Di Pierro
392b66bd5a update(docs): update release.md to port Falco to use release/M.m.x branches.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-13 14:27:02 +01:00
Federico Di Pierro
cb5dddf8ec fix(release): fixed tag creation step in release doc.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-13 14:27:02 +01:00
Andrea Terzolo
98550e80b3 chore: remove a no more useful cmake file
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
0d62fb9133 ci: remove unit tests from circleCI
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
af9fbbcdc6 chore: remove no more useful cmake files
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
d7e498caf9 fix after rebase
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
0004b140b1 ci: use new unit tests where necessary
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
dff127bb65 cleanup: remove old tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
5e5869357a tests: add Configuration tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
71d7c574e0 tests: add Ruleset tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
0f83411f05 tests: add PluginRequirements tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
696a744004 tests: add WarningResolver tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
8059e28af5 tests: add MacroResolver tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
1faa35552a tests: add EvtTypeResolver tests
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
88bac44f05 test: first scaffolfing of the initial structure
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Andrea Terzolo
dca76ba93c chore: fix building with njson
Signed-off-by: Andrea Terzolo <andrea.terzolo@polito.it>
2023-02-10 11:41:24 +01:00
Aldo Lacuku
43c802d045 fix(dockerfile/no-driver): install ca-certificates
Signed-off-by: Aldo Lacuku <aldo@lacuku.eu>
2023-02-09 17:31:31 +01:00
Federico Di Pierro
7343bcf050 cleanup(uerspace/falco): do not enter dropping mode.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-09 14:16:31 +01:00
Jason Dellaluce
eaeec7c079 fix(userspace): avoid using std namespace in sources
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-08 15:30:29 +01:00
Jason Dellaluce
54f117141b update(userspace/engine): avoid relying on leaked std namespace
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
2023-02-08 15:30:29 +01:00
Federico Di Pierro
01ae266332 fix(cmake): properly check that git describe returns a real tag (semversioned).
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-07 13:49:28 +01:00
Federico Di Pierro
d5907f612c fix(cmake): fixed tag fetching fallback (that is indeed needed).
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-02-07 13:49:28 +01:00
176 changed files with 8620 additions and 6102 deletions

View File

@@ -39,7 +39,8 @@ jobs:
- run:
name: Build Falco packages 🏗️
command: |
DOCKER_BUILDKIT=1 docker build -f /tmp/source-arm64/falco/docker/builder/modern-falco-builder.Dockerfile --output type=local,dest=/tmp --build-arg CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DFALCO_ETC_DIR=/etc/falco -DBUILD_FALCO_MODERN_BPF=ON -DMODERN_BPF_SKEL_DIR=/source/skeleton-build/skel_dir -DBUILD_DRIVER=Off -DBUILD_BPF=Off" --build-arg DEST_BUILD_DIR=/build-arm64/release /tmp/source-arm64/falco
FALCO_VERSION=$(cat /tmp/source-arm64/falco/skeleton-build/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
DOCKER_BUILDKIT=1 docker build -f /tmp/source-arm64/falco/docker/builder/modern-falco-builder.Dockerfile --output type=local,dest=/tmp --build-arg CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DFALCO_ETC_DIR=/etc/falco -DBUILD_FALCO_MODERN_BPF=ON -DMODERN_BPF_SKEL_DIR=/source/skeleton-build/skel_dir -DBUILD_DRIVER=Off -DBUILD_BPF=Off -DFALCO_VERSION=${FALCO_VERSION}" --build-arg DEST_BUILD_DIR=/build-arm64/release /tmp/source-arm64/falco
- store_artifacts:
path: /tmp/packages
@@ -82,11 +83,6 @@ jobs:
command: |
cd /build-static/release
make -j6 package
- run:
name: Run unit tests
command: |
cd /build-static/release
make tests
- run:
name: Prepare artifacts
command: |
@@ -140,7 +136,8 @@ jobs:
- run:
name: Build Falco packages 🏗️
command: |
DOCKER_BUILDKIT=1 docker build -f /tmp/source/falco/docker/builder/modern-falco-builder.Dockerfile --output type=local,dest=/tmp --build-arg CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DFALCO_ETC_DIR=/etc/falco -DBUILD_FALCO_MODERN_BPF=ON -DMODERN_BPF_SKEL_DIR=/source/skeleton-build/skel_dir -DBUILD_DRIVER=Off -DBUILD_BPF=Off" --build-arg DEST_BUILD_DIR=/build/release /tmp/source/falco
FALCO_VERSION=$(cat /tmp/source/falco/skeleton-build/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
DOCKER_BUILDKIT=1 docker build -f /tmp/source/falco/docker/builder/modern-falco-builder.Dockerfile --output type=local,dest=/tmp --build-arg CMAKE_OPTIONS="-DCMAKE_BUILD_TYPE=Release -DUSE_BUNDLED_DEPS=On -DFALCO_ETC_DIR=/etc/falco -DBUILD_FALCO_MODERN_BPF=ON -DMODERN_BPF_SKEL_DIR=/source/skeleton-build/skel_dir -DBUILD_DRIVER=Off -DBUILD_BPF=Off -DFALCO_VERSION=${FALCO_VERSION}" --build-arg DEST_BUILD_DIR=/build/release /tmp/source/falco
- store_artifacts:
path: /tmp/packages
@@ -214,533 +211,6 @@ jobs:
name: Execute driver-loader integration tests
command: /tmp/ws/source/falco/test/driver-loader/run_test.sh /tmp/ws/build/release/
# Sign rpm packages
"rpm-sign":
docker:
- image: docker.io/centos:7
steps:
- attach_workspace:
at: /
- run:
name: Install rpmsign
command: |
yum update -y
yum install rpm-sign expect which -y
- run:
name: Prepare
command: |
echo "%_signature gpg" > ~/.rpmmacros
echo "%_gpg_name Falcosecurity Package Signing" >> ~/.rpmmacros
echo "%__gpg_sign_cmd %{__gpg} --force-v3-sigs --batch --no-armor --passphrase-fd 3 --no-secmem-warning -u \"%{_gpg_name}\" -sb --digest-algo sha256 %{__plaintext_filename}'" >> ~/.rpmmacros
cat > ~/sign \<<EOF
#!/usr/bin/expect -f
spawn rpmsign --addsign {*}\$argv
expect -exact "Enter pass phrase: "
send -- "\n"
expect eof
EOF
chmod +x ~/sign
echo $GPG_KEY | base64 -d | gpg --import
- run:
name: Sign rpm x86_64
command: |
cd /build/release/
~/sign *.rpm
rpm --qf %{SIGPGP:pgpsig} -qp *.rpm | grep SHA256
- run:
name: Sign rpm arm64
command: |
cd /build-arm64/release/
~/sign *.rpm
rpm --qf %{SIGPGP:pgpsig} -qp *.rpm | grep SHA256
- persist_to_workspace:
root: /
paths:
- build/release/*.rpm
- build-arm64/release/*.rpm
# Publish the dev packages
"publish-packages-dev":
docker:
- image: docker.io/centos:7
steps:
- attach_workspace:
at: /
- run:
name: Setup
command: |
yum install epel-release -y
yum update -y
yum install createrepo gpg python python-pip -y
pip install awscli==1.19.47
echo $GPG_KEY | base64 -d | gpg --import
- run:
name: Publish rpm-dev
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.rpm -r rpm-dev
- run:
name: Publish bin-dev
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin-dev -a x86_64
/source/falco/scripts/publish-bin -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.tar.gz -r bin-dev -a aarch64
- run:
name: Publish bin-static-dev
command: |
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin-dev -a x86_64
"publish-packages-deb-dev":
docker:
- image: docker.io/debian:stable
steps:
- attach_workspace:
at: /
- run:
name: Setup
command: |
apt update -y
apt-get install apt-utils bzip2 gpg python python3-pip -y
pip install awscli
echo $GPG_KEY | base64 -d | gpg --import
- run:
name: Publish deb-dev
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-deb -f /build/release/falco-${FALCO_VERSION}-x86_64.deb -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.deb -r deb-dev
"build-docker-dev":
docker:
- image: alpine:3.16
steps:
- attach_workspace:
at: /
- setup_remote_docker:
version: 20.10.12
docker_layer_caching: true
- run:
name: Install deps
command: |
apk update
apk add make bash git docker docker-cli-buildx py3-pip
pip install awscli
- run:
name: Login to registries
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
- run:
name: Build and publish no-driver-dev
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
cd /source/falco
docker buildx build --push --build-arg VERSION_BUCKET=bin-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
-t falcosecurity/falco-no-driver:x86_64-master \
-t falcosecurity/falco:x86_64-master-slim \
-t public.ecr.aws/falcosecurity/falco-no-driver:x86_64-master \
-t public.ecr.aws/falcosecurity/falco:x86_64-master-slim \
docker/no-driver
- run:
name: Build and publish falco-dev
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
cd /source/falco
docker buildx build --push --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
-t falcosecurity/falco:x86_64-master \
-t public.ecr.aws/falcosecurity/falco:x86_64-master \
docker/falco
- run:
name: Build and publish falco-driver-loader-dev
command: |
cd /source/falco
docker buildx build --push --build-arg FALCO_IMAGE_TAG=x86_64-master \
-t falcosecurity/falco-driver-loader:x86_64-master \
-t public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-master \
docker/driver-loader
"build-docker-dev-arm64":
machine:
enabled: true
image: ubuntu-2004:202101-01
docker_layer_caching: true
resource_class: arm.medium
steps:
- attach_workspace:
at: /tmp
- run:
name: Install deps
command: |
sudo apt update
sudo apt install groff less python3-pip
pip install awscli
- run:
name: Login to registries
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
- run:
name: Build and publish no-driver-dev
command: |
FALCO_VERSION=$(cat /tmp/build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
cd /tmp/source-arm64/falco
docker buildx build --push --build-arg VERSION_BUCKET=bin-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
-t falcosecurity/falco-no-driver:aarch64-master \
-t falcosecurity/falco:aarch64-master-slim \
-t public.ecr.aws/falcosecurity/falco-no-driver:aarch64-master \
-t public.ecr.aws/falcosecurity/falco:aarch64-master-slim \
docker/no-driver
- run:
name: Build and publish falco-dev
command: |
FALCO_VERSION=$(cat /tmp/build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
cd /tmp/source-arm64/falco
docker buildx build --push --build-arg VERSION_BUCKET=deb-dev --build-arg FALCO_VERSION=${FALCO_VERSION} \
-t falcosecurity/falco:aarch64-master \
-t public.ecr.aws/falcosecurity/falco:aarch64-master \
docker/falco
- run:
name: Build and publish falco-driver-loader-dev
command: |
cd /tmp/source-arm64/falco
docker buildx build --push --build-arg FALCO_IMAGE_TAG=aarch64-master \
-t falcosecurity/falco-driver-loader:aarch64-master \
-t public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-master \
docker/driver-loader
# Publish docker packages
"publish-docker-dev":
docker:
- image: cimg/base:stable
user: root
steps:
- setup_remote_docker:
version: 20.10.12
- run:
name: Install deps
command: |
sudo apt update
sudo apt install groff less python3-pip
pip install awscli
- run:
name: Login to registries
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
- run:
name: Upload no-driver-dev manifest to registries
command: |
docker manifest create falcosecurity/falco-no-driver:master \
falcosecurity/falco-no-driver:aarch64-master \
falcosecurity/falco-no-driver:x86_64-master
docker manifest push falcosecurity/falco-no-driver:master
docker manifest create falcosecurity/falco:master-slim \
falcosecurity/falco:aarch64-master-slim \
falcosecurity/falco:x86_64-master-slim
docker manifest push falcosecurity/falco:master-slim
docker manifest create public.ecr.aws/falcosecurity/falco-no-driver:master \
public.ecr.aws/falcosecurity/falco-no-driver:aarch64-master \
public.ecr.aws/falcosecurity/falco-no-driver:x86_64-master
docker manifest push public.ecr.aws/falcosecurity/falco-no-driver:master
docker manifest create public.ecr.aws/falcosecurity/falco:master-slim \
public.ecr.aws/falcosecurity/falco:aarch64-master-slim \
public.ecr.aws/falcosecurity/falco:x86_64-master-slim
docker manifest push public.ecr.aws/falcosecurity/falco:master-slim
- run:
name: Upload falco-dev manifest to registries
command: |
docker manifest create falcosecurity/falco:master \
falcosecurity/falco:aarch64-master \
falcosecurity/falco:x86_64-master
docker manifest push falcosecurity/falco:master
docker manifest create public.ecr.aws/falcosecurity/falco:master \
public.ecr.aws/falcosecurity/falco:aarch64-master \
public.ecr.aws/falcosecurity/falco:x86_64-master
docker manifest push public.ecr.aws/falcosecurity/falco:master
- run:
name: Upload falco-driver-loader-dev manifest to registries
command: |
docker manifest create falcosecurity/falco-driver-loader:master \
falcosecurity/falco-driver-loader:aarch64-master \
falcosecurity/falco-driver-loader:x86_64-master
docker manifest push falcosecurity/falco-driver-loader:master
docker manifest create public.ecr.aws/falcosecurity/falco-driver-loader:master \
public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-master \
public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-master
docker manifest push public.ecr.aws/falcosecurity/falco-driver-loader:master
# Publish the packages
"publish-packages":
docker:
- image: docker.io/centos:7
steps:
- attach_workspace:
at: /
- run:
name: Setup
command: |
yum install epel-release -y
yum update -y
yum install createrepo gpg python python-pip -y
pip install awscli==1.19.47
echo $GPG_KEY | base64 -d | gpg --import
- run:
name: Publish rpm
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-rpm -f /build/release/falco-${FALCO_VERSION}-x86_64.rpm -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.rpm -r rpm
- run:
name: Publish bin
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-bin -f /build/release/falco-${FALCO_VERSION}-x86_64.tar.gz -r bin -a x86_64
/source/falco/scripts/publish-bin -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.tar.gz -r bin -a aarch64
- run:
name: Publish bin-static
command: |
FALCO_VERSION=$(cat /build-static/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
cp -f /build-static/release/falco-${FALCO_VERSION}-x86_64.tar.gz /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz
/source/falco/scripts/publish-bin -f /build-static/release/falco-${FALCO_VERSION}-static-x86_64.tar.gz -r bin -a x86_64
"publish-packages-deb":
docker:
- image: docker.io/debian:stable
steps:
- attach_workspace:
at: /
- run:
name: Setup
command: |
apt update -y
apt-get install apt-utils bzip2 gpg python python3-pip -y
pip install awscli
echo $GPG_KEY | base64 -d | gpg --import
- run:
name: Publish deb
command: |
FALCO_VERSION=$(cat /build/release/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
/source/falco/scripts/publish-deb -f /build/release/falco-${FALCO_VERSION}-x86_64.deb -f /build-arm64/release/falco-${FALCO_VERSION}-aarch64.deb -r deb
"build-docker":
docker:
- image: alpine:3.16
steps:
- attach_workspace:
at: /
- setup_remote_docker:
version: 20.10.12
docker_layer_caching: true
- run:
name: Install deps
command: |
apk update
apk add make bash git docker docker-cli-buildx py3-pip
pip install awscli
- run:
name: Login to registries
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
- run:
name: Build and publish no-driver
command: |
cd /source/falco
docker buildx build --push --build-arg VERSION_BUCKET=bin --build-arg FALCO_VERSION=${CIRCLE_TAG} \
-t "falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}" \
-t falcosecurity/falco-no-driver:x86_64-latest \
-t "falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim" \
-t "falcosecurity/falco:x86_64-latest-slim" \
-t "public.ecr.aws/falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}" \
-t "public.ecr.aws/falcosecurity/falco-no-driver:x86_64-latest" \
-t "public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim" \
-t "public.ecr.aws/falcosecurity/falco:x86_64-latest-slim" \
docker/no-driver
- run:
name: Build and publish falco
command: |
cd /source/falco
docker buildx build --push --build-arg VERSION_BUCKET=deb --build-arg FALCO_VERSION=${CIRCLE_TAG} \
-t "falcosecurity/falco:x86_64-${CIRCLE_TAG}" \
-t "falcosecurity/falco:x86_64-latest" \
-t "public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}" \
-t "public.ecr.aws/falcosecurity/falco:x86_64-latest" \
docker/falco
- run:
name: Build and publish falco-driver-loader
command: |
cd /source/falco
docker buildx build --push --build-arg FALCO_IMAGE_TAG=x86_64-${CIRCLE_TAG} \
-t "falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}" \
-t "falcosecurity/falco-driver-loader:x86_64-latest" \
-t "public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}" \
-t "public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-latest" \
docker/driver-loader
"build-docker-arm64":
machine:
enabled: true
image: ubuntu-2004:202101-01
docker_layer_caching: true
resource_class: arm.medium
steps:
- attach_workspace:
at: /tmp
- run:
name: Install deps
command: |
sudo apt update
sudo apt install groff less python3-pip
pip install awscli
- run:
name: Login to registries
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
- run:
name: Build and publish no-driver
command: |
cd /tmp/source-arm64/falco
docker buildx build --push --build-arg VERSION_BUCKET=bin --build-arg FALCO_VERSION=${CIRCLE_TAG} \
-t falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
-t falcosecurity/falco-no-driver:aarch64-latest \
-t falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
-t "falcosecurity/falco:aarch64-latest-slim" \
-t public.ecr.aws/falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
-t "public.ecr.aws/falcosecurity/falco-no-driver:aarch64-latest" \
-t public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
-t "public.ecr.aws/falcosecurity/falco:aarch64-latest-slim" \
docker/no-driver
- run:
name: Build and publish falco
command: |
cd /tmp/source-arm64/falco
docker buildx build --push --build-arg VERSION_BUCKET=deb --build-arg FALCO_VERSION=${CIRCLE_TAG} \
-t "falcosecurity/falco:aarch64-${CIRCLE_TAG}" \
-t "falcosecurity/falco:aarch64-latest" \
-t "public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG}" \
-t "public.ecr.aws/falcosecurity/falco:aarch64-latest" \
docker/falco
- run:
name: Build and publish falco-driver-loader
command: |
cd /tmp/source-arm64/falco
docker buildx build --push --build-arg FALCO_IMAGE_TAG=aarch64-${CIRCLE_TAG} \
-t "falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG}" \
-t "falcosecurity/falco-driver-loader:aarch64-latest" \
-t "public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG}" \
-t "public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-latest" \
docker/driver-loader
# Publish docker packages
"publish-docker":
docker:
- image: cimg/base:stable
user: root
steps:
- setup_remote_docker:
version: 20.10.12
- run:
name: Install deps
command: |
sudo apt update
sudo apt install groff less python3-pip
pip install awscli
- run:
name: Login to registries
command: |
echo ${DOCKERHUB_SECRET} | docker login -u ${DOCKERHUB_USER} --password-stdin
aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws/falcosecurity
- run:
name: Upload no-driver manifest to registries
command: |
docker manifest create falcosecurity/falco-no-driver:${CIRCLE_TAG} \
falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}
docker manifest push falcosecurity/falco-no-driver:${CIRCLE_TAG}
docker manifest create falcosecurity/falco-no-driver:latest \
falcosecurity/falco-no-driver:aarch64-latest \
falcosecurity/falco-no-driver:x86_64-latest
docker manifest push falcosecurity/falco-no-driver:latest
docker manifest create falcosecurity/falco:${CIRCLE_TAG}-slim \
falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim
docker manifest push falcosecurity/falco:${CIRCLE_TAG}-slim
docker manifest create falcosecurity/falco:latest-slim \
falcosecurity/falco:aarch64-latest-slim \
falcosecurity/falco:x86_64-latest-slim
docker manifest push falcosecurity/falco:latest-slim
docker manifest create public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG} \
public.ecr.aws/falcosecurity/falco-no-driver:aarch64-${CIRCLE_TAG} \
public.ecr.aws/falcosecurity/falco-no-driver:x86_64-${CIRCLE_TAG}
docker manifest push public.ecr.aws/falcosecurity/falco-no-driver:${CIRCLE_TAG}
docker manifest create public.ecr.aws/falcosecurity/falco-no-driver:latest \
public.ecr.aws/falcosecurity/falco-no-driver:aarch64-latest \
public.ecr.aws/falcosecurity/falco-no-driver:x86_64-latest
docker manifest push public.ecr.aws/falcosecurity/falco-no-driver:latest
docker manifest create public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}-slim \
public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG}-slim \
public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}-slim
docker manifest push public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}-slim
docker manifest create public.ecr.aws/falcosecurity/falco:latest-slim \
public.ecr.aws/falcosecurity/falco:aarch64-latest-slim \
public.ecr.aws/falcosecurity/falco:x86_64-latest-slim
docker manifest push public.ecr.aws/falcosecurity/falco:latest-slim
- run:
name: Upload falco manifest to registries
command: |
docker manifest create falcosecurity/falco:${CIRCLE_TAG} \
falcosecurity/falco:aarch64-${CIRCLE_TAG} \
falcosecurity/falco:x86_64-${CIRCLE_TAG}
docker manifest push falcosecurity/falco:${CIRCLE_TAG}
docker manifest create falcosecurity/falco:latest \
falcosecurity/falco:aarch64-latest \
falcosecurity/falco:x86_64-latest
docker manifest push falcosecurity/falco:latest
docker manifest create public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG} \
public.ecr.aws/falcosecurity/falco:aarch64-${CIRCLE_TAG} \
public.ecr.aws/falcosecurity/falco:x86_64-${CIRCLE_TAG}
docker manifest push public.ecr.aws/falcosecurity/falco:${CIRCLE_TAG}
docker manifest create public.ecr.aws/falcosecurity/falco:latest \
public.ecr.aws/falcosecurity/falco:aarch64-latest \
public.ecr.aws/falcosecurity/falco:x86_64-latest
docker manifest push public.ecr.aws/falcosecurity/falco:latest
- run:
name: Upload falco-driver-loader manifest to registries
command: |
docker manifest create falcosecurity/falco-driver-loader:${CIRCLE_TAG} \
falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG} \
falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}
docker manifest push falcosecurity/falco-driver-loader:${CIRCLE_TAG}
docker manifest create falcosecurity/falco-driver-loader:latest \
falcosecurity/falco-driver-loader:aarch64-latest \
falcosecurity/falco-driver-loader:x86_64-latest
docker manifest push falcosecurity/falco-driver-loader:latest
docker manifest create public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG} \
public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-${CIRCLE_TAG} \
public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-${CIRCLE_TAG}
docker manifest push public.ecr.aws/falcosecurity/falco-driver-loader:${CIRCLE_TAG}
docker manifest create public.ecr.aws/falcosecurity/falco-driver-loader:latest \
public.ecr.aws/falcosecurity/falco-driver-loader:aarch64-latest \
public.ecr.aws/falcosecurity/falco-driver-loader:x86_64-latest
docker manifest push public.ecr.aws/falcosecurity/falco-driver-loader:latest
workflows:
version: 2.1
build_and_test:
@@ -760,166 +230,3 @@ workflows:
- "tests-driver-loader-integration":
requires:
- "build-centos7"
- "rpm-sign":
context: falco
filters:
tags:
ignore: /.*/
branches:
only: master
requires:
- "tests-integration"
- "tests-integration-arm64"
- "publish-packages-dev":
context:
- falco
- test-infra
filters:
tags:
ignore: /.*/
branches:
only: master
requires:
- "rpm-sign"
- "tests-integration-static"
- "publish-packages-deb-dev":
context:
- falco
- test-infra
filters:
tags:
ignore: /.*/
branches:
only: master
requires:
- "tests-integration"
- "tests-integration-arm64"
- "build-docker-dev":
context:
- falco
- test-infra
filters:
tags:
ignore: /.*/
branches:
only: master
requires:
- "publish-packages-dev"
- "publish-packages-deb-dev"
- "tests-driver-loader-integration"
- "build-docker-dev-arm64":
context:
- falco
- test-infra
filters:
tags:
ignore: /.*/
branches:
only: master
requires:
- "publish-packages-dev"
- "publish-packages-deb-dev"
- "tests-driver-loader-integration"
- "publish-docker-dev":
context:
- falco
- test-infra
filters:
tags:
ignore: /.*/
branches:
only: master
requires:
- "build-docker-dev"
- "build-docker-dev-arm64"
# - "quality/static-analysis" # This is temporarily disabled: https://github.com/falcosecurity/falco/issues/1526
release:
jobs:
- "build-musl":
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "build-centos7":
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "build-arm64":
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "rpm-sign":
context: falco
requires:
- "build-centos7"
- "build-arm64"
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "publish-packages":
context:
- falco
- test-infra
requires:
- "build-musl"
- "rpm-sign"
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "publish-packages-deb":
context:
- falco
- test-infra
requires:
- "build-centos7"
- "build-arm64"
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "build-docker":
context:
- falco
- test-infra
requires:
- "publish-packages"
- "publish-packages-deb"
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "build-docker-arm64":
context:
- falco
- test-infra
requires:
- "publish-packages"
- "publish-packages-deb"
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- "publish-docker":
context:
- falco
- test-infra
requires:
- "build-docker"
- "build-docker-arm64"
filters:
tags:
only: /.*/
branches:
ignore: /.*/

24
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
#
# 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.
#
version: 2
updates:
- package-ecosystem: gitsubmodule
schedule:
interval: "daily"
directory: /

View File

@@ -2,10 +2,14 @@ name: CI Build
on:
pull_request:
branches: [master]
push:
branches: [master]
workflow_dispatch:
# Checks if any concurrent jobs under the same pull request or branch are being executed
# NOTE: this will cancel every workflow that is being ran against a PR as group is just the github ref (without the workflow name)
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
build-minimal:
runs-on: ubuntu-20.04
@@ -26,7 +30,7 @@ jobs:
run: |
mkdir build-minimal
pushd build-minimal
cmake -DMINIMAL_BUILD=On -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DCMAKE_BUILD_TYPE=Release ..
cmake -DMINIMAL_BUILD=On -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DCMAKE_BUILD_TYPE=Release -DBUILD_FALCO_UNIT_TESTS=On ..
popd
- name: Build
@@ -38,7 +42,7 @@ jobs:
- name: Run unit tests
run: |
pushd build-minimal
make tests
sudo ./unit_tests/falco_unit_tests
popd
build-ubuntu-focal:
@@ -60,7 +64,7 @@ jobs:
run: |
mkdir build
pushd build
cmake -DBUILD_BPF=On ..
cmake -DBUILD_BPF=On -DCMAKE_BUILD_TYPE=Release -DBUILD_FALCO_UNIT_TESTS=On ..
popd
- name: Build
@@ -72,7 +76,7 @@ jobs:
- name: Run unit tests
run: |
pushd build
make tests
sudo ./unit_tests/falco_unit_tests
popd
build-ubuntu-focal-debug:
@@ -94,7 +98,7 @@ jobs:
run: |
mkdir build
pushd build
cmake -DCMAKE_BUILD_TYPE=debug -DBUILD_BPF=On ..
cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_BPF=On -DBUILD_FALCO_UNIT_TESTS=On ..
popd
- name: Build
@@ -106,5 +110,5 @@ jobs:
- name: Run unit tests
run: |
pushd build
make tests
sudo ./unit_tests/falco_unit_tests
popd

64
.github/workflows/images_bumper.yml vendored Normal file
View File

@@ -0,0 +1,64 @@
name: Builder and Tester Images Bumper
on:
push:
branches: [master]
jobs:
paths-filter:
runs-on: ubuntu-latest
outputs:
builder_changed: ${{ steps.filter.outputs.builder }}
tester_changed: ${{ steps.filter.outputs.tester }}
steps:
- uses: actions/checkout@v2
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
builder:
- 'docker/builder/**'
tester:
- 'docker/tester/**'
update-builder-tester-images:
runs-on: ubuntu-22.04
needs: paths-filter
if: needs.paths-filter.outputs.builder_changed == 'true' || needs.paths-filter.outputs.tester_changed == 'true'
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: 'amd64,arm64'
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push new builder image
if: needs.paths-filter.outputs.builder_changed == 'true'
uses: docker/build-push-action@v3
with:
context: docker/builder
platforms: linux/amd64,linux/arm64
tags: latest
push: true
- name: Build and push new tester image
if: needs.paths-filter.outputs.tester_changed == 'true'
uses: docker/build-push-action@v3
with:
context: docker/tester
platforms: linux/amd64,linux/arm64
tags: latest
push: true

93
.github/workflows/master.yaml vendored Normal file
View File

@@ -0,0 +1,93 @@
name: Dev Packages and Docker images
on:
push:
branches: [master]
# Checks if any concurrent jobs is running for master CI and eventually cancel it
concurrency:
group: ci-master
cancel-in-progress: true
jobs:
# We need to use an ubuntu-latest to fetch Falco version because
# Falco version is computed by some cmake scripts that do git sorceries
# to get the current version.
# But centos7 jobs have a git version too old and actions/checkout does not
# fully clone the repo, but uses http rest api instead.
fetch-version:
runs-on: ubuntu-latest
# Map the job outputs to step outputs
outputs:
version: ${{ steps.store_version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install build dependencies
run: |
sudo apt update
sudo apt install -y cmake build-essential
- name: Configure project
run: |
mkdir build && cd build
cmake -DUSE_BUNDLED_DEPS=On ..
- name: Load and store Falco version output
id: store_version
run: |
FALCO_VERSION=$(cat build/userspace/falco/config_falco.h | grep 'FALCO_VERSION ' | cut -d' ' -f3 | sed -e 's/^"//' -e 's/"$//')
echo "version=${FALCO_VERSION}" >> $GITHUB_OUTPUT
build-dev-packages:
needs: [fetch-version]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: x86_64
version: ${{ needs.fetch-version.outputs.version }}
secrets: inherit
build-dev-packages-arm64:
needs: [fetch-version]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: aarch64
version: ${{ needs.fetch-version.outputs.version }}
secrets: inherit
publish-dev-packages:
needs: [fetch-version, build-dev-packages, build-dev-packages-arm64]
uses: ./.github/workflows/reusable_publish_packages.yaml
with:
bucket_suffix: '-dev'
version: ${{ needs.fetch-version.outputs.version }}
secrets: inherit
build-dev-docker:
needs: [fetch-version, publish-dev-packages]
uses: ./.github/workflows/reusable_build_docker.yaml
with:
arch: x86_64
bucket_suffix: '-dev'
version: ${{ needs.fetch-version.outputs.version }}
tag: master
secrets: inherit
build-dev-docker-arm64:
needs: [fetch-version, publish-dev-packages]
uses: ./.github/workflows/reusable_build_docker.yaml
with:
arch: aarch64
bucket_suffix: '-dev'
version: ${{ needs.fetch-version.outputs.version }}
tag: master
secrets: inherit
publish-dev-docker:
needs: [fetch-version, build-dev-docker, build-dev-docker-arm64]
uses: ./.github/workflows/reusable_publish_docker.yaml
with:
tag: master
secrets: inherit

105
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,105 @@
name: Release Packages and Docker images
on:
release:
types: [published]
# Checks if any concurrent jobs is running for release CI and eventually cancel it.
concurrency:
group: ci-release
cancel-in-progress: true
jobs:
release-settings:
runs-on: ubuntu-latest
outputs:
is_latest: ${{ steps.get_settings.outputs.is_latest }}
bucket_suffix: ${{ steps.get_settings.outputs.bucket_suffix }}
steps:
- name: Get latest release
uses: rez0n/actions-github-release@v2.0
id: latest_release
env:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ github.repository }}
type: "stable"
- name: Get settings for this release
id: get_settings
shell: python
run: |
import os
import re
import sys
semver_no_meta = '''^(?P<major>0|[1-9]\d*)\.(?P<minor>0|[1-9]\d*)\.(?P<patch>0|[1-9]\d*)(?:-(?P<prerelease>(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?$'''
tag_name = '${{ github.event.release.tag_name }}'
is_valid_version = re.match(semver_no_meta, tag_name) is not None
if not is_valid_version:
print(f'Release version {tag_name} is not a valid full or pre-release. See RELEASE.md for more information.')
sys.exit(1)
is_prerelease = '-' in tag_name
# Safeguard: you need to both set "latest" in GH and not have suffixes to overwrite latest
is_latest = '${{ steps.latest_release.outputs.release }}' == tag_name and not is_prerelease
bucket_suffix = '-dev' if is_prerelease else ''
with open(os.environ['GITHUB_OUTPUT'], 'a') as ofp:
print(f'is_latest={is_latest}'.lower(), file=ofp)
print(f'bucket_suffix={bucket_suffix}', file=ofp)
build-packages:
needs: [release-settings]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: x86_64
version: ${{ github.event.release.tag_name }}
secrets: inherit
build-packages-arm64:
needs: [release-settings]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: aarch64
version: ${{ github.event.release.tag_name }}
secrets: inherit
publish-packages:
needs: [release-settings, build-packages, build-packages-arm64]
uses: ./.github/workflows/reusable_publish_packages.yaml
with:
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]
uses: ./.github/workflows/reusable_build_docker.yaml
with:
arch: x86_64
bucket_suffix: ${{ needs.release-settings.outputs.bucket_suffix }}
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
with:
arch: aarch64
bucket_suffix: ${{ needs.release-settings.outputs.bucket_suffix }}
version: ${{ github.event.release.tag_name }}
tag: ${{ github.event.release.tag_name }}
secrets: inherit
publish-docker:
needs: [release-settings, build-docker, build-docker-arm64]
uses: ./.github/workflows/reusable_publish_docker.yaml
secrets: inherit
with:
is_latest: ${{ needs.release-settings.outputs.is_latest == 'true' }}
tag: ${{ github.event.release.tag_name }}
sign: true

View File

@@ -0,0 +1,73 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
arch:
description: x86_64 or aarch64
required: true
type: string
bucket_suffix:
description: bucket suffix for packages
required: false
default: ''
type: string
version:
description: The Falco version to use when building images
required: true
type: string
tag:
description: The tag to use (e.g. "master" or "0.35.0")
required: true
type: string
# 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,
# and this "build" workflow is actually only building images.
jobs:
build-docker:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
env:
TARGETARCH: ${{ (inputs.arch == 'aarch64' && 'arm64') || 'amd64' }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- 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 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 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-driver-loader image
run: |
cd ${{ github.workspace }}/docker/driver-loader/
docker build -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg FALCO_IMAGE_TAG=${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-driver-loader-${{ inputs.arch }}.tar
- name: Upload images tarballs
uses: actions/upload-artifact@v3
with:
name: falco-images
path: /tmp/falco-*.tar

View File

@@ -0,0 +1,160 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
arch:
description: x86_64 or aarch64
required: true
type: string
version:
description: The Falco version to use when building packages
required: true
type: string
jobs:
build-modern-bpf-skeleton:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || '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
- name: Checkout
uses: actions/checkout@v3
- name: Build modern BPF skeleton
run: |
mkdir skeleton-build && cd skeleton-build
cmake -DUSE_BUNDLED_DEPS=ON -DBUILD_FALCO_MODERN_BPF=ON -DCREATE_TEST_TARGETS=Off -DFALCO_VERSION=${{ inputs.version }} ..
make ProbeSkeleton -j6
- name: Upload skeleton
uses: actions/upload-artifact@v3
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: skeleton-build/skel_dir/bpf_probe.skel.h
build-packages:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || '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: Install build dependencies
run: |
yum -y install centos-release-scl
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
- name: Checkout
uses: actions/checkout@v3
- name: Download skeleton
uses: actions/download-artifact@v3
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: /tmp
- name: Install updated cmake
run: |
curl -L -o /tmp/cmake.tar.gz https://github.com/Kitware/CMake/releases/download/v3.22.5/cmake-3.22.5-linux-$(uname -m).tar.gz
gzip -d /tmp/cmake.tar.gz
tar -xpf /tmp/cmake.tar --directory=/tmp
cp -R /tmp/cmake-3.22.5-linux-$(uname -m)/* /usr
rm -rf /tmp/cmake-3.22.5-linux-$(uname -m)
- name: Prepare project
run: |
mkdir build && cd build
source /opt/rh/devtoolset-9/enable
cmake \
-DCMAKE_BUILD_TYPE=Release \
-DUSE_BUNDLED_DEPS=On \
-DFALCO_ETC_DIR=/etc/falco \
-DBUILD_FALCO_MODERN_BPF=ON \
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DFALCO_VERSION=${{ inputs.version }} \
..
- name: Build project
run: |
cd build
source /opt/rh/devtoolset-9/enable
make falco -j6
- name: Build packages
run: |
cd build
source /opt/rh/devtoolset-9/enable
make package
- name: Upload Falco tar.gz package
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.tar.gz
path: |
${{ github.workspace }}/build/falco-*.tar.gz
- name: Upload Falco deb package
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.deb
path: |
${{ github.workspace }}/build/falco-*.deb
- name: Upload Falco rpm package
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.rpm
path: |
${{ github.workspace }}/build/falco-*.rpm
build-musl-package:
# x86_64 only for now
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
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Prepare project
run: |
mkdir build && cd build
cmake -DCPACK_GENERATOR=TGZ -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DCMAKE_BUILD_TYPE=Release -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 }}
- name: Build project
run: |
cd build
make -j6 all
- name: Build packages
run: |
cd build
make -j6 package
- name: Rename static package
run: |
cd build
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@v3
with:
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
path: |
${{ github.workspace }}/build/falco-${{ inputs.version }}-static-x86_64.tar.gz

View File

@@ -0,0 +1,144 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
tag:
description: The tag to push
required: true
type: string
is_latest:
description: Update the latest tag with the new image
required: false
type: boolean
default: false
sign:
description: Add signature with cosign
required: false
type: boolean
default: false
permissions:
id-token: write
contents: read
jobs:
publish-docker:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Download images tarballs
uses: actions/download-artifact@v3
with:
name: falco-images
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@v2
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
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
- name: Setup Crane
uses: imjasonh/setup-crane@v0.3
with:
version: v0.15.1
# 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:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
- name: Create no-driver manifest on Docker Hub
uses: Noelware/docker-manifest-action@0.3.1
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: 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
uses: Noelware/docker-manifest-action@0.3.1
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-driver-loader manifest on Docker Hub
uses: Noelware/docker-manifest-action@0.3.1
with:
inputs: docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
push: true
- name: Get Digests for images
id: digests
run: |
echo "falco-no-driver=$(crane digest docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco=$(crane digest docker.io/falcosecurity/falco:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-driver-loader=$(crane digest docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }})" >> $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:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }}
crane copy public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim
- 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:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
crane tag public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
- name: Setup Cosign
if: inputs.sign
uses: sigstore/cosign-installer@main
with:
cosign-release: v2.0.2
- name: Sign images with cosign
if: inputs.sign
env:
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@${{ steps.digests.outputs.falco }}
cosign sign docker.io/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign public.ecr.aws/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
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 }}

View File

@@ -0,0 +1,150 @@
# This is a reusable workflow used by master and release CI
on:
workflow_call:
inputs:
version:
description: The Falco version to use when publishing packages
required: true
type: string
bucket_suffix:
description: bucket suffix for packages
required: false
default: ''
type: string
permissions:
id-token: write
contents: read
env:
AWS_S3_REGION: eu-west-1
AWS_CLOUDFRONT_DIST_ID: E1CQNPFWRXLGQD
jobs:
publish-packages:
runs-on: ubuntu-latest
container: docker.io/centos:7
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: |
yum install epel-release -y
yum update -y
yum install rpm-sign expect which createrepo gpg python python-pip -y
pip install awscli==1.19.47
# Configure AWS role; see https://github.com/falcosecurity/test-infra/pull/1102
# Note: master CI can only push dev packages as we have 2 different roles for master and release.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco${{ inputs.bucket_suffix }}-s3"
aws-region: ${{ env.AWS_S3_REGION }}
- name: Download RPM x86_64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-x86_64.rpm
path: /tmp/falco-rpm
- name: Download RPM aarch64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-aarch64.rpm
path: /tmp/falco-rpm
- name: Download binary x86_64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-x86_64.tar.gz
path: /tmp/falco-bin
- name: Download binary aarch64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-aarch64.tar.gz
path: /tmp/falco-bin
- name: Download static binary x86_64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
path: /tmp/falco-bin-static
- name: Import gpg key
env:
GPG_KEY: ${{ secrets.GPG_KEY }}
run: printenv GPG_KEY | gpg --import -
- name: Sign rpms
run: |
echo "%_signature gpg" > ~/.rpmmacros
echo "%_gpg_name Falcosecurity Package Signing" >> ~/.rpmmacros
echo "%__gpg_sign_cmd %{__gpg} --force-v3-sigs --batch --no-armor --passphrase-fd 3 --no-secmem-warning -u \"%{_gpg_name}\" -sb --digest-algo sha256 %{__plaintext_filename}'" >> ~/.rpmmacros
cat > ~/sign <<EOF
#!/usr/bin/expect -f
spawn rpmsign --addsign {*}\$argv
expect -exact "Enter pass phrase: "
send -- "\n"
expect eof
EOF
chmod +x ~/sign
~/sign /tmp/falco-rpm/falco-*.rpm
rpm --qf %{SIGPGP:pgpsig} -qp /tmp/falco-rpm/falco-*.rpm | grep SHA256
- name: Publish rpm
run: |
./scripts/publish-rpm -f /tmp/falco-rpm/falco-${{ inputs.version }}-x86_64.rpm -f /tmp/falco-rpm/falco-${{ inputs.version }}-aarch64.rpm -r rpm${{ inputs.bucket_suffix }}
- name: Publish bin
run: |
./scripts/publish-bin -f /tmp/falco-bin/falco-${{ inputs.version }}-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
./scripts/publish-bin -f /tmp/falco-bin/falco-${{ inputs.version }}-aarch64.tar.gz -r bin${{ inputs.bucket_suffix }} -a aarch64
- name: Publish static
run: |
./scripts/publish-bin -f /tmp/falco-bin-static/falco-${{ inputs.version }}-static-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
publish-packages-deb:
runs-on: ubuntu-latest
container: docker.io/debian:stable
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: |
apt update -y
apt-get install apt-utils bzip2 gpg python python3-pip -y
pip install awscli
# Configure AWS role; see https://github.com/falcosecurity/test-infra/pull/1102
# Note: master CI can only push dev packages as we have 2 different roles for master and release.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco${{ inputs.bucket_suffix }}-s3"
aws-region: ${{ env.AWS_S3_REGION }}
- name: Download deb x86_64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-x86_64.deb
path: /tmp/falco-deb
- name: Download deb aarch64
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-aarch64.deb
path: /tmp/falco-deb
- name: Import gpg key
env:
GPG_KEY: ${{ secrets.GPG_KEY }}
run: printenv GPG_KEY | gpg --import -
- name: Publish deb
run: |
./scripts/publish-deb -f /tmp/falco-deb/falco-${{ inputs.version }}-x86_64.deb -f /tmp/falco-deb/falco-${{ inputs.version }}-aarch64.deb -r deb${{ inputs.bucket_suffix }}

View File

@@ -24,6 +24,8 @@ This is a list of production adopters of Falco (in alphabetical order):
* [Coveo](https://www.coveo.com/) - Coveo stitches together content and data, learning from every interaction, to tailor every experience using AI to drive growth, satisfy customers and develop employee proficiency. All Falco events are centralized in our SIEM for analysis. Understanding what is running on production servers, and the context around why things are running is even more tricky now that we have further abstractions with containers and orchestration systems. Falco is giving us a good visibility inside containers and complement other Host and Network Intrusion Detection Systems. In a near future, we expect to deploy serverless functions to take action when Falco identifies patterns worth taking action for.
* [Deckhouse](https://deckhouse.io/) - Deckhouse Platform presents to you the opportunity to create homogeneous Kubernetes clusters anywhere and handles comprehensive, automagical management for them. It supplies all the add-ons you need for auto-scaling, observability, security, and service mesh. Falco is used as a part of the [runtime-audit-engine](https://deckhouse.io/documentation/latest/modules/650-runtime-audit-engine/) module to provide threats detection and enforce security compliance out of the box. By pairing with [shell-operator](https://github.com/flant/shell-operator) Falco can be configured by Kubernetes Custom Resources.
* [Fairwinds](https://fairwinds.com/) - [Fairwinds Insights](https://fairwinds.com/insights), Kubernetes governance software, integrates Falco to offer a single pane of glass view into potential security incidents. Insights adds out-of-the-box integrations and rules filter to reduce alert fatigue and improve security response. The platform adds security prevention, detection, and response capabilities to your existing Kubernetes infrastructure. Security and DevOps teams benefit from a centralized view of container security vulnerability scanning and runtime container security.
* [Frame.io](https://frame.io/) - Frame.io is a cloud-based (SaaS) video review and collaboration platform that enables users to securely upload source media, work-in-progress edits, dailies, and more into private workspaces where they can invite their team and clients to collaborate on projects. Understanding what is running on production servers, and the context around why things are running is even more tricky now that we have further abstractions like Docker and Kubernetes. To get this needed visibility into our system, we rely on Falco. Falco's ability to collect raw system calls such as open, connect, exec, along with their arguments offer key insights on what is happening on the production system and became the foundation of our intrusion detection and alerting system.

View File

@@ -1,5 +1,17 @@
# Change Log
## v0.34.1
Released on 2023-02-20
### Minor Changes
* fix(userspace/engine): correctly bump FALCO_ENGINE_VERSION after introduction of new fields [[#2418](https://github.com/falcosecurity/falco/pull/2418)] - [@loresuso](https://github.com/loresuso/)
### Non user-facing changes
* fix(dockerfile/no-driver): install ca-certificates [[#2412](https://github.com/falcosecurity/falco/pull/2412)] - [@alacuku](https://github.com/alacuku)
## v0.34.0
Released on 2023-02-07

View File

@@ -18,6 +18,7 @@ option(USE_BUNDLED_DEPS "Bundle hard to find dependencies into the Falco binary"
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(MUSL_OPTIMIZED_BUILD "Enable if you want a musl optimized build" OFF)
option(BUILD_FALCO_UNIT_TESTS "Build falco unit tests" OFF)
# 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)
@@ -43,6 +44,8 @@ if (${EP_UPDATE_DISCONNECTED})
PROPERTY EP_UPDATE_DISCONNECTED TRUE)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
# Elapsed time
# set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") # TODO(fntlnz, leodido): add a flag to enable this
@@ -107,7 +110,7 @@ if(BUILD_WARNINGS_AS_ERRORS)
endif()
set(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS "--std=c++0x ${CMAKE_COMMON_FLAGS} -Wno-class-memaccess")
set(CMAKE_CXX_FLAGS "-std=c++17 ${CMAKE_COMMON_FLAGS} -Wno-class-memaccess")
set(CMAKE_C_FLAGS_DEBUG "${FALCO_EXTRA_DEBUG_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${FALCO_EXTRA_DEBUG_FLAGS}")
@@ -148,16 +151,7 @@ include(falcosecurity-libs)
include(jq)
# nlohmann-json
set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson")
message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'")
set(NJSON_INCLUDE "${NJSON_SRC}/single_include")
ExternalProject_Add(
njson
URL "https://github.com/nlohmann/json/archive/v3.3.0.tar.gz"
URL_HASH "SHA256=2fd1d207b4669a7843296c41d3b6ac5b23d00dec48dba507ba051d14564aa801"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
include(njson)
# b64
include(b64)
@@ -222,7 +216,6 @@ set(FALCO_BIN_DIR bin)
add_subdirectory(scripts)
add_subdirectory(userspace/engine)
add_subdirectory(userspace/falco)
add_subdirectory(tests)
if(NOT MUSL_OPTIMIZED_BUILD)
include(plugins)
@@ -232,3 +225,7 @@ include(falcoctl)
# Packages configuration
include(CPackConfig)
if(BUILD_FALCO_UNIT_TESTS)
add_subdirectory(unit_tests)
endif()

142
README.md
View File

@@ -5,12 +5,8 @@
[![Build Status](https://img.shields.io/circleci/build/github/falcosecurity/falco/master?style=for-the-badge)](https://circleci.com/gh/falcosecurity/falco) [![CII Best Practices Summary](https://img.shields.io/cii/summary/2317?label=CCI%20Best%20Practices&style=for-the-badge)](https://bestpractices.coreinfrastructure.org/projects/2317) [![GitHub](https://img.shields.io/github/license/falcosecurity/falco?style=for-the-badge)](COPYING) [![Latest](https://img.shields.io/github/v/release/falcosecurity/falco?style=for-the-badge)](https://github.com/falcosecurity/falco/releases/latest) ![Architectures](https://img.shields.io/badge/ARCHS-x86__64%7Caarch64-blueviolet?style=for-the-badge)
Want to talk? Join us on the [#falco](https://kubernetes.slack.com/messages/falco) channel in the [Kubernetes Slack](https://slack.k8s.io).
## Latest releases
Read the [change log](CHANGELOG.md).
<!--
Badges in the following table are constructed by using the
https://img.shields.io/badge/dynamic/xml endpoint.
@@ -49,116 +45,90 @@ Notes:
-->
| | development | stable |
|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| rpm-x86_64 | [![rpm-dev](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Frpm-dev%2Ffalco-%26delimiter=aarch64)][1] | [![rpm](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Frpm%2Ffalco-%26delimiter=aarch64)][2] |
| deb-x86_64 | [![deb-dev](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fdeb-dev%2Fstable%2Ffalco-%26delimiter=aarch64)][3] | [![deb](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fdeb%2Fstable%2Ffalco-%26delimiter=aarch64)][4] |
| binary-x86_64 | [![bin-dev](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%20%22falco-%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fbin-dev%2Fx86_64%2Ffalco-)][5] | [![bin](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%20%22falco-%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fbin%2Fx86_64%2Ffalco-)][6] |
| rpm-aarch64 | [![rpm-dev](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Frpm-dev%2Ffalco-%26delimiter=x86_64)][1] | [![rpm](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Frpm%2Ffalco-%26delimiter=x86_64)][2] |
| deb-aarch64 | [![deb-dev](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fdeb-dev%2Fstable%2Ffalco-%26delimiter=x86_64)][3] | [![deb](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fdeb%2Fstable%2Ffalco-%26delimiter=x86_64)][4] |
| binary-aarch64 | [![bin-dev](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%20%22falco-%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fbin-dev%2Faarch64%2Ffalco-)][7] | [![bin](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%20%22falco-%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fbin%2Faarch64%2Ffalco-)][8] |
| | stable |
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| rpm-x86_64 | [![rpm](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Frpm%2Ffalco-%26delimiter=aarch64)][2] |
| deb-x86_64 | [![deb](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fdeb%2Fstable%2Ffalco-%26delimiter=aarch64)][4] |
| binary-x86_64 | [![bin](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%20%22falco-%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fbin%2Fx86_64%2Ffalco-)][6] |
| rpm-aarch64 | [![rpm](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Frpm%2Ffalco-%26delimiter=x86_64)][2] |
| deb-aarch64 | [![deb](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-before%28substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%22falco-%22%29%2C%22.asc%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fdeb%2Fstable%2Ffalco-%26delimiter=x86_64)][4] |
| binary-aarch64 | [![bin](https://img.shields.io/badge/dynamic/xml?color=%2300aec7&style=flat-square&label=Falco&query=substring-after%28%28%2F%2A%5Bname%28%29%3D%27ListBucketResult%27%5D%2F%2A%5Bname%28%29%3D%27Contents%27%5D%29%5Blast%28%29%5D%2F%2A%5Bname%28%29%3D%27Key%27%5D%2C%20%22falco-%22%29&url=https%3A%2F%2Ffalco-distribution.s3-eu-west-1.amazonaws.com%2F%3Fprefix%3Dpackages%2Fbin%2Faarch64%2Ffalco-)][8] |
---
For comprehensive information on the latest updates and changes to the project, please refer to the [change log](CHANGELOG.md). Additionally, we have documented the [release process](RELEASE.md) for delivering new versions of Falco.
The Falco Project, originally created by [Sysdig](https://sysdig.com), is an incubating [CNCF](https://cncf.io) open source cloud native runtime security tool.
Falco makes it easy to consume kernel events, and enrich those events with information from Kubernetes and the rest of the cloud native stack.
Falco can also be extended to other data sources by using plugins.
Falco has a rich set of security rules specifically built for Kubernetes, Linux, and cloud-native.
If a rule is violated in a system, Falco will send an alert notifying the user of the violation and its severity.
## Introduction to Falco
## What can Falco detect?
[Falco](https://falco.org/), originally created by [Sysdig](https://sysdig.com), is an incubating project under the [CNCF](https://cncf.io).
Falco can detect and alert on any behavior that involves making Linux system calls.
Falco alerts can be triggered by the use of specific system calls, their arguments, and by properties of the calling process.
For example, Falco can easily detect incidents including but not limited to:
Falco is a cloud native runtime security tool for Linux operating systems. It is designed to detect and alert on abnormal behavior and potential security threats in real-time.
- A shell is running inside a container or pod in Kubernetes.
- A container is running in privileged mode, or is mounting a sensitive path, such as `/proc`, from the host.
- A server process is spawning a child process of an unexpected type.
- Unexpected read of a sensitive file, such as `/etc/shadow`.
- A non-device file is written to `/dev`.
- A standard system binary, such as `ls`, is making an outbound network connection.
- A privileged pod is started in a Kubernetes cluster.
At its core, Falco is a kernel event monitoring and detection agent that captures events, such as syscalls, based on custom rules. Falco can enhance these events by integrating metadata from the container runtime and Kubernetes. The collected events can be analyzed off-host in SIEM or data lake systems.
The official Falco rules are maintained and released in [falcosecurity/rules](https://github.com/falcosecurity/rules/). That repository also contains the Falco rules inventory [document](https://github.com/falcosecurity/rules/blob/main/rules_inventory/rules_overview.md), which provides additional details around the default rules Falco ships with.
## Installing Falco
If you would like to run Falco in **production** please adhere to the [official installation guide](https://falco.org/docs/getting-started/installation/).
### Kubernetes
| Tool | Link | Note |
|----------|--------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| Helm | [Chart Repository](https://github.com/falcosecurity/charts/tree/master/falco#introduction) | The Falco community offers regular helm chart releases. |
| Minikube | [Tutorial](https://falco.org/docs/getting-started/third-party/#minikube) | The Falco driver has been baked into minikube for easy deployment. |
| Kind | [Tutorial](https://falco.org/docs/getting-started/third-party/#kind) | Running Falco with kind requires a driver on the host system. |
| GKE | [Tutorial](https://falco.org/docs/getting-started/third-party/#gke) | We suggest using the eBPF driver for running Falco on GKE. |
## Developing
Falco is designed to be extensible such that it can be built into cloud-native applications and infrastructure.
Falco has a [gRPC](https://falco.org/docs/grpc/) endpoint and an API defined in [protobuf](https://github.com/falcosecurity/falco/blob/master/userspace/falco/outputs.proto).
The Falco Project supports various SDKs for this endpoint.
### SDKs
| Language | Repository |
|----------|---------------------------------------------------------|
| Go | [client-go](https://github.com/falcosecurity/client-go) |
## Plugins
Falco comes with a [plugin framework](https://falco.org/docs/plugins/) that extends it to potentially any cloud detection scenario. Plugins are shared libraries that conform to a documented API and allow for:
- Adding new event sources that can be used in rules;
- Adding the ability to define new fields and extract information from events.
The Falco Project maintains [various plugins](https://github.com/falcosecurity/plugins) and provides SDKs for plugin development.
For detailed technical information and insights into the cyber threats that Falco can detect, visit the official [Falco](https://falco.org/) website.
### SDKs
## Falco Repo: Powering the Core of The Falco Project
| Language | Repository |
|----------|-------------------------------------------------------------------------------|
| Go | [falcosecurity/plugin-sdk-go](https://github.com/falcosecurity/plugin-sdk-go) |
This is the main Falco repository which contains the source code for building the Falco binary. By utilizing its [libraries](https://github.com/falcosecurity/libs) and the [falco.yaml](falco.yaml) configuration file, this repository forms the foundation of Falco's functionality. The Falco repository is closely interconnected with the following *core* repositories:
- [falcosecurity/libs](https://github.com/falcosecurity/libs): Falco's libraries are key to its fundamental operations, making up the greater portion of the source code of the Falco binary and providing essential features such as kernel drivers.
- [falcosecurity/rules](https://github.com/falcosecurity/rules): Contains the official ruleset for Falco, providing pre-defined detection rules for various security threats and abnormal behaviors.
- [falcosecurity/plugins](https://github.com/falcosecurity/plugins/): Falco plugins facilitate integration with external services, expand Falco's capabilities beyond syscalls and container events, and are designed to evolve with specialized functionality in future releases.
- [falcosecurity/falcoctl](https://github.com/falcosecurity/falcoctl): Command-line utility for managing and interacting with Falco.
For more information, visit the official hub of The Falco Project: [falcosecurity/evolution](https://github.com/falcosecurity/evolution). It provides valuable insights and information about the project's repositories.
## Getting Started with Falco
Carefully review and follow the [official guide and documentation](https://falco.org/docs/getting-started/).
Considerations and guidance for Falco adopters:
1. Understand dependencies: Assess the environment where you'll run Falco and consider kernel versions and architectures.
2. Define threat detection objectives: Clearly identify the threats you want to detect and evaluate Falco's strengths and limitations.
3. Consider performance and cost: Assess compute performance overhead and align with system administrators or SREs. Budget accordingly.
4. Choose build and customization approach: Decide between the open source Falco build or creating a custom build pipeline. Customize the build and deployment process as necessary, including incorporating unique tests or approaches, to ensure a resilient deployment with fast deployment cycles.
5. Integrate with output destinations: Integrate Falco with SIEM, data lake systems, or other preferred output destinations to establish a robust foundation for comprehensive data analysis and enable effective incident response workflows.
## Documentation
## How to Contribute
Please refer to the [contributing guide](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) and the [code of conduct](https://github.com/falcosecurity/evolution/CODE_OF_CONDUCT.md) for more information on how to contribute.
The [Official Documentation](https://falco.org/docs/) is the best resource to learn about Falco.
## Join the Community
To get involved with The Falco Project please visit [the community repository](https://github.com/falcosecurity/community) to find more.
To get involved with the Falco Project please visit the [community repository](https://github.com/falcosecurity/community) to find more information and ways to get involved.
If you have any questions about Falco or contributing, do not hesitate to file an issue or contact the Falco maintainers and community members for assistance.
How to reach out?
- Join the [#falco](https://kubernetes.slack.com/messages/falco) channel on the [Kubernetes Slack](https://slack.k8s.io)
- [Join the Falco mailing list](https://lists.cncf.io/g/cncf-falco-dev)
- [Read the Falco documentation](https://falco.org/docs/)
- Join the [#falco](https://kubernetes.slack.com/messages/falco) channel on the [Kubernetes Slack](https://slack.k8s.io).
- Join the [Falco mailing list](https://lists.cncf.io/g/cncf-falco-dev).
- File an [issue](https://github.com/falcosecurity/falco/issues) or make feature requests.
## How to contribute
## Commitment to Falco's Own Security
See the [contributing guide](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) and the [code of conduct](https://github.com/falcosecurity/evolution/CODE_OF_CONDUCT.md).
## Security Audit
Full reports of various security audits can be found [here](./audits/).
A third party security audit was performed by Cure53, you can see the full report [here](./audits/SECURITY_AUDIT_2019_07.pdf).
In addition, you can refer to the [falco security](https://github.com/falcosecurity/falco/security) and [libs security](https://github.com/falcosecurity/libs/security) sections for detailed updates on security advisories and policies.
## Reporting security vulnerabilities
To report security vulnerabilities, please follow the community process outlined in the documentation found [here](https://github.com/falcosecurity/.github/blob/main/SECURITY.md).
## What's next for Falco?
Stay updated with Falco's evolving capabilities by exploring the [Falco Roadmap](https://github.com/orgs/falcosecurity/projects/5), which provides insights into the features currently under development and planned for future releases.
Please report security vulnerabilities following the community process documented [here](https://github.com/falcosecurity/.github/blob/main/SECURITY.md).
## License
Falco is licensed to you under the [Apache 2.0](./COPYING) open source license.
## Project Evolution
The [falcosecurity/evolution](https://github.com/falcosecurity/evolution) repository is the official space for the community to work together, discuss ideas, and document processes. It is also a place to make decisions. Check it out to find more helpful resources.
## Resources
- [Governance](https://github.com/falcosecurity/evolution/blob/main/GOVERNANCE.md)

View File

@@ -5,18 +5,22 @@
This document provides the process to create a new Falco release. In addition, it provides information about the versioning of the Falco components. At a high level each Falco release consists of the following main components:
- Falco binary (userspace)
- Falco kernel driver object files (kernel space)
- Falco binary (userspace), includes `modern_bpf` driver object code (kernel space) starting with Falco 0.34.x releases
- Falco kernel driver object files, separate artifacts for `kmod` and `bpf` drivers, not applicable for `modern_bpf` driver (kernel space)
- Option 1: Kernel module (`.ko` files)
- Option 2: eBPF (`.o` files)
- Falco config and primary rules `.yaml` files (userspace)
- Falco config and rules `.yaml` files (userspace)
- Falco plugins (userspace - optional)
One nice trait about releasing separate artifacts for userspace and kernel space is that Falco is amenable to supporting a large array of environments, that is, multiple kernel versions, distros and architectures (see `libs` [driver - kernel version support matrix](https://github.com/falcosecurity/libs#drivers-officially-supported-architectures)). The Falco project manages the release of both the Falco userspace binary and pre-compiled Falco kernel drivers for the most popular kernel versions and distros. The build and publish process is managed by the [test-infra](https://github.com/falcosecurity/test-infra) repo. The Falco userspace executable includes bundled dependencies, so that it can be run from anywhere.
> Note: Starting with Falco 0.34.x releases, the Falco userspace binary includes the `modern_bpf` driver object code during the linking process. This integration is made possible by the CO-RE (Compile Once - Run Everywhere) feature of the modern BPF driver. CO-RE allows the driver to function on kernels that have backported BTF (BPF Type Format) support or have a kernel version >= 5.8. For the older `kmod` and `bpf` drivers, separate artifacts are released for the kernel space. This is because these drivers need to be explicitly compiled for the specific kernel release, using the exact kernel headers. This approach ensures that Falco can support a wide range of environments, including multiple kernel versions, distributions, and architectures. (see `libs` [driver - kernel version support matrix](https://github.com/falcosecurity/libs#drivers-officially-supported-architectures)).
The Falco project also publishes all sources for each component. In fact, sources are included in the Falco release in the same way as some plugins (k8saudit and cloudtrail) as well as the rules that are shipped together with Falco. This empowers the end user to audit the integrity of the project as well as build kernel drivers for custom kernels or not officially supported kernels / distros (see [driverkit](https://github.com/falcosecurity/driverkit) for more information). While the Falco project is deeply embedded into an ecosystem of supporting [Falco sub-projects](https://github.com/falcosecurity/evolution) that aim to make the deployment of Falco easy, user-friendly, extendible and cloud-native, core Falco is split across two repos, [falco](https://github.com/falcosecurity/falco) (this repo) and [libs](https://github.com/falcosecurity/libs). The `libs` repo contains >90% of Falco's core features and is the home of each of the kernel drivers and engines. More details are provided in the [Falco Components Versioning](#falco-components-versioning) section.
The Falco Project manages the release of both the Falco userspace binary and pre-compiled Falco kernel drivers for the most popular kernel versions and distros. The build and publish process is managed by the [test-infra](https://github.com/falcosecurity/test-infra) repo.
Finally, the release process follows a transparent process described in more detail in the following sections and the official [Falco docs](https://falco.org/) contain rich information around building, installing and using Falco.
The Falco userspace executable includes bundled dependencies, so that it can be run from anywhere.
Falco publishes all sources, enabling users to audit the project's integrity and build kernel drivers for custom or unsupported kernels/distributions, specifically for non-modern BPF drivers (see [driverkit](https://github.com/falcosecurity/driverkit) for more information).
Finally, the release process follows a transparent process described in more detail in the following sections and the official [Falco guide and documentation](https://falco.org/) provide rich information around building, installing and using Falco.
### Falco Binaries, Rules and Sources Artifacts - Quick Links
@@ -28,7 +32,7 @@ The Falco project publishes all sources and the Falco userspace binaries as GitH
- `tgz`, `zip` source code
- [Libs Releases](https://github.com/falcosecurity/libs/releases)
- `tgz`, `zip` source code
- [Libs Releases](https://github.com/falcosecurity/libs/releases)
- [Driver Releases](https://github.com/falcosecurity/libs/releases), marked with `+driver` [build metadata](https://semver.org/).
- `tgz`, `zip` source code
- [Falco Rules Releases](https://github.com/falcosecurity/rules/releases)
- `tgz`, `zip` source code, each ruleset is tagged separately in a mono-repo fashion, see the [rules release guidelines](https://github.com/falcosecurity/rules/blob/main/RELEASE.md)
@@ -42,8 +46,9 @@ Alternatively Falco binaries or plugins can be downloaded from the Falco Artifac
### Falco Drivers Artifacts Repo - Quick Links
> Note: This section specifically applies to non-modern BPF drivers.
The Falco project publishes all drivers for each release for all popular kernel versions / distros and `x86_64` and `aarch64` architectures to the Falco project managed Artifacts repo. The Artifacts repo follows standard directory level conventions. The respective driver object file is prefixed by distro and named / versioned by kernel release - `$(uname -r)`. Pre-compiled drivers are released with a [best effort](https://github.com/falcosecurity/falco/blob/master/proposals/20200818-artifacts-storage.md#notice) notice. This is because gcc (`kmod`) and clang (`bpf`) compilers or for example the eBPF verifier are not perfect. More details around driver versioning and driver compatibility are provided in the [Falco Components Versioning](#falco-components-versioning) section. Short preview: If you use the standard Falco setup leveraging driver-loader, [driver-loader script](https://github.com/falcosecurity/falco/blob/master/scripts/falco-driver-loader) will fetch the kernel space artifact (object file) corresponding to the default `DRIVER_VERSION` Falco was shipped with.
The Falco Project publishes all drivers for each release for popular kernel versions / distros and `x86_64` and `aarch64` architectures to the Falco project's managed Artifacts repo. The Artifacts repo follows standard directory level conventions. The respective driver object file is prefixed by distro and named / versioned by kernel release - `$(uname -r)`. Pre-compiled drivers are released with a [best effort](https://github.com/falcosecurity/falco/blob/master/proposals/20200818-artifacts-storage.md#notice) notice. This is because gcc (`kmod`) and clang (`bpf`) compilers sometimes fail to build the artifacts for a specific kernel version. More details around driver versioning and driver compatibility are provided in the [Falco Components Versioning](#falco-components-versioning) section. Short preview: If you use the standard Falco setup leveraging driver-loader, [driver-loader script](https://github.com/falcosecurity/falco/blob/master/scripts/falco-driver-loader) will fetch the kernel space artifact (object file) corresponding to the default `DRIVER_VERSION` Falco was shipped with.
- [Falco Artifacts Repo Drivers Root](https://download.falco.org/?prefix=driver/)
- Option 1: Kernel module (`.ko` files) - all under same driver version directory
@@ -52,16 +57,16 @@ The Falco project publishes all drivers for each release for all popular kernel
### Timeline
Falco releases are due to happen 3 times per year. Our current schedule sees a new release by the end of January, May, and September each year. Hotfix releases can happen whenever it's needed.
Falco follows a release schedule of three times per year, with releases expected at the end of January, May, and September. Hotfix releases are issued as needed.
Changes and new features are grouped in [milestones](https://github.com/falcosecurity/falco/milestones), the milestone with the next version represents what is going to be released.
Changes and new features are organized into [milestones](https://github.com/falcosecurity/falco/milestones). The milestone corresponding to the next version represents the content that will be included in the upcoming release.
### Procedures
The release process is mostly automated requiring only a few manual steps to initiate and complete it.
The release process is mostly automated, requiring only a few manual steps to initiate and complete.
Moreover, we need to assign owners for each release (usually we pair a new person with an experienced one). Assignees and the due date are proposed during the [weekly community call](https://github.com/falcosecurity/community).
Moreover, we assign owners for each release (typically pairing a new person with an experienced one). Assignees and due dates for releases are proposed during the [weekly community call](https://github.com/falcosecurity/community).
At a high level each Falco release needs to follow a pre-determined sequencing of releases and build order:
@@ -69,11 +74,13 @@ At a high level each Falco release needs to follow a pre-determined sequencing o
- [4] Falco driver pre-compiled object files push to Falco's Artifacts repo
- [5] Falco userspace binary release
Finally, on the proposed due date the assignees for the upcoming release proceed with the processes described below.
Assignees are responsible for creating a Falco GitHub issue to track the release tasks and monitor the progress of the release. This issue serves as a central point for communication and provides updates on the release dates. You can refer to the [Falco v0.35 release](https://github.com/falcosecurity/falco/issues/2554) or [Libs Release (0.11.0+5.0.1+driver)](https://github.com/falcosecurity/libs/issues/1092) issues as examples/templates for creating the release issue.
Finally, on the proposed due date, the assignees for the upcoming release proceed with the processes described below.
## Pre-Release Checklist
Prior to cutting a release the following preparatory steps should take 5 minutes using the GitHub UI.
Before proceeding with the release, make sure to complete the following preparatory steps, which can be easily done using the GitHub UI:
### 1. Release notes
- Find the previous release date (`YYYY-MM-DD`) by looking at the [Falco releases](https://github.com/falcosecurity/falco/releases)
@@ -87,7 +94,19 @@ Prior to cutting a release the following preparatory steps should take 5 minutes
- Move the [tasks not completed](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Aopen) to a new minor milestone
### 3. Release PR
### 3. Release branch
Assuming we are releasing a non-patch version (like: Falco 0.34.0), a new release branch needs to be created.
Its naming will be `release/M.m.x`; for example: `release/0.34.x`.
The same branch will then be used for any eventual cherry pick for patch releases.
For patch releases, instead, the `release/M.m.x` branch should already be in place; no more steps are needed.
Double check that any PR that should be part of the tag has been cherry-picked from master!
### 4. Release PR
The release PR is meant to be made against the respective `release/M.m.x` branch, **then cherry-picked on master**.
- Double-check if any hard-coded version number is present in the code, it should be not present anywhere:
- If any, manually correct it then open an issue to automate version number bumping later
@@ -98,50 +117,54 @@ Prior to cutting a release the following preparatory steps should take 5 minutes
- Add the latest changes on top the previous `CHANGELOG.md`
- Submit a PR with the above modifications
- Await PR approval
- Close the completed milestone as soon as the PR is merged
- Close the completed milestone as soon as the PR is merged into the release branch
- Cherry pick the PR on master too
## Publishing Pre-Releases (RCs and tagged development versions)
Core maintainers and/or the release manager can decide to publish pre-releases at any time before the final release
is live for development and testing purposes.
The prerelease tag must be formatted as `M.m.p-r`where `r` is the prerelease version information (e.g. `0.35.0-rc1`.)
To do so:
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
- Use `M.m.p-r` both as tag version and release title.
- Check the "Set as a pre-release" checkbox and make sure "Set as the latest release" is unchecked
- It is recommended to add a brief description so that other contributors will understand the reason why the prerelease is published
- Publish the prerelease!
- The release pipeline will start automatically. Packages will be uploaded to the `-dev` bucket and container images will be tagged with the specified tag.
In order to check the status of the release pipeline click on the [GitHub Actions tab](https://github.com/falcosecurity/falco/actions?query=event%3Arelease) in the Falco repository and filter by release.
## Release
Now assume `x.y.z` is the new version.
Assume `M.m.p` is the new version.
### 1. Create a tag
- Once the release PR has got merged, and the CI has done its job on the master, git tag the new release
```
git pull
git checkout master
git tag x.y.z
git push origin x.y.z
```
> **N.B.**: do NOT use an annotated tag. For reference https://git-scm.com/book/en/v2/Git-Basics-Tagging
- Wait for the CI to complete
### 2. Update the GitHub release
### 1. Create the release with GitHub
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
- Use `x.y.z` both as tag version and release title
- Use `M.m.p` both as tag version and release title
- Use the following template to fill the release description:
```
<!-- Substitute x.y.z with the current release version -->
<!-- Substitute M.m.p with the current release version -->
| Packages | Download |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| rpm-x86_64 | [![rpm](https://img.shields.io/badge/Falco-x.y.z-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpm/falco-x.y.z-x86_64.rpm) |
| deb-x86_64 | [![deb](https://img.shields.io/badge/Falco-x.y.z-%2300aec7?style=flat-square)](https://download.falco.org/packages/deb/stable/falco-x.y.z-x86_64.deb) |
| tgz-x86_64 | [![tgz](https://img.shields.io/badge/Falco-x.y.z-%2300aec7?style=flat-square)](https://download.falco.org/packages/bin/x86_64/falco-x.y.z-x86_64.tar.gz) |
| rpm-aarch64 | [![rpm](https://img.shields.io/badge/Falco-x.y.z-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpm/falco-x.y.z-aarch64.rpm) |
| deb-aarch64 | [![deb](https://img.shields.io/badge/Falco-x.y.z-%2300aec7?style=flat-square)](https://download.falco.org/packages/deb/stable/falco-x.y.z-aarch64.deb) |
| tgz-aarch64 | [![tgz](https://img.shields.io/badge/Falco-x.y.z-%2300aec7?style=flat-square)](https://download.falco.org/packages/bin/aarch64/falco-x.y.z-aarch64.tar.gz) |
| rpm-x86_64 | [![rpm](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpm/falco-M.m.p-x86_64.rpm) |
| deb-x86_64 | [![deb](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/deb/stable/falco-M.m.p-x86_64.deb) |
| tgz-x86_64 | [![tgz](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/bin/x86_64/falco-M.m.p-x86_64.tar.gz) |
| rpm-aarch64 | [![rpm](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpm/falco-M.m.p-aarch64.rpm) |
| deb-aarch64 | [![deb](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/deb/stable/falco-M.m.p-aarch64.deb) |
| tgz-aarch64 | [![tgz](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/bin/aarch64/falco-M.m.p-aarch64.tar.gz) |
| Images |
| --------------------------------------------------------------------------- |
| `docker pull docker.io/falcosecurity/falco:x.y.z` |
| `docker pull public.ecr.aws/falcosecurity/falco:x.y.z` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:x.y.z` |
| `docker pull docker.io/falcosecurity/falco-no-driver:x.y.z` |
| `docker pull docker.io/falcosecurity/falco:M.m.p` |
| `docker pull public.ecr.aws/falcosecurity/falco:M.m.p` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:M.m.p` |
| `docker pull docker.io/falcosecurity/falco-no-driver:M.m.p` |
<changelog>
@@ -163,14 +186,17 @@ Now assume `x.y.z` is the new version.
```
- Finally, publish the release!
- The release pipeline will start automatically upon publication and all packages and container images will be uploaded to the stable repositories.
### 3. Update the meeting notes
In order to check the status of the release pipeline click on the [GitHub Actions tab](https://github.com/falcosecurity/falco/actions?query=event%3Arelease) in the Falco repository and filter by release.
### 2. Update the meeting notes
For each release we archive the meeting notes in git for historical purposes.
- The notes from the Falco meetings can be [found here](https://hackmd.io/3qYPnZPUQLGKCzR14va_qg).
- Note: There may be other notes from working groups that can optionally be added as well as needed.
- Add the entire content of the document to a new file in [github.com/falcosecurity/community/tree/master/meeting-notes](https://github.com/falcosecurity/community/tree/master/meeting-notes) as a new file labeled `release-x.y.z.md`
- Add the entire content of the document to a new file in [github.com/falcosecurity/community/tree/master/meeting-notes](https://github.com/falcosecurity/community/tree/master/meeting-notes) as a new file labeled `release-M.m.p.md`
- Open up a pull request with the new change.
@@ -186,13 +212,13 @@ Announce the new release to the world!
## Falco Components Versioning
This section provides more details around the versioning of all components that make up core Falco. It can also be a useful guide for the uninitiated to be more informed about Falco's source. Because the `libs` repo contains >90% of Falco's core features and is the home of each of the kernel drivers and engines, the [libs release doc](https://github.com/falcosecurity/libs/blob/master/release.md) is an excellent additional resource. In addition, the [plugins release doc](https://github.com/falcosecurity/plugins/blob/master/release.md) provides similar details around Falco's plugins. `SHA256` checksums are provided throughout Falco's source code to empower the end user to perform integrity checks. All Falco releases also contain the sources as part of the packages.
This section provides more details around the versioning of the components that make up Falco's core. It can also be a useful guide for the uninitiated to be more informed about Falco's source. Because `libs` makes up the greater portion of the source code of the Falco binary and is the home of each of the kernel drivers and engines, the [libs release doc](https://github.com/falcosecurity/libs/blob/master/release.md) is an excellent additional resource. In addition, the [plugins release doc](https://github.com/falcosecurity/plugins/blob/master/release.md) provides similar details around Falco's plugins. `SHA256` checksums are provided throughout Falco's source code to empower the end user to perform integrity checks. All Falco releases also contain the sources as part of the packages.
### Falco repo (this repo)
- Falco version is a git tag (`x.y.z`), see [Procedures](#procedures) section. Note that the Falco version is a sem-ver-like schema, but not fully compatible with sem-ver.
- [FALCO_ENGINE_VERSION](https://github.com/falcosecurity/falco/blob/master/userspace/engine/falco_engine_version.h) is not sem-ver and must be bumped either when a backward incompatible change has been introduced to the rules files syntax or `falco --list -N | sha256sum` has changed. Breaking changes introduced in the Falco engine are not necessarily tied to the drivers or libs versions. The primary idea behind the hash is that when new filter / display fields (see currently supported [Falco fields](https://falco.org/docs/rules/supported-fields/)) are introduced a version bump indicates that this field was not available in previous engine versions. See the [rules release guidelines](https://github.com/falcosecurity/rules/blob/main/RELEASE.md#versioning-a-ruleset) to understand how this affects the versioning of Falco rules.
- During development and release preparation, libs and driver reference commits are often bumped in Falco's cmake setup ([falcosecurity-libs cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/falcosecurity-libs.cmake#L30) and [driver cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/driver.cmake#L29)) in order to merge new Falco features. In practice they are mostly bumped at the same time referencing the same `libs` commit. However, for the official Falco build `FALCOSECURITY_LIBS_VERSION` flag that references the stable Libs version is used (read below).
- [FALCO_ENGINE_VERSION](https://github.com/falcosecurity/falco/blob/master/userspace/engine/falco_engine_version.h) is not sem-ver and must be bumped either when a backward incompatible change has been introduced to the rules files syntax and/or `FALCO_FIELDS_CHECKSUM` computed via `falco --list -N | sha256sum` has changed. The primary idea is that when new filter / display fields (see currently supported [Falco fields](https://falco.org/docs/rules/supported-fields/)) are introduced, a version change indicates that these fields were not available in previous engine versions. See the [rules release guidelines](https://github.com/falcosecurity/rules/blob/main/RELEASE.md#versioning-a-ruleset) to understand how this affects the versioning of Falco rules. Breaking changes introduced in the Falco engine are not necessarily tied to the drivers or libs versions. Lastly, `FALCO_ENGINE_VERSION` is typically incremented once during a Falco release cycle, while `FALCO_FIELDS_CHECKSUM` is bumped whenever necessary during the development and testing phases of the release cycle.
- During development and release preparation, libs and driver reference commits are often bumped in Falco's cmake setup ([falcosecurity-libs cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/falcosecurity-libs.cmake#L30) and [driver cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/driver.cmake#L29)) in order to merge new Falco features. In practice, they are mostly bumped at the same time referencing the same `libs` commit. However, for the official Falco build `FALCOSECURITY_LIBS_VERSION` flag that references the stable libs version is used (read below).
- Similarly, Falco plugins versions are bumped in Falco's cmake setup ([plugins cmake](https://github.com/falcosecurity/falco/blob/master/cmake/modules/plugins.cmake)) and those versions are the ones used for the Falco release.
- At release time Plugin, Libs and Driver versions are compatible with Falco.
- If you use the standard Falco setup leveraging driver-loader, [driver-loader script](https://github.com/falcosecurity/falco/blob/master/scripts/falco-driver-loader) will fetch the kernel space artifact (object file) corresponding to the default `DRIVER_VERSION` Falco was shipped with (read more below under Libs).
@@ -212,7 +238,7 @@ Driver:
### Libs repo
- Libs version is a git tag (`x.y.z`) and when building Falco the libs version is set via the `FALCOSECURITY_LIBS_VERSION` flag (see above).
- Driver version in and of itself is not directly tied to the Falco binary as opposed to the libs version being part of the source code used to compile Falco's userspace binary. This is because of the strict separation between userspace and kernel space artifacts, so things become a bit more interesting here. This is why the concept of a `Default driver` has been introduced to still implicitly declare the compatible driver versions. For example, if the default driver version is `2.0.0+driver`, Falco works with all driver versions >= 2.0.0 and < 3.0.0. This is a consequence of how the driver version is constructed starting from the `Driver API version` and `Driver Schema version`. Driver API and Schema versions are explained in the respective [libs driver doc](https://github.com/falcosecurity/libs/blob/master/driver/README.VERSION.md) -> Falco's `driver-loader` will always fetch the default driver, therefore a Falco release is always "shipped" with the driver version corresponding to the default driver.
- The driver version is not directly linked to the userspace components of the Falco binary. This is because of the clear separation between userspace and kernel space, which adds an additional layer of complexity. To address this, the concept of a `Default driver` has been introduced, allowing for implicit declaration of compatible driver versions. For example, if the default driver version is `5.0.1+driver`, Falco works with all driver versions >= 5.0.1 and < 6.0.0. This is a consequence of how the driver version is constructed starting from the `Driver API version` and `Driver Schema version`. Driver API and Schema versions are explained in the respective [libs driver doc](https://github.com/falcosecurity/libs/blob/master/driver/README.VERSION.md) -> Falco's `driver-loader` will always fetch the default driver, therefore a Falco release is always "shipped" with the driver version corresponding to the default driver.
- See [libs release doc](https://github.com/falcosecurity/libs/blob/master/release.md) for more information.
### Plugins repo
@@ -223,4 +249,4 @@ Driver:
### Rules repo
- Rulesets are versioned individually through git tags
- See [rules release doc](https://github.com/falcosecurity/rules/blob/main/RELEASE.md) for more information.
- See [plugins release doc](https://github.com/falcosecurity/plugins/blob/master/release.md) for more information about plugins rulesets.
- See [plugins release doc](https://github.com/falcosecurity/plugins/blob/master/release.md) for more information about plugins rulesets.

Binary file not shown.

View File

@@ -3,7 +3,9 @@
# Falco Branding Guidelines
This document describes The Falco Project's branding guidelines, language, and message.
Falco is an open source security project whose brand and identity are governed by the [Cloud Native Computing Foundation](https://www.linuxfoundation.org/legal/trademark-usage).
This document describes the official branding guidelines of The Falco Project. Please see the [Falco Branding](https://falco.org/community/falco-brand/) page on our website for further details.
Content in this document can be used to publicly share about Falco.
@@ -82,7 +84,7 @@ Examples of malicious behavior include:
Falco is capable of [consuming the Kubernetes audit logs](https://kubernetes.io/docs/tasks/debug-application-cluster/falco/#use-falco-to-collect-audit-events).
By adding Kubernetes application context, and Kubernetes audit logs teams can understand who did what.
### Writing about Falco
##### Yes
@@ -122,7 +124,6 @@ Falco does not prevent unwanted behavior.
Falco however alerts when unusual behavior occurs.
This is commonly referred to as **detection** or **forensics**.
---
# Glossary

View File

@@ -1,159 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or
# https://cmake.org/licensing for details.
#[=======================================================================[.rst:
Catch
-----
This module defines a function to help use the Catch test framework.
The :command:`catch_discover_tests` discovers tests by asking the compiled test
executable to enumerate its tests. This does not require CMake to be re-run
when tests change. However, it may not work in a cross-compiling environment,
and setting test properties is less convenient.
This command is intended to replace use of :command:`add_test` to register
tests, and will create a separate CTest test for each Catch test case. Note
that this is in some cases less efficient, as common set-up and tear-down logic
cannot be shared by multiple test cases executing in the same instance.
However, it provides more fine-grained pass/fail information to CTest, which is
usually considered as more beneficial. By default, the CTest test name is the
same as the Catch name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
.. command:: catch_discover_tests
Automatically add tests with CTest by querying the compiled test executable
for available tests::
catch_discover_tests(target
[TEST_SPEC arg1...]
[EXTRA_ARGS arg1...]
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
[PROPERTIES name1 value1...]
[TEST_LIST var]
)
``catch_discover_tests`` sets up a post-build command on the test executable
that generates the list of tests by parsing the output from running the test
with the ``--list-test-names-only`` argument. This ensures that the full
list of tests is obtained. Since test discovery occurs at build time, it is
not necessary to re-run CMake when the list of tests changes.
However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
in order to function in a cross-compiling environment.
Additionally, setting properties on tests is somewhat less convenient, since
the tests are not available at CMake time. Additional test properties may be
assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
more fine-grained test control is needed, custom content may be provided
through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
directory property. The set of discovered tests is made accessible to such a
script via the ``<target>_TESTS`` variable.
The options are:
``target``
Specifies the Catch executable, which must be a known CMake executable
target. CMake will substitute the location of the built executable when
running the test.
``TEST_SPEC arg1...``
Specifies test cases, wildcarded test cases, tags and tag expressions to
pass to the Catch executable with the ``--list-test-names-only`` argument.
``EXTRA_ARGS arg1...``
Any extra arguments to pass on the command line to each test case.
``WORKING_DIRECTORY dir``
Specifies the directory in which to run the discovered test cases. If this
option is not provided, the current binary directory is used.
``TEST_PREFIX prefix``
Specifies a ``prefix`` to be prepended to the name of each discovered test
case. This can be useful when the same test executable is being used in
multiple calls to ``catch_discover_tests()`` but with different
``TEST_SPEC`` or ``EXTRA_ARGS``.
``TEST_SUFFIX suffix``
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
be specified.
``PROPERTIES name1 value1...``
Specifies additional properties to be set on all tests discovered by this
invocation of ``catch_discover_tests``.
``TEST_LIST var``
Make the list of tests available in the variable ``var``, rather than the
default ``<target>_TESTS``. This can be useful when the same test
executable is being used in multiple calls to ``catch_discover_tests()``.
Note that this variable is only available in CTest.
#]=======================================================================]
# ------------------------------------------------------------------------------
function(catch_discover_tests TARGET)
cmake_parse_arguments("" "" "TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST" "TEST_SPEC;EXTRA_ARGS;PROPERTIES"
${ARGN})
if(NOT _WORKING_DIRECTORY)
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
endif()
if(NOT _TEST_LIST)
set(_TEST_LIST ${TARGET}_TESTS)
endif()
# Generate a unique name based on the extra arguments
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}")
string(SUBSTRING ${args_hash} 0 7 args_hash)
# Define rule to generate test list for aforementioned test executable
set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
get_property(
crosscompiling_emulator
TARGET ${TARGET}
PROPERTY CROSSCOMPILING_EMULATOR)
add_custom_command(
TARGET ${TARGET}
POST_BUILD
BYPRODUCTS "${ctest_tests_file}"
COMMAND
"${CMAKE_COMMAND}" -D "TEST_TARGET=${TARGET}" -D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>" -D
"TEST_EXECUTOR=${crosscompiling_emulator}" -D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}" -D
"TEST_SPEC=${_TEST_SPEC}" -D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}" -D "TEST_PROPERTIES=${_PROPERTIES}" -D
"TEST_PREFIX=${_TEST_PREFIX}" -D "TEST_SUFFIX=${_TEST_SUFFIX}" -D "TEST_LIST=${_TEST_LIST}" -D
"CTEST_FILE=${ctest_tests_file}" -P "${_CATCH_DISCOVER_TESTS_SCRIPT}"
VERBATIM)
file(
WRITE "${ctest_include_file}"
"if(EXISTS \"${ctest_tests_file}\")\n" " include(\"${ctest_tests_file}\")\n" "else()\n"
" add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n" "endif()\n")
if(NOT ${CMAKE_VERSION} VERSION_LESS "3.10.0")
# Add discovered tests to directory TEST_INCLUDE_FILES
set_property(
DIRECTORY
APPEND
PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}")
else()
# Add discovered tests as directory TEST_INCLUDE_FILE if possible
get_property(
test_include_file_set
DIRECTORY
PROPERTY TEST_INCLUDE_FILE
SET)
if(NOT ${test_include_file_set})
set_property(DIRECTORY PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}")
else()
message(FATAL_ERROR "Cannot set more than one TEST_INCLUDE_FILE")
endif()
endif()
endfunction()
# ######################################################################################################################
set(_CATCH_DISCOVER_TESTS_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/CatchAddTests.cmake)

View File

@@ -1,61 +0,0 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or
# https://cmake.org/licensing for details.
set(prefix "${TEST_PREFIX}")
set(suffix "${TEST_SUFFIX}")
set(spec ${TEST_SPEC})
set(extra_args ${TEST_EXTRA_ARGS})
set(properties ${TEST_PROPERTIES})
set(script)
set(suite)
set(tests)
function(add_command NAME)
set(_args "")
foreach(_arg ${ARGN})
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
else()
set(_args "${_args} ${_arg}")
endif()
endforeach()
set(script
"${script}${NAME}(${_args})\n"
PARENT_SCOPE)
endfunction()
# Run test executable to get list of available tests
if(NOT EXISTS "${TEST_EXECUTABLE}")
message(FATAL_ERROR "Specified test executable '${TEST_EXECUTABLE}' does not exist")
endif()
execute_process(
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-names-only
OUTPUT_VARIABLE output
RESULT_VARIABLE result)
# Catch --list-test-names-only reports the number of tests, so 0 is... surprising
if(${result} EQUAL 0)
message(WARNING "Test executable '${TEST_EXECUTABLE}' contains no tests!\n")
elseif(${result} LESS 0)
message(FATAL_ERROR "Error running test executable '${TEST_EXECUTABLE}':\n" " Result: ${result}\n"
" Output: ${output}\n")
endif()
string(REPLACE "\n" ";" output "${output}")
# Parse output
foreach(line ${output})
set(test ${line})
# use escape commas to handle properly test cases with commands inside the name
string(REPLACE "," "\\," test_name ${test})
# ...and add to script
add_command(add_test "${prefix}${test}${suffix}" ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" "${test_name}" ${extra_args})
add_command(set_tests_properties "${prefix}${test}${suffix}" PROPERTIES WORKING_DIRECTORY "${TEST_WORKING_DIR}"
${properties})
list(APPEND tests "${prefix}${test}${suffix}")
endforeach()
# Create a list of all discovered tests, which users may use to e.g. set properties on the tests
add_command(set ${TEST_LIST} ${tests})
# Write CTest script
file(WRITE "${CTEST_FILE}" "${script}")

View File

@@ -1,27 +0,0 @@
#
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
include(ExternalProject)
set(CATCH2_INCLUDE ${CMAKE_BINARY_DIR}/catch2-prefix/include)
set(CATCH_EXTERNAL_URL URL https://github.com/catchorg/catch2/archive/v2.13.9.tar.gz URL_HASH
SHA256=06dbc7620e3b96c2b69d57bf337028bf245a211b3cddb843835bfe258f427a52)
ExternalProject_Add(
catch2
PREFIX ${CMAKE_BINARY_DIR}/catch2-prefix
${CATCH_EXTERNAL_URL}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/catch2-prefix/src/catch2/single_include/catch2/catch.hpp
${CATCH2_INCLUDE}/catch.hpp)

View File

@@ -1,28 +0,0 @@
#
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
include(ExternalProject)
set(FAKEIT_INCLUDE ${CMAKE_BINARY_DIR}/fakeit-prefix/include)
set(FAKEIT_EXTERNAL_URL URL https://github.com/eranpeer/fakeit/archive/2.0.9.tar.gz URL_HASH
SHA256=dc4ee7b17a84c959019b92c20fce6dc9426e9e170b6edf84db6cb2e188520cd7)
ExternalProject_Add(
fakeit-external
PREFIX ${CMAKE_BINARY_DIR}/fakeit-prefix
${FAKEIT_EXTERNAL_URL}
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND
${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/fakeit-prefix/src/fakeit-external/single_header/catch/fakeit.hpp
${FAKEIT_INCLUDE}/fakeit.hpp)

View File

@@ -1,31 +0,0 @@
#
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
# This module is used to understand where the makedev function is defined in the glibc in use. see 'man 3 makedev'
# Usage: In your CMakeLists.txt include(FindMakedev)
#
# In your source code:
#
# #if HAVE_SYS_MKDEV_H #include <sys/mkdev.h> #endif #ifdef HAVE_SYS_SYSMACROS_H #include <sys/sysmacros.h> #endif
#
include(${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake)
check_include_file("sys/mkdev.h" HAVE_SYS_MKDEV_H)
check_include_file("sys/sysmacros.h" HAVE_SYS_SYSMACROS_H)
if(HAVE_SYS_MKDEV_H)
add_definitions(-DHAVE_SYS_MKDEV_H)
endif()
if(HAVE_SYS_SYSMACROS_H)
add_definitions(-DHAVE_SYS_SYSMACROS_H)
endif()

View File

@@ -19,29 +19,36 @@ if(NOT FALCO_VERSION)
# Try to obtain the exact git tag
git_get_exact_tag(FALCO_TAG)
if(NOT FALCO_TAG)
# Fetch current hash
get_git_head_revision(refspec FALCO_HASH)
if(NOT FALCO_HASH OR FALCO_HASH MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Obtain the closest tag
git_get_latest_tag(FALCO_LATEST_TAG)
if(NOT FALCO_LATEST_TAG OR FALCO_LATEST_TAG MATCHES "NOTFOUND$")
# Obtain the closest tag
git_describe(FALCO_VERSION "--always" "--tags" "--abbrev=7")
string(REGEX MATCH "^[0-9]+.[0-9]+.[0-9]+$" FALCO_TAG ${FALCO_VERSION})
if(FALCO_VERSION MATCHES "NOTFOUND$" OR FALCO_TAG STREQUAL "")
# Fetch current hash
get_git_head_revision(refspec FALCO_HASH)
if(NOT FALCO_HASH OR FALCO_HASH MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Compute commit delta since tag
git_get_delta_from_tag(FALCO_DELTA ${FALCO_LATEST_TAG} ${FALCO_HASH})
if(NOT FALCO_DELTA OR FALCO_DELTA MATCHES "NOTFOUND$")
# Obtain the closest tag
git_get_latest_tag(FALCO_LATEST_TAG)
if(NOT FALCO_LATEST_TAG OR FALCO_LATEST_TAG MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Cut hash to 7 bytes
string(SUBSTRING ${FALCO_HASH} 0 7 FALCO_HASH)
# Format FALCO_VERSION to be semver with prerelease and build part
set(FALCO_VERSION
"${FALCO_LATEST_TAG}-${FALCO_DELTA}+${FALCO_HASH}")
endif()
# Compute commit delta since tag
git_get_delta_from_tag(FALCO_DELTA ${FALCO_LATEST_TAG} ${FALCO_HASH})
if(NOT FALCO_DELTA OR FALCO_DELTA MATCHES "NOTFOUND$")
set(FALCO_VERSION "0.0.0")
else()
# Cut hash to 7 bytes
string(SUBSTRING ${FALCO_HASH} 0 7 FALCO_HASH)
# Format FALCO_VERSION to be semver with prerelease and build part
set(FALCO_VERSION
"${FALCO_LATEST_TAG}-${FALCO_DELTA}+${FALCO_HASH}")
endif()
endif()
endif()
endif()
# Format FALCO_VERSION to be semver with prerelease and build part
string(REPLACE "-g" "+" FALCO_VERSION "${FALCO_VERSION}")
else()
# A tag has been found: use it as the Falco version
set(FALCO_VERSION "${FALCO_TAG}")

View File

@@ -91,15 +91,16 @@ function(git_get_latest_tag _var)
find_package(Git QUIET)
endif()
# We use git describe --tags `git rev-list --tags --max-count=1`
# We use git describe --tags `git rev-list --exclude "*.*.*-*" --tags --max-count=1`
# Note how we eclude prereleases tags (the ones with "-alphaX")
execute_process(COMMAND
"${GIT_EXECUTABLE}"
rev-list
--exclude "*.*.*-*"
--tags
--max-count=1
WORKING_DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMAND tail -n1
RESULT_VARIABLE
res
OUTPUT_VARIABLE

View File

@@ -26,8 +26,8 @@ else()
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
# ie., `cmake -DDRIVER_VERSION=dev ..`
if(NOT DRIVER_VERSION)
set(DRIVER_VERSION "4.0.0+driver")
set(DRIVER_CHECKSUM "SHA256=0f71a4e4492847ce6ca35fe6f9ecdf682f603c878397e57d7628a0cd60a29aed")
set(DRIVER_VERSION "5.0.1+driver")
set(DRIVER_CHECKSUM "SHA256=8b197b916b6419dac8fb41807aa05d822164c7bfd2c3eef66d20d060a05a485a")
endif()
# cd /path/to/build && cmake /path/to/source

View File

@@ -15,14 +15,14 @@ include(ExternalProject)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} FALCOCTL_SYSTEM_NAME)
set(FALCOCTL_VERSION "0.4.0")
set(FALCOCTL_VERSION "0.5.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "13c88e612efe955bc014918a7af30bae28dc5ba99b2962af57e36b1b87f527f9")
set(FALCOCTL_HASH "ba82ee14ee72fe5737f1b5601e403d8a9422dfe2c467d1754eb488001eeea5f1")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "0f8898853e99a2cd1b4dd6b161e8545cf20ce0e3ce79cddc539f6002257d5de5")
set(FALCOCTL_HASH "be145ece641d439011cc4a512d0fd2dac5974cab7399f9a7cd43f08eb43dd446")
endif()
ExternalProject_Add(

View File

@@ -25,14 +25,17 @@ if(FALCOSECURITY_LIBS_SOURCE_DIR)
else()
# 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 ..`
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
if(NOT FALCOSECURITY_LIBS_VERSION)
set(FALCOSECURITY_LIBS_VERSION "0.10.3")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=be6c771b9182fcd8fcd52cb56022c380edf6e051d1b0eee1983e093494ac0837")
set(FALCOSECURITY_LIBS_VERSION "0.11.0-rc5")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=079ab5f596a0d8af2a7f843e8159f83cb7c864331019aaed822daa737c75e9e7")
endif()
# cd /path/to/build && cmake /path/to/source
execute_process(COMMAND "${CMAKE_COMMAND}" -DFALCOSECURITY_LIBS_VERSION=${FALCOSECURITY_LIBS_VERSION} -DFALCOSECURITY_LIBS_CHECKSUM=${FALCOSECURITY_LIBS_CHECKSUM}
execute_process(COMMAND "${CMAKE_COMMAND}"
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}"
-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 .
@@ -50,6 +53,8 @@ if(MUSL_OPTIMIZED_BUILD)
endif()
set(SCAP_HOST_ROOT_ENV_VAR_NAME "HOST_ROOT")
set(SCAP_HOSTNAME_ENV_VAR "FALCO_HOSTNAME")
set(SINSP_AGENT_CGROUP_MEM_PATH_ENV_VAR "FALCO_CGROUP_MEM_PATH")
if(NOT LIBSCAP_DIR)
set(LIBSCAP_DIR "${FALCOSECURITY_LIBS_SOURCE_DIR}")

34
cmake/modules/njson.cmake Normal file
View File

@@ -0,0 +1,34 @@
#
# 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.
#
#
# nlohmann-json
#
if(NJSON_INCLUDE)
# Adding the custom target we can use it with `add_dependencies()`
if(NOT TARGET njson)
add_custom_target(njson)
endif()
else()
# We always use the bundled version
set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson")
set(NJSON_INCLUDE "${NJSON_SRC}/single_include")
ExternalProject_Add(
njson
URL "https://github.com/nlohmann/json/archive/v3.3.0.tar.gz"
URL_HASH "SHA256=2fd1d207b4669a7843296c41d3b6ac5b23d00dec48dba507ba051d14564aa801"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'")
endif()

View File

@@ -13,22 +13,26 @@
include(ExternalProject)
# 'stable' or 'dev'
set(PLUGINS_DOWNLOAD_BUCKET "dev")
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME)
if(NOT DEFINED PLUGINS_COMPONENT_NAME)
set(PLUGINS_COMPONENT_NAME "${CMAKE_PROJECT_NAME}-plugins")
endif()
set(PLUGIN_K8S_AUDIT_VERSION "0.5.0")
# k8saudit
set(PLUGIN_K8S_AUDIT_VERSION "0.6.0-0.5.3-33%2B81ffddd")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_K8S_AUDIT_HASH "c4abb288df018940be8e548340a74d39623b69142304e01523ea189bc698bc80")
set(PLUGIN_K8S_AUDIT_HASH "990e5c67d3b3c7cf5d30c73d73871b58767171ce7c998c1ca1d94d70c67db290")
else() # aarch64
set(PLUGIN_K8S_AUDIT_HASH "3bcc849d9f95a3fa519b4592d0947149e492b530fb935a3f98f098e234b7baa7")
set(PLUGIN_K8S_AUDIT_HASH "c3634dfa83c8c8898811ab6b7587ea6d1c6dfffbdfa56def28cab43aaf01f88c")
endif()
ExternalProject_Add(
k8saudit-plugin
URL "https://download.falco.org/plugins/stable/k8saudit-${PLUGIN_K8S_AUDIT_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/k8saudit-${PLUGIN_K8S_AUDIT_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=${PLUGIN_K8S_AUDIT_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@@ -38,24 +42,25 @@ install(FILES "${PROJECT_BINARY_DIR}/k8saudit-plugin-prefix/src/k8saudit-plugin/
ExternalProject_Add(
k8saudit-rules
URL "https://download.falco.org/plugins/stable/k8saudit-rules-${PLUGIN_K8S_AUDIT_VERSION}.tar.gz"
URL_HASH "SHA256=4383c69ba0ad63a127667c05618c37effc5297e6a7e68a1492acb0e48386540e"
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/k8saudit-rules-${PLUGIN_K8S_AUDIT_VERSION}.tar.gz"
URL_HASH "SHA256=2e3214fee00a012b32402aad5198df889773fc5f86b8ab87583fbc56ae5fb78c"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
set(PLUGIN_CLOUDTRAIL_VERSION "0.7.0")
# cloudtrail
set(PLUGIN_CLOUDTRAIL_VERSION "0.8.0-0.7.3-33%2B81ffddd")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_CLOUDTRAIL_HASH "85d94d8f5915804d5a30ff2f056e51de27d537f1fd1115050b4f4be6d32588cf")
set(PLUGIN_CLOUDTRAIL_HASH "144c297ae4285ea84b04af272f708a8b824f58bc9427a2eb91b467a6285d9e10")
else() # aarch64
set(PLUGIN_CLOUDTRAIL_HASH "61ae471ee41e76680da9ab66f583d1ec43a2e48fbad8c157caecef56e4aa5fb7")
set(PLUGIN_CLOUDTRAIL_HASH "19e7e8e11aaecd16442f65a265d3cd80ffb736ca4d3d8215893900fa0f04b926")
endif()
ExternalProject_Add(
cloudtrail-plugin
URL "https://download.falco.org/plugins/stable/cloudtrail-${PLUGIN_CLOUDTRAIL_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/cloudtrail-${PLUGIN_CLOUDTRAIL_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=${PLUGIN_CLOUDTRAIL_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
@@ -65,24 +70,25 @@ install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-plugin-prefix/src/cloudtrail-plu
ExternalProject_Add(
cloudtrail-rules
URL "https://download.falco.org/plugins/stable/cloudtrail-rules-${PLUGIN_CLOUDTRAIL_VERSION}.tar.gz"
URL_HASH "SHA256=c805be29ddc14fbffa29f7d6ee4f7e968a3bdb42da5f5483e5e6de273e8850c8"
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/cloudtrail-rules-${PLUGIN_CLOUDTRAIL_VERSION}.tar.gz"
URL_HASH "SHA256=4f51d4bd9679f7f244c225b6fe530323f3536663da26a5b9d94d6953ed4e2cbc"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-rules-prefix/src/cloudtrail-rules/aws_cloudtrail_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-rules-prefix/src/cloudtrail-rules/aws_cloudtrail_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
set(PLUGIN_JSON_VERSION "0.6.0")
# json
set(PLUGIN_JSON_VERSION "0.7.0-0.6.2-36%2B81ffddd")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_JSON_HASH "15fb7eddd978e8bb03f05412e9446e264e4548d7423b3d724b99d6d87a8c1b27")
set(PLUGIN_JSON_HASH "a9d8c595a139df5dc0cf2117127b496c94a9d3a3d0e84c1f18b3ccc9163f5f4a")
else() # aarch64
set(PLUGIN_JSON_HASH "4db23f35a750e10a5b7b54c9aa469a7587705e7faa22927e941b41f3c5533e9f")
set(PLUGIN_JSON_HASH "7d78620395526d1e6a948cc915d1d52a343c2b637c9ac0e3892e76826fcdc2df")
endif()
ExternalProject_Add(
json-plugin
URL "https://download.falco.org/plugins/stable/json-${PLUGIN_JSON_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/json-${PLUGIN_JSON_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=${PLUGIN_JSON_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""

View File

@@ -19,6 +19,7 @@ if(NOT USE_BUNDLED_DEPS)
else()
message(FATAL_ERROR "Couldn't find system yamlcpp")
endif()
add_custom_target(yamlcpp)
else()
set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp")
message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'")

View File

@@ -3,6 +3,7 @@ FROM centos:7
LABEL name="falcosecurity/falco-builder"
LABEL usage="docker run -v $PWD/..:/source -v $PWD/build:/build falcosecurity/falco-builder cmake"
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
ARG BUILD_TYPE=release
ARG BUILD_DRIVER=OFF

View File

@@ -29,12 +29,13 @@ RUN source scl_source enable devtoolset-9; \
make falco -j${MAKE_JOBS}
RUN make package
# We need `make tests` and `make all` for integration tests.
RUN make tests -j${MAKE_JOBS}
# We need `make all` for integration tests.
RUN make all -j${MAKE_JOBS}
FROM scratch AS export-stage
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
ARG DEST_BUILD_DIR="/build"
COPY --from=build-stage /build/release/falco-*.tar.gz /packages/

View File

@@ -1,7 +1,8 @@
ARG FALCO_IMAGE_TAG=latest
FROM falcosecurity/falco:${FALCO_IMAGE_TAG}
FROM docker.io/falcosecurity/falco:${FALCO_IMAGE_TAG}
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"
@@ -10,4 +11,4 @@ ENV HOME /root
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -1,6 +1,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"

View File

@@ -2,6 +2,7 @@ FROM debian:buster
LABEL usage="docker run -i -t -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 --name NAME IMAGE"
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
ARG TARGETARCH

View File

@@ -23,10 +23,14 @@ RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /falco/
FROM debian:11-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 \
&& apt clean -y && rm -rf /var/lib/apt/lists/*
ENV HOST_ROOT /host
ENV HOME /root

View File

@@ -3,6 +3,7 @@ FROM fedora:31
LABEL name="falcosecurity/falco-tester"
LABEL usage="docker run -v /boot:/boot:ro -v /var/run/docker.sock:/var/run/docker.sock -v $PWD/..:/source -v $PWD/build:/build --name <name> falcosecurity/falco-tester test"
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
ARG TARGETARCH

View File

@@ -15,6 +15,7 @@ LABEL "description"="Falco is a security policy engine that monitors system call
LABEL "io.k8s.display-name"="Falco"
LABEL "io.k8s.description"="Falco is a security policy engine that monitors system calls and cloud events, and fires alerts when security policies are violated."
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"

1194
falco.yaml

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
# Falco Roadmap Management Proposal
## Summary
This document proposes the introduction of a structured process for managing Falco's roadmap and implementing related changes in our development process. The goal is to ensure the efficient execution of our roadmap objectives.
### Goals
The pillars of this proposal are:
- Define processes for release cycles and development iterations
- Provide guidelines for planning and prioritizing efforts
- Introduce regular meetings for core maintainers
- Using *GitHub Project* as the primary tool for managing *The Falco Project* roadmap
### Non-Goals
- Providing an exact set of criteria for task prioritization
- Detailing testing procedures
- Providing detailed instructions for GitHub Project usage
- Addressing hotfix releases
### Scope of this Proposal
Primarily, the roadmap targets the planning of Falco development and releases. However, given Falco's dependence on numerous components, it's inevitable that scheduling and planning activities span across multiple repositories. We anticipate that all [core repositories](https://github.com/falcosecurity/evolution#official) will be interconnected with the roadmap, making it comprehensive enough to incorporate items from all related [Falcosecurity repositories](https://github.com/falcosecurity) as necessary.
This proposal does **not apply to hotfix releases** that may happen whenever needed at the maintainers' discretion.
## Release Cycles and Development Iterations
Falco releases happen 3 times per year. Each release cycle completes, respectively, by the end of January, May, and September.
A **release cycle is a 16-week time frame** between two subsequent releases.
Using this schema, in a 52-week calendar year, we allocate 48 weeks for scheduled activities (16 weeks *x* 3 releases), leaving 4 weeks for breaks.
The 16-week release cycle is further divided into three distinct iterations:
| Iteration Name | Duration | Description |
|---------------|----------|-------------|
| Development | 8 weeks | Development phase |
| Stabilization | 4 weeks | Feature completion and bug fixing |
| Release Preparation | 4 weeks | Release preparation, testing, bug fixing, no new feature |
### Targeted Release Date
The final week of the *Release Preparation* should conclude before the *last Monday of the release month* (ie. January/May/September). This *last Monday* is designated as the **targeted release date** (when the release is being published), and the remaining part of the week is considered a break period.
### Milestones
For each release, we create a [GitHub Milestone](https://github.com/falcosecurity/falco/milestones) (whose due date must be equal to the target release date). We use the milestone to collect all items to be tentatively completed within the release.
### Alignment of Falco Components
The release schedule of the [components Falco depends on](https://github.com/falcosecurity/falco/blob/master/RELEASE.md#falco-components-versioning) needs to be synchronized to conform to these stipulations. For instance, a [falcosecurity/libs](https://github.com/falcosecurity/libs) release may be required at least one week prior to the termination of each iteration.
The maintainers are responsible for adapting those components' release schedules and procedures to release cycles and development iterations of Falco. Furthermore, all release processes must be documented and provide clear expectations regarding release dates.
## Project Roadmap
We use the [GitHub Project called *Falco Roadmap*](https://github.com/orgs/falcosecurity/projects/5) to plan and track the progress of each release cycle. The GitHub Project needs to be configured with the above mentioned iterations and break periods, compiled with actual dates. It's recommended to preconfigure the GitHub Project to accommodate the current plus the following three release cycles.
### Roadmap Planning
The roadmap serves as a strategic planning tool that outlines the goals and objectives for Falco. Its purpose is to visually represent the overall direction and timeline, enhance transparency and engage the community.
The onus is on the [Core Maintainers](https://github.com/falcosecurity/evolution/blob/main/GOVERNANCE.md#core-maintainers) to manage the roadmap. In this regard, Core Maintainers meet in **planning sessions on the first week of each calendar month**.
During these planning sessions, tasks are allocated to the current iteration or postponed to one of the following iterations. The assigned iteration indicates the projected completion date for a particular workstream.
When a session matches with the commencement of an iteration, maintainers convene to assess the planning and prioritize tasks for the iteration. The first planning session of a release cycle must define top priorities for the related release.
## Testing and Quality Assurance (QA)
Each iteration's output must include at least one Falco pre-release (or a viable development build) designated for testing and QA activities. While it's acceptable for these builds to contain unfinished features or known bugs, they must enable any community member to contribute to the testing and QA efforts.
The targeted schedule for these Testing/QA activities should be the **last week of each iteration** (or earlier during the *Release Preparation*).
Testing and Quality Assurance criteria and procedures must be defined and documented across relevant repositories.
Furthermore, given the strong reliance of Falco on [falcosecurity/libs](https://github.com/falcosecurity/libs), the above-mentioned pre-release/build for Testing/QA purposes must be based on the most recent *libs* development for the intended iteration. This means that during each interaction, a *libs* release (either pre or stable) must happen early enough to be used for this purpose.
## Next Steps and Conclusions
The Falco 0.36 release cycle, running from June to September 2023, will mark the initiation of the new process. This cycle will also serve as an experimental phase for refining the process.
Furthermore, as soon as possible, we will kick off a Working Group specifically to ensure smooth execution. This group will involve community members in assisting maintainers with roadmap management. It will provide curated feature suggestions for the roadmap, informed by community needs. This approach would facilitate the core maintainers' decisions, as they would mostly need just to review and adopt these pre-vetted recommendations, enhancing efficiency.
The Working Group's responsibilities will include (non-exhaustive list):
- Address input from the [2023-04-27 Core Maintainers meeting](https://github.com/falcosecurity/community/blob/main/meeting-notes/2023-04-27-Falco-Roadmap-Discussion.md)
- Sorting and reviewing pending issues to identify key topics for discussion and potential inclusion in the roadmap
- Establishing protocols not explicitly covered in this document
- Updating the documentation accordingly
- Supporting Core Maintainers in managing the [Falco Roadmap GitHub project](https://github.com/orgs/falcosecurity/projects/5)
- Gathering suggestions from all involved stakeholders to put forward potential enhancements
Finally, we anticipate the need for minor adjustments, which will become apparent only after an initial period of experimentation. Thus we have to intend this process to be flexible enough to adapt to emerging needs and improvements as long as the fundamental spirit of this proposal is upheld.

View File

@@ -128,10 +128,38 @@ get_target_id() {
case "${OS_ID}" in
("amzn")
if [[ $VERSION_ID == "2" ]]; then
case "${VERSION_ID}" in
("2")
TARGET_ID="amazonlinux2"
else
;;
("2022")
TARGET_ID="amazonlinux2022"
;;
("2023")
TARGET_ID="amazonlinux2023"
;;
(*)
TARGET_ID="amazonlinux"
;;
esac
;;
("debian")
# Workaround: debian kernelreleases might now be actual kernel running;
# instead, they might be the Debian kernel package
# providing the compatible kernel ABI
# See https://lists.debian.org/debian-user/2017/03/msg00485.html
# Real kernel release is embedded inside the kernel version.
# Moreover, kernel arch, when present, is attached to the former,
# therefore make sure to properly take it and attach it to the latter.
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
local ARCH_extra=""
if [[ $KERNEL_RELEASE =~ -(amd64|arm64) ]];
then
ARCH_extra="-${BASH_REMATCH[1]}"
fi
if [[ $(uname -v) =~ ([0-9]+\.[0-9]+\.[0-9]+\-[0-9]+) ]];
then
KERNEL_RELEASE="${BASH_REMATCH[1]}${ARCH_extra}"
fi
;;
("ubuntu")
@@ -151,7 +179,7 @@ get_target_id() {
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
("minikube")
TARGET_ID="${OS_ID}"
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
# Extract the minikube version. Ex. With minikube version equal to "v1.26.0-1655407986-14197" the extracted version
# will be "1.26.0"
if [[ $(cat ${HOST_ROOT}/etc/VERSION) =~ ([0-9]+(\.[0-9]+){2}) ]]; then
@@ -163,7 +191,7 @@ get_target_id() {
fi
;;
("bottlerocket")
TARGET_ID="${OS_ID}"
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
# variant_id has been sourced from os-release. Get only the first variant part
if [[ -n ${VARIANT_ID} ]]; then
# take just first part (eg: VARIANT_ID=aws-k8s-1.15 -> aws)
@@ -172,6 +200,11 @@ get_target_id() {
# version_id has been sourced from os-release. Build a kernel version like: 1_1.11.0-aws
KERNEL_VERSION="1_${VERSION_ID}-${VARIANT_ID_CUT}"
;;
("talos")
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
# version_id has been sourced from os-release. Build a kernel version like: 1_1.4.1
KERNEL_VERSION="1_${VERSION_ID}"
;;
(*)
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
@@ -232,10 +265,10 @@ load_kernel_module_compile() {
continue
fi
echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
echo "#!/usr/bin/env bash" > /tmp/falco-dkms-make
echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
chmod +x /tmp/falco-dkms-make
if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "#!/usr/bin/env bash" > "${TMPDIR}/falco-dkms-make"
echo "make CC=${CURRENT_GCC} \$@" >> "${TMPDIR}/falco-dkms-make"
chmod +x "${TMPDIR}/falco-dkms-make"
if dkms install --directive="MAKE='${TMPDIR}/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "* ${DRIVER_NAME} module installed in dkms"
KO_FILE="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}"
if [ -f "$KO_FILE.ko" ]; then
@@ -659,6 +692,8 @@ if [ -v FALCO_BPF_PROBE ]; then
DRIVER="bpf"
fi
TMPDIR=${TMPDIR:-"/tmp"}
ENABLE_COMPILE=
ENABLE_DOWNLOAD=

View File

@@ -624,7 +624,7 @@ trace_files: !mux
disabled_and_enabled_rules_1:
exit_status: 1
stderr_contains: "Runtime error: You can not specify both disabled .-D/-T. and enabled .-t. rules. Exiting."
stderr_contains: "Error: You can not specify both disabled .-D/-T. and enabled .-t. rules"
disable_tags: [a]
run_tags: [a]
rules_file:
@@ -633,7 +633,7 @@ trace_files: !mux
disabled_and_enabled_rules_2:
exit_status: 1
stderr_contains: "Runtime error: You can not specify both disabled .-D/-T. and enabled .-t. rules. Exiting."
stderr_contains: "Error: You can not specify both disabled .-D/-T. and enabled .-t. rules"
disabled_rules:
- "open.*"
run_tags: [a]

View File

@@ -56,7 +56,7 @@ trace_files: !mux
incompatible_extract_sources:
exit_status: 1
stderr_contains: "Plugin '.*' has field extraction capability but is not compatible with any known event source"
stderr_contains: "Plugin '.*' is loaded but unused as not compatible with any known event source"
conf_file: BUILD_DIR/test/confs/plugins/incompatible_extract_sources.yaml
rules_file:
- rules/plugins/cloudtrail_create_instances.yaml

View File

@@ -17,7 +17,7 @@ limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <plugin_info.h>
#include <engine/source_plugin/plugin_info.h>
static const char *pl_required_api_version = PLUGIN_API_VERSION_STR;
static const char *pl_name_base = "test_extract";

View File

@@ -18,7 +18,7 @@ limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <plugin_info.h>
#include <engine/source_plugin/plugin_info.h>
static const char *pl_required_api_version = PLUGIN_API_VERSION_STR;
static uint32_t pl_id = 999;

View File

@@ -6,7 +6,7 @@ idna==2.9
pathtools==0.1.2
pbr==5.4.5
PyYAML==5.4
requests==2.26.0
requests==2.31.0
six==1.14.0
stevedore==1.32.0
urllib3==1.26.5

View File

@@ -1,76 +0,0 @@
#
# Copyright (C) 2019 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.
#
set(
FALCO_TESTS_SOURCES
test_base.cpp
engine/test_rulesets.cpp
engine/test_falco_utils.cpp
engine/test_filter_macro_resolver.cpp
engine/test_filter_evttype_resolver.cpp
engine/test_filter_warning_resolver.cpp
engine/test_plugin_requirements.cpp
falco/test_yaml_helper.cpp
)
set(FALCO_TESTED_LIBRARIES falco_engine ${YAMLCPP_LIB})
SET(FALCO_TESTS_ARGUMENTS "" CACHE STRING "Test arguments to pass to the Falco test suite")
option(FALCO_BUILD_TESTS "Determines whether to build tests." ON)
if(FALCO_BUILD_TESTS)
enable_testing()
if(NOT TARGET catch)
include(DownloadCatch)
endif()
if(NOT TARGET fakeit)
include(DownloadFakeIt)
endif()
add_executable(falco_test ${FALCO_TESTS_SOURCES})
target_link_libraries(falco_test PUBLIC ${FALCO_TESTED_LIBRARIES})
if(MINIMAL_BUILD)
target_include_directories(
falco_test
PUBLIC "${CATCH2_INCLUDE}"
"${FAKEIT_INCLUDE}"
"${PROJECT_SOURCE_DIR}/userspace/engine"
"${PROJECT_BINARY_DIR}/userspace/falco"
"${YAMLCPP_INCLUDE_DIR}"
"${PROJECT_SOURCE_DIR}/userspace/falco")
else()
target_include_directories(
falco_test
PUBLIC "${CATCH2_INCLUDE}"
"${FAKEIT_INCLUDE}"
"${PROJECT_SOURCE_DIR}/userspace/engine"
"${PROJECT_BINARY_DIR}/userspace/falco"
"${YAMLCPP_INCLUDE_DIR}"
"${PROJECT_SOURCE_DIR}/userspace/falco")
endif()
add_dependencies(falco_test catch2)
include(CMakeParseArguments)
include(CTest)
include(Catch)
catch_discover_tests(falco_test)
separate_arguments(FALCO_TESTS_ARGUMENTS)
add_custom_target(tests COMMAND ${CMAKE_CTEST_COMMAND} ${FALCO_TESTS_ARGUMENTS} DEPENDS falco_test)
endif()

View File

@@ -1,2 +0,0 @@
labels:
- area/tests

View File

@@ -1,57 +0,0 @@
# Falco unit tests
This folder contains the unit-tests suite for Falco.
The framework we use for unit-tests is [Catch2](https://github.com/catchorg/Catch2), while the one we use for mocking is [FakeIt](https://github.com/eranpeer/FakeIt).
## How to write tests
When you want to test a new file or test a non tested file, remember four steps:
- The folder structure here is the same as the one in the `userspace` folder, so `userspace/engine` becomes `tests/engine`.
- We call test files with this format `test_<original-file-name>.cpp`
- Update the `CMakeLists.txt` file to include your file in `FALCO_TESTS_SOURCES` and change the `FALCO_TESTED_LIBRARIES` accordingly. You might also need to add dependencies, in that case, look at `target_link_libraries` and `target_include_directories`
- If you are unsure on how to write tests, refer to our existing tests in this folder and to the [Catch2](https://github.com/catchorg/Catch2/tree/master/docs) documentation.
## How to execute tests
The suite can be configured with `cmake` and run with `make`.
In the root folder of Falco, after creating the build directory:
```bash
cd falco
mkdir build
cd build
```
You can prepare the tests with:
```
cmake ..
```
Optionally, you can customize the test suite by passing custom arguments like the examples below:
**filter all tests containing the word ctor**
```bash
cmake -DFALCO_TESTS_ARGUMENTS:STRING="-R ctor" ..
```
**verbose execution**
```bash
cmake -DFALCO_TESTS_ARGUMENTS:STRING="-V" ..
```
To see a list of all the custom arguments you may pass, execute `ctest --help` in your terminal.
Once you are ready, you can run your configuration with:
```bash
make tests
```

View File

@@ -1,52 +0,0 @@
/*
Copyright (C) 2020 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "falco_utils.h"
#include <catch.hpp>
TEST_CASE("is_unix_scheme matches", "[utils]")
{
SECTION("rvalue")
{
bool res = falco::utils::network::is_unix_scheme("unix:///run/falco/falco.sock");
REQUIRE(res);
}
SECTION("std::string")
{
std::string url("unix:///run/falco/falco.sock");
bool res = falco::utils::network::is_unix_scheme(url);
REQUIRE(res);
}
SECTION("char[]")
{
char url[] = "unix:///run/falco/falco.sock";
bool res = falco::utils::network::is_unix_scheme(url);
REQUIRE(res);
}
}
TEST_CASE("is_unix_scheme does not match", "[utils]")
{
bool res = falco::utils::network::is_unix_scheme("something:///run/falco/falco.sock");
REQUIRE_FALSE(res);
}
TEST_CASE("is_unix_scheme only matches scheme at the start of the string", "[utils]")
{
bool res = falco::utils::network::is_unix_scheme("/var/run/unix:///falco.sock");
REQUIRE_FALSE(res);
}

View File

@@ -1,237 +0,0 @@
/*
Copyright (C) 2021 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "filter_evttype_resolver.h"
#include <catch.hpp>
#include <sinsp.h>
#include <filter/parser.h>
using namespace std;
using namespace libsinsp::filter;
string to_string(set<uint16_t> s)
{
string out = "[";
for(auto &val : s)
{
out += out.size() == 1 ? "" : ", ";
out += to_string(val);
}
out += "]";
return out;
}
void compare_evttypes(std::unique_ptr<ast::expr> f, set<uint16_t> &expected)
{
set<uint16_t> actual;
filter_evttype_resolver().evttypes(f.get(), actual);
for(auto &etype : expected)
{
REQUIRE(actual.find(etype) != actual.end());
}
for(auto &etype : actual)
{
REQUIRE(expected.find(etype) != expected.end());
}
}
std::unique_ptr<ast::expr> compile(const string &fltstr)
{
return libsinsp::filter::parser(fltstr).parse();
}
TEST_CASE("Should find event types from filter", "[rule_loader]")
{
set<uint16_t> openat_only{
PPME_SYSCALL_OPENAT_E, PPME_SYSCALL_OPENAT_X,
PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X };
set<uint16_t> close_only{
PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X };
set<uint16_t> openat_close{
PPME_SYSCALL_OPENAT_E, PPME_SYSCALL_OPENAT_X,
PPME_SYSCALL_OPENAT_2_E, PPME_SYSCALL_OPENAT_2_X,
PPME_SYSCALL_CLOSE_E, PPME_SYSCALL_CLOSE_X };
set<uint16_t> not_openat;
set<uint16_t> not_openat_close;
set<uint16_t> not_close;
set<uint16_t> all_events;
set<uint16_t> no_events;
for(uint32_t i = 2; i < PPM_EVENT_MAX; i++)
{
// Skip events that are unused.
if(sinsp::is_unused_event(i))
{
continue;
}
all_events.insert(i);
if(openat_only.find(i) == openat_only.end())
{
not_openat.insert(i);
}
if(openat_close.find(i) == openat_close.end())
{
not_openat_close.insert(i);
}
if (close_only.find(i) == close_only.end())
{
not_close.insert(i);
}
}
SECTION("evt_type_eq")
{
auto f = compile("evt.type=openat");
compare_evttypes(std::move(f), openat_only);
}
SECTION("evt_type_in")
{
auto f = compile("evt.type in (openat, close)");
compare_evttypes(std::move(f), openat_close);
}
SECTION("evt_type_ne")
{
auto f = compile("evt.type!=openat");
compare_evttypes(std::move(f), not_openat);
}
SECTION("not_evt_type_eq")
{
auto f = compile("not evt.type=openat");
compare_evttypes(std::move(f), not_openat);
}
SECTION("not_evt_type_in")
{
auto f = compile("not evt.type in (openat, close)");
compare_evttypes(std::move(f), not_openat_close);
}
SECTION("not_evt_type_ne")
{
auto f = compile("not evt.type != openat");
compare_evttypes(std::move(f), openat_only);
}
SECTION("evt_type_or")
{
auto f = compile("evt.type=openat or evt.type=close");
compare_evttypes(std::move(f), openat_close);
}
SECTION("not_evt_type_or")
{
auto f = compile("evt.type!=openat or evt.type!=close");
compare_evttypes(std::move(f), all_events);
}
SECTION("evt_type_or_ne")
{
auto f = compile("evt.type=close or evt.type!=openat");
compare_evttypes(std::move(f), not_openat);
}
SECTION("evt_type_and")
{
auto f = compile("evt.type=close and evt.type=openat");
compare_evttypes(std::move(f), no_events);
}
SECTION("evt_type_and_non_evt_type")
{
auto f = compile("evt.type=openat and proc.name=nginx");
compare_evttypes(std::move(f), openat_only);
}
SECTION("evt_type_and_non_evt_type_not")
{
auto f = compile("evt.type=openat and not proc.name=nginx");
compare_evttypes(std::move(f), openat_only);
}
SECTION("evt_type_and_nested")
{
auto f = compile("evt.type=openat and (proc.name=nginx)");
compare_evttypes(std::move(f), openat_only);
}
SECTION("evt_type_and_nested_multi")
{
auto f = compile("evt.type=openat and (evt.type=close and proc.name=nginx)");
compare_evttypes(std::move(f), no_events);
}
SECTION("non_evt_type")
{
auto f = compile("proc.name=nginx");
compare_evttypes(std::move(f), all_events);
}
SECTION("non_evt_type_or")
{
auto f = compile("evt.type=openat or proc.name=nginx");
compare_evttypes(std::move(f), all_events);
}
SECTION("non_evt_type_or_nested_first")
{
auto f = compile("(evt.type=openat) or proc.name=nginx");
compare_evttypes(std::move(f), all_events);
}
SECTION("non_evt_type_or_nested_second")
{
auto f = compile("evt.type=openat or (proc.name=nginx)");
compare_evttypes(std::move(f), all_events);
}
SECTION("non_evt_type_or_nested_multi")
{
auto f = compile("evt.type=openat or (evt.type=close and proc.name=nginx)");
compare_evttypes(std::move(f), openat_close);
}
SECTION("non_evt_type_or_nested_multi_not")
{
auto f = compile("evt.type=openat or not (evt.type=close and proc.name=nginx)");
compare_evttypes(std::move(f), not_close);
}
SECTION("non_evt_type_and_nested_multi_not")
{
auto f = compile("evt.type=openat and not (evt.type=close and proc.name=nginx)");
compare_evttypes(std::move(f), openat_only);
}
SECTION("ne_and_and")
{
auto f = compile("evt.type!=openat and evt.type!=close");
compare_evttypes(std::move(f), not_openat_close);
}
SECTION("not_not")
{
auto f = compile("not (not evt.type=openat)");
compare_evttypes(std::move(f), openat_only);
}
}

View File

@@ -1,298 +0,0 @@
/*
Copyright (C) 2020 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "filter_macro_resolver.h"
#include <catch.hpp>
using namespace std;
using namespace 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)
{
return std::find_if(
values.begin(),
values.end(),
[&ref](const filter_macro_resolver::value_info& v) { return v.first == ref; });
}
TEST_CASE("Should resolve macros on a filter AST", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos(12, 85, 27);
SECTION("in the general case")
{
std::shared_ptr<expr> macro = std::move(
unary_check_expr::create("test.field", "", "exists"));
std::vector<std::unique_ptr<expr>> filter_and;
filter_and.push_back(unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(not_expr::create(value_expr::create(macro_name, macro_pos)));
std::shared_ptr<expr> filter = std::move(and_expr::create(filter_and));
std::vector<std::unique_ptr<expr>> expected_and;
expected_and.push_back(unary_check_expr::create("evt.name", "", "exists"));
expected_and.push_back(not_expr::create(clone(macro.get())));
std::shared_ptr<expr> expected = std::move(and_expr::create(expected_and));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected.get()));
// second run
REQUIRE(resolver.run(filter) == false);
REQUIRE(resolver.get_resolved_macros().empty());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected.get()));
}
SECTION("with a single node")
{
std::shared_ptr<expr> macro = std::move(
unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
// first run
expr* old_filter_ptr = filter.get();
REQUIRE(resolver.run(filter) == true);
REQUIRE(filter.get() != old_filter_ptr);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(macro.get()));
// second run
old_filter_ptr = filter.get();
REQUIRE(resolver.run(filter) == false);
REQUIRE(filter.get() == old_filter_ptr);
REQUIRE(resolver.get_resolved_macros().empty());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(macro.get()));
}
SECTION("with multiple macros")
{
string a_macro_name = macro_name + "_1";
string b_macro_name = macro_name + "_2";
pos_info a_macro_pos(11, 75, 43);
pos_info b_macro_pos(91, 21, 9);
std::shared_ptr<expr> a_macro = std::move(
unary_check_expr::create("one.field", "", "exists"));
std::shared_ptr<expr> b_macro = std::move(
unary_check_expr::create("another.field", "", "exists"));
std::vector<std::unique_ptr<expr>> filter_or;
filter_or.push_back(value_expr::create(a_macro_name, a_macro_pos));
filter_or.push_back(value_expr::create(b_macro_name, b_macro_pos));
std::shared_ptr<expr> filter = std::move(or_expr::create(filter_or));
std::vector<std::unique_ptr<expr>> expected_or;
expected_or.push_back(clone(a_macro.get()));
expected_or.push_back(clone(b_macro.get()));
std::shared_ptr<expr> expected_filter = std::move(or_expr::create(expected_or));
filter_macro_resolver resolver;
resolver.set_macro(a_macro_name, a_macro);
resolver.set_macro(b_macro_name, b_macro);
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 2);
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), a_macro_name);
REQUIRE(a_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(a_resolved_itr->first == a_macro_name);
REQUIRE(a_resolved_itr->second == a_macro_pos);
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), b_macro_name);
REQUIRE(b_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(b_resolved_itr->first == b_macro_name);
REQUIRE(b_resolved_itr->second == b_macro_pos);
REQUIRE(filter->is_equal(expected_filter.get()));
// second run
REQUIRE(resolver.run(filter) == false);
REQUIRE(resolver.get_resolved_macros().empty());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected_filter.get()));
}
SECTION("with nested macros")
{
string a_macro_name = macro_name + "_1";
string b_macro_name = macro_name + "_2";
pos_info a_macro_pos(47, 1, 76);
pos_info b_macro_pos(111, 65, 2);
std::vector<std::unique_ptr<expr>> a_macro_and;
a_macro_and.push_back(unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(value_expr::create(b_macro_name, b_macro_pos));
std::shared_ptr<expr> a_macro = std::move(and_expr::create(a_macro_and));
std::shared_ptr<expr> b_macro = std::move(
unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<expr> filter = std::move(value_expr::create(a_macro_name, a_macro_pos));
std::vector<std::unique_ptr<expr>> expected_and;
expected_and.push_back(unary_check_expr::create("one.field", "", "exists"));
expected_and.push_back(unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<expr> expected_filter = std::move(and_expr::create(expected_and));
filter_macro_resolver resolver;
resolver.set_macro(a_macro_name, a_macro);
resolver.set_macro(b_macro_name, b_macro);
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 2);
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), a_macro_name);
REQUIRE(a_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(a_resolved_itr->first == a_macro_name);
REQUIRE(a_resolved_itr->second == a_macro_pos);
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), b_macro_name);
REQUIRE(b_resolved_itr != resolver.get_resolved_macros().end());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(b_resolved_itr->first == b_macro_name);
REQUIRE(b_resolved_itr->second == b_macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected_filter.get()));
// second run
REQUIRE(resolver.run(filter) == false);
REQUIRE(resolver.get_resolved_macros().empty());
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(expected_filter.get()));
}
}
TEST_CASE("Should find unknown macros", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos(9, 4, 2);
SECTION("in the general case")
{
std::vector<std::unique_ptr<expr>> filter_and;
filter_and.push_back(unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(not_expr::create(value_expr::create(macro_name, macro_pos)));
std::shared_ptr<expr> filter = std::move(and_expr::create(filter_and));
filter_macro_resolver resolver;
REQUIRE(resolver.run(filter) == false);
REQUIRE(resolver.get_unknown_macros().size() == 1);
REQUIRE(resolver.get_unknown_macros().begin()->first == macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_resolved_macros().empty());
}
SECTION("with nested macros")
{
string a_macro_name = macro_name + "_1";
string b_macro_name = macro_name + "_2";
pos_info a_macro_pos(32, 84, 9);
pos_info b_macro_pos(1, 0, 5);
std::vector<std::unique_ptr<expr>> a_macro_and;
a_macro_and.push_back(unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(value_expr::create(b_macro_name, b_macro_pos));
std::shared_ptr<expr> a_macro = std::move(and_expr::create(a_macro_and));
std::shared_ptr<expr> filter = std::move(value_expr::create(a_macro_name, a_macro_pos));
auto expected_filter = clone(a_macro.get());
filter_macro_resolver resolver;
resolver.set_macro(a_macro_name, a_macro);
// first run
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(resolver.get_resolved_macros().begin()->first == a_macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == a_macro_pos);
REQUIRE(resolver.get_unknown_macros().size() == 1);
REQUIRE(resolver.get_unknown_macros().begin()->first == b_macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->second == b_macro_pos);
REQUIRE(filter->is_equal(expected_filter.get()));
}
}
TEST_CASE("Should undefine macro", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos_1(12, 9, 3);
pos_info macro_pos_2(9, 6, 3);
std::shared_ptr<expr> macro = std::move(unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<expr> a_filter = std::move(value_expr::create(macro_name, macro_pos_1));
std::shared_ptr<expr> b_filter = std::move(value_expr::create(macro_name, macro_pos_2));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
REQUIRE(resolver.run(a_filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos_1);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(a_filter->is_equal(macro.get()));
resolver.set_macro(macro_name, NULL);
REQUIRE(resolver.run(b_filter) == false);
REQUIRE(resolver.get_resolved_macros().empty());
REQUIRE(resolver.get_unknown_macros().size() == 1);
REQUIRE(resolver.get_unknown_macros().begin()->first == macro_name);
REQUIRE(resolver.get_unknown_macros().begin()->second == macro_pos_2);
}
// checks that the macro AST is cloned and not shared across resolved filters
TEST_CASE("Should clone macro AST", "[rule_loader]")
{
string macro_name = "test_macro";
pos_info macro_pos(5, 2, 8888);
std::shared_ptr<unary_check_expr> macro = std::move(unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<expr> filter = std::move(value_expr::create(macro_name, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(macro_name, macro);
REQUIRE(resolver.run(filter) == true);
REQUIRE(resolver.get_resolved_macros().size() == 1);
REQUIRE(resolver.get_resolved_macros().begin()->first == macro_name);
REQUIRE(resolver.get_resolved_macros().begin()->second == macro_pos);
REQUIRE(resolver.get_unknown_macros().empty());
REQUIRE(filter->is_equal(macro.get()));
macro->field = "another.field";
REQUIRE(!filter->is_equal(macro.get()));
}

View File

@@ -1,45 +0,0 @@
/*
Copyright (C) 2020 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "filter_warning_resolver.h"
#include <catch.hpp>
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_CASE("Should spot warnings in filtering conditions", "[rule_loader]")
{
SECTION("for unsafe usage of <NA> in k8s audit fields")
{
REQUIRE(false == warns("ka.field exists"));
REQUIRE(false == warns("some.field = <NA>"));
REQUIRE(true == warns("jevt.field = <NA>"));
REQUIRE(true == warns("ka.field = <NA>"));
REQUIRE(true == warns("ka.field == <NA>"));
REQUIRE(true == warns("ka.field != <NA>"));
REQUIRE(true == warns("ka.field in (<NA>)"));
REQUIRE(true == warns("ka.field in (otherval, <NA>)"));
REQUIRE(true == warns("ka.field intersects (<NA>)"));
REQUIRE(true == warns("ka.field intersects (otherval, <NA>)"));
REQUIRE(true == warns("ka.field pmatch (<NA>)"));
REQUIRE(true == warns("ka.field pmatch (otherval, <NA>)"));
}
}

View File

@@ -1,269 +0,0 @@
/*
Copyright (C) 2022 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.
*/
#include <memory>
#include <catch.hpp>
#include "falco_engine.h"
static void check_requirements(
bool expect_success,
const std::vector<falco_engine::plugin_version_requirement>& plugins,
const std::string& ruleset_content)
{
std::string err;
std::unique_ptr<falco_engine> e(new falco_engine());
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 (expect_success)
{
FAIL(res->as_string(false, c));
}
return;
}
if (!e->check_plugin_requirements(plugins, err))
{
if (expect_success)
{
FAIL(err);
}
}
else if (!expect_success)
{
FAIL("unexpected successful plugin requirements check");
}
}
TEST_CASE("check_plugin_requirements must accept", "[rule_loader]")
{
SECTION("no requirement")
{
check_requirements(true, {{"k8saudit", "0.1.0"}}, "");
}
SECTION("single plugin")
{
check_requirements(true, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
)");
}
SECTION("single plugin newer version")
{
check_requirements(true, {{"k8saudit", "0.2.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
)");
}
SECTION("multiple plugins")
{
check_requirements(true, {{"k8saudit", "0.1.0"}, {"json", "0.3.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- name: json
version: 0.3.0
)");
}
SECTION("single plugin multiple versions")
{
check_requirements(true, {{"k8saudit", "0.2.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 0.2.0
)");
}
SECTION("single plugin with alternatives")
{
check_requirements(true, {{"k8saudit-other", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
)");
}
SECTION("multiple plugins with alternatives")
{
check_requirements(true, {{"k8saudit-other", "0.5.0"}, {"json2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
)");
}
SECTION("multiple plugins with alternatives with multiple versions")
{
check_requirements(true, {{"k8saudit-other", "0.7.0"}, {"json2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 1.0.0
alternatives:
- name: k8saudit-other
version: 0.7.0
)");
}
}
TEST_CASE("check_plugin_requirements must reject", "[rule_loader]")
{
SECTION("no plugin loaded")
{
check_requirements(false, {}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
)");
}
SECTION("single plugin wrong name")
{
check_requirements(false, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit2
version: 0.1.0
)");
}
SECTION("single plugin wrong version")
{
check_requirements(false, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.2.0
)");
}
SECTION("multiple plugins")
{
check_requirements(false, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- name: json
version: 0.3.0
)");
}
SECTION("single plugin multiple versions")
{
check_requirements(false, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 0.2.0
)");
}
SECTION("single plugin with alternatives")
{
check_requirements(false, {{"k8saudit2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
)");
}
SECTION("single plugin with overlapping alternatives")
{
check_requirements(false, {{"k8saudit", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit
version: 0.4.0
)");
}
SECTION("multiple plugins with alternatives")
{
check_requirements(false, {{"k8saudit-other", "0.5.0"}, {"json3", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
)");
}
SECTION("multiple plugins with alternatives with multiple versions")
{
check_requirements(false, {{"k8saudit", "0.7.0"}, {"json2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.4.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 1.0.0
alternatives:
- name: k8saudit-other
version: 0.7.0
)");
}
}

View File

@@ -1,242 +0,0 @@
/*
Copyright (C) 2020 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "falco_common.h"
#include "evttype_index_ruleset.h"
#include <filter.h>
#include <catch.hpp>
static bool exact_match = true;
static bool substring_match = false;
static uint16_t default_ruleset = 0;
static uint16_t non_default_ruleset = 3;
static uint16_t other_non_default_ruleset = 2;
static std::set<std::string> tags = {"some_tag", "some_other_tag"};
static std::set<uint16_t> evttypes = { ppm_event_type::PPME_GENERIC_E };
static std::shared_ptr<gen_event_filter_factory> create_factory()
{
std::shared_ptr<gen_event_filter_factory> ret(new sinsp_filter_factory(NULL));
return ret;
}
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(
std::shared_ptr<gen_event_filter_factory> f)
{
libsinsp::filter::parser parser("evt.type=open");
std::shared_ptr<libsinsp::filter::ast::expr> ret(parser.parse());
return ret;
}
static std::shared_ptr<gen_event_filter> create_filter(
std::shared_ptr<gen_event_filter_factory> f,
std::shared_ptr<libsinsp::filter::ast::expr> ast)
{
sinsp_filter_compiler compiler(f, ast.get());
std::shared_ptr<gen_event_filter> filter(compiler.compile());
return filter;
}
static std::shared_ptr<filter_ruleset> create_ruleset(
std::shared_ptr<gen_event_filter_factory> f)
{
std::shared_ptr<filter_ruleset> ret(new evttype_index_ruleset(f));
return ret;
}
TEST_CASE("Should enable/disable on ruleset", "[rulesets]")
{
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto filter = create_filter(f, ast);
falco_rule rule;
rule.name = "one_rule";
rule.source = falco_common::syscall_source;
rule.tags = tags;
r->add(rule, filter, ast);
SECTION("Should enable/disable for exact match w/ default ruleset")
{
r->enable("one_rule", exact_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable("one_rule", exact_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for exact match w/ specific ruleset")
{
r->enable("one_rule", exact_match, non_default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 1);
REQUIRE(r->enabled_count(default_ruleset) == 0);
REQUIRE(r->enabled_count(other_non_default_ruleset) == 0);
r->disable("one_rule", exact_match, non_default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 0);
REQUIRE(r->enabled_count(default_ruleset) == 0);
REQUIRE(r->enabled_count(other_non_default_ruleset) == 0);
}
SECTION("Should not enable for exact match different rule name")
{
r->enable("some_other_rule", exact_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for exact match w/ substring and default ruleset")
{
r->enable("one_rule", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable("one_rule", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should not enable for substring w/ exact_match")
{
r->enable("one_", exact_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for prefix match w/ default ruleset")
{
r->enable("one_", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable("one_", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for suffix match w/ default ruleset")
{
r->enable("_rule", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable("_rule", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for substring match w/ default ruleset")
{
r->enable("ne_ru", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable("ne_ru", substring_match, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for substring match w/ specific ruleset")
{
r->enable("ne_ru", substring_match, non_default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 1);
REQUIRE(r->enabled_count(default_ruleset) == 0);
REQUIRE(r->enabled_count(other_non_default_ruleset) == 0);
r->disable("ne_ru", substring_match, non_default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 0);
REQUIRE(r->enabled_count(default_ruleset) == 0);
REQUIRE(r->enabled_count(other_non_default_ruleset) == 0);
}
SECTION("Should enable/disable for tags w/ default ruleset")
{
std::set<std::string> want_tags = {"some_tag"};
r->enable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
SECTION("Should enable/disable for tags w/ specific ruleset")
{
std::set<std::string> want_tags = {"some_tag"};
r->enable_tags(want_tags, non_default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 1);
REQUIRE(r->enabled_count(default_ruleset) == 0);
REQUIRE(r->enabled_count(other_non_default_ruleset) == 0);
r->disable_tags(want_tags, non_default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 0);
REQUIRE(r->enabled_count(default_ruleset) == 0);
REQUIRE(r->enabled_count(other_non_default_ruleset) == 0);
}
SECTION("Should not enable for different tags")
{
std::set<std::string> want_tags = {"some_different_tag"};
r->enable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(non_default_ruleset) == 0);
}
SECTION("Should enable/disable for overlapping tags")
{
std::set<std::string> want_tags = {"some_tag", "some_different_tag"};
r->enable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
r->disable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}
}
TEST_CASE("Should enable/disable on ruleset for incremental adding tags", "[rulesets]")
{
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto rule1_filter = create_filter(f, ast);
falco_rule rule1;
rule1.name = "one_rule";
rule1.source = falco_common::syscall_source;
rule1.tags = {"rule1_tag"};
r->add(rule1, rule1_filter, ast);
auto rule2_filter = create_filter(f, ast);
falco_rule rule2;
rule2.name = "two_rule";
rule2.source = falco_common::syscall_source;
rule2.tags = {"rule2_tag"};
r->add(rule2, rule2_filter, ast);
std::set<std::string> want_tags;
want_tags = rule1.tags;
r->enable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
want_tags = rule2.tags;
r->enable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 2);
r->disable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 1);
want_tags = rule1.tags;
r->disable_tags(want_tags, default_ruleset);
REQUIRE(r->enabled_count(default_ruleset) == 0);
}

View File

@@ -1,106 +0,0 @@
/*
Copyright (C) 2021 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "configuration.h"
#include <catch.hpp>
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"
;
TEST_CASE("configuration must load YAML data", "[configuration]")
{
yaml_helper conf;
SECTION("broken YAML")
{
string sample_broken_yaml = sample_yaml + " / bad_symbol";
REQUIRE_THROWS(conf.load_from_string(sample_broken_yaml));
}
SECTION("valid YAML")
{
REQUIRE_NOTHROW(conf.load_from_string(sample_yaml));
}
SECTION("clearing and reloading")
{
conf.load_from_string(sample_yaml);
REQUIRE(conf.is_defined("base_value") == true);
conf.clear();
REQUIRE(conf.is_defined("base_value") == false);
conf.load_from_string(sample_yaml);
REQUIRE(conf.is_defined("base_value") == true);
}
}
TEST_CASE("configuration must read YAML fields", "[configuration]")
{
yaml_helper conf;
conf.load_from_string(sample_yaml);
SECTION("base level")
{
REQUIRE(conf.is_defined("base_value") == true);
REQUIRE(conf.is_defined("base_value_2") == true);
REQUIRE(conf.is_defined("unknown_base_value") == false);
}
SECTION("arbitrary depth nesting")
{
REQUIRE(conf.get_scalar<int>("base_value.id", -1) == 1);
REQUIRE(conf.get_scalar<string>("base_value.name", "none") == "sample_name");
REQUIRE(conf.get_scalar<bool>("base_value.subvalue.subvalue2.boolean", false) == true);
}
SECTION("list field elements")
{
REQUIRE(conf.get_scalar<string>("base_value_2.sample_list[0]", "none") == "elem1");
REQUIRE(conf.get_scalar<string>("base_value_2.sample_list[1]", "none") == "elem2");
REQUIRE(conf.get_scalar<string>("base_value_2.sample_list[2]", "none") == "elem3");
}
SECTION("sequence")
{
vector<string> seq;
conf.get_sequence(seq, "base_value_2.sample_list");
REQUIRE(seq.size() == 3);
REQUIRE(seq[0] == "elem1");
REQUIRE(seq[1] == "elem2");
REQUIRE(seq[2] == "elem3");
}
}
TEST_CASE("configuration must modify YAML fields", "[configuration]")
{
string key = "base_value.subvalue.subvalue2.boolean";
yaml_helper conf;
conf.load_from_string(sample_yaml);
REQUIRE(conf.get_scalar<bool>(key, false) == true);
conf.set_scalar<bool>(key, false);
REQUIRE(conf.get_scalar<bool>(key, true) == false);
conf.set_scalar<bool>(key, true);
REQUIRE(conf.get_scalar<bool>(key, false) == true);
}

64
unit_tests/CMakeLists.txt Normal file
View File

@@ -0,0 +1,64 @@
#
# 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.
#
message(STATUS "Falco unit tests build enabled")
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG release-1.12.1
)
FetchContent_MakeAvailable(googletest)
file(GLOB_RECURSE ENGINE_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/engine/*.cpp)
file(GLOB_RECURSE FALCO_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/falco/*.cpp)
set(FALCO_UNIT_TESTS_SOURCES
"${ENGINE_TESTS}"
"${FALCO_TESTS}"
)
set(FALCO_UNIT_TESTS_INCLUDES
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
)
set(FALCO_UNIT_TESTS_DEPENDENCIES
gtest
gtest_main
falco_application
)
get_target_property(FALCO_APPLICATION_LIBRARIES falco_application LINK_LIBRARIES)
set(FALCO_UNIT_TESTS_LIBRARIES
gtest
gtest_main
falco_application
${FALCO_APPLICATION_LIBRARIES}
)
message(STATUS "FALCO_UNIT_TESTS_SOURCES: ${FALCO_UNIT_TESTS_SOURCES}")
message(STATUS "FALCO_UNIT_TESTS_INCLUDES: ${FALCO_UNIT_TESTS_INCLUDES}")
message(STATUS "FALCO_UNIT_TESTS_DEPENDENCIES: ${FALCO_UNIT_TESTS_DEPENDENCIES}")
message(STATUS "FALCO_UNIT_TESTS_LIBRARIES: ${FALCO_UNIT_TESTS_LIBRARIES}")
add_executable(falco_unit_tests ${FALCO_UNIT_TESTS_SOURCES})
target_include_directories(falco_unit_tests ${FALCO_UNIT_TESTS_INCLUDES})
target_link_libraries(falco_unit_tests ${FALCO_UNIT_TESTS_LIBRARIES})
add_dependencies(falco_unit_tests ${FALCO_UNIT_TESTS_DEPENDENCIES})

13
unit_tests/README.md Normal file
View File

@@ -0,0 +1,13 @@
# Falco unit tests
## Intro
Under `unit_tests/engine` and `unit_tests/falco` directories, we have different test suites that could be a single file or an entire directory according to the number and the complexity of tests.
## Build and Run
```bash
cmake -DMINIMAL_BUILD=On -DBUILD_BPF=Off -DBUILD_DRIVER=Off -DBUILD_FALCO_UNIT_TESTS=On ..
make falco_unit_tests
sudo ./unit_tests/falco_unit_tests
```

View File

@@ -0,0 +1,70 @@
/*
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.
*/
#include <gtest/gtest.h>
#include <engine/falco_utils.h>
TEST(FalcoUtils, is_unix_scheme)
{
/* Wrong prefix */
ASSERT_EQ(falco::utils::network::is_unix_scheme("something:///run/falco/falco.sock"), false);
/* Similar prefix, but wrong */
ASSERT_EQ(falco::utils::network::is_unix_scheme("unix///falco.sock"), false);
/* Right prefix, passed as an `rvalue` */
ASSERT_EQ(falco::utils::network::is_unix_scheme("unix:///falco.sock"), true);
/* Right prefix, passed as a `std::string` */
std::string url_string("unix:///falco.sock");
ASSERT_EQ(falco::utils::network::is_unix_scheme(url_string), true);
/* Right prefix, passed as a `char[]` */
char url_char[] = "unix:///falco.sock";
ASSERT_EQ(falco::utils::network::is_unix_scheme(url_char), true);
}
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("1y"), 31536000000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("300ms"), 300UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("255s"), 255000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("5m"), 300000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("15m"), 900000UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("30m"), 1800000UL);
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"), 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);
ASSERT_EQ(falco::utils::parse_prometheus_interval("200"), 200UL);
/* Invalid, non prometheus compliant time ordering will result in 0ms. */
ASSERT_EQ(falco::utils::parse_prometheus_interval("1ms1y"), 0UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1t1y"), 0UL);
ASSERT_EQ(falco::utils::parse_prometheus_interval("1t"), 0UL);
}

View File

@@ -0,0 +1,49 @@
/*
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 ASSERT_EQd 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 <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);
// 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 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());
}

View File

@@ -0,0 +1,278 @@
/*
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 ASSERT_EQd 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 <gtest/gtest.h>
#include <engine/filter_macro_resolver.h>
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)
{
return std::find_if(
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)
{
libsinsp::filter::ast::pos_info macro_pos(12, 85, 27);
std::shared_ptr<libsinsp::filter::ast::expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> filter_and;
filter_and.push_back(libsinsp::filter::ast::unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(libsinsp::filter::ast::not_expr::create(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos)));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::and_expr::create(filter_and));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> expected_and;
expected_and.push_back(libsinsp::filter::ast::unary_check_expr::create("evt.name", "", "exists"));
expected_and.push_back(libsinsp::filter::ast::not_expr::create(clone(macro.get())));
std::shared_ptr<libsinsp::filter::ast::expr> expected = std::move(libsinsp::filter::ast::and_expr::create(expected_and));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
// first run
ASSERT_TRUE(resolver.run(filter));
ASSERT_EQ(resolver.get_resolved_macros().size(), 1);
ASSERT_STREQ(resolver.get_resolved_macros().begin()->first.c_str(), MACRO_NAME);
ASSERT_EQ(resolver.get_resolved_macros().begin()->second, macro_pos);
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(expected.get()));
// second run
ASSERT_FALSE(resolver.run(filter));
ASSERT_TRUE(resolver.get_resolved_macros().empty());
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(expected.get()));
}
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_single_node)
{
libsinsp::filter::ast::pos_info macro_pos(12, 85, 27);
std::shared_ptr<libsinsp::filter::ast::expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
// first run
libsinsp::filter::ast::expr* old_filter_ptr = filter.get();
ASSERT_TRUE(resolver.run(filter));
ASSERT_NE(filter.get(), old_filter_ptr);
ASSERT_EQ(resolver.get_resolved_macros().size(), 1);
ASSERT_STREQ(resolver.get_resolved_macros().begin()->first.c_str(), MACRO_NAME);
ASSERT_EQ(resolver.get_resolved_macros().begin()->second, macro_pos);
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(macro.get()));
// second run
old_filter_ptr = filter.get();
ASSERT_FALSE(resolver.run(filter));
ASSERT_EQ(filter.get(), old_filter_ptr);
ASSERT_TRUE(resolver.get_resolved_macros().empty());
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(macro.get()));
}
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_multiple_macros)
{
libsinsp::filter::ast::pos_info a_macro_pos(11, 75, 43);
libsinsp::filter::ast::pos_info b_macro_pos(91, 21, 9);
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = std::move(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> b_macro = std::move(libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists"));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> filter_or;
filter_or.push_back(libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos));
filter_or.push_back(libsinsp::filter::ast::value_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::or_expr::create(filter_or));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> expected_or;
expected_or.push_back(clone(a_macro.get()));
expected_or.push_back(clone(b_macro.get()));
std::shared_ptr<libsinsp::filter::ast::expr> expected_filter = std::move(libsinsp::filter::ast::or_expr::create(expected_or));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_A_NAME, a_macro);
resolver.set_macro(MACRO_B_NAME, b_macro);
// first run
ASSERT_TRUE(resolver.run(filter));
ASSERT_EQ(resolver.get_resolved_macros().size(), 2);
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), MACRO_A_NAME);
ASSERT_NE(a_resolved_itr, resolver.get_resolved_macros().end());
ASSERT_STREQ(a_resolved_itr->first.c_str(), MACRO_A_NAME);
ASSERT_EQ(a_resolved_itr->second, a_macro_pos);
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), MACRO_B_NAME);
ASSERT_NE(b_resolved_itr, resolver.get_resolved_macros().end());
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_STREQ(b_resolved_itr->first.c_str(), MACRO_B_NAME);
ASSERT_EQ(b_resolved_itr->second, b_macro_pos);
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
// second run
ASSERT_FALSE(resolver.run(filter));
ASSERT_TRUE(resolver.get_resolved_macros().empty());
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
}
TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_nested_macros)
{
libsinsp::filter::ast::pos_info a_macro_pos(47, 1, 76);
libsinsp::filter::ast::pos_info b_macro_pos(111, 65, 2);
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> a_macro_and;
a_macro_and.push_back(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(libsinsp::filter::ast::value_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = std::move(libsinsp::filter::ast::and_expr::create(a_macro_and));
std::shared_ptr<libsinsp::filter::ast::expr> b_macro = std::move(
libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> expected_and;
expected_and.push_back(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
expected_and.push_back(libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> expected_filter = std::move(libsinsp::filter::ast::and_expr::create(expected_and));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_A_NAME, a_macro);
resolver.set_macro(MACRO_B_NAME, b_macro);
// first run
ASSERT_TRUE(resolver.run(filter));
ASSERT_EQ(resolver.get_resolved_macros().size(), 2);
auto a_resolved_itr = find_value(resolver.get_resolved_macros(), MACRO_A_NAME);
ASSERT_NE(a_resolved_itr, resolver.get_resolved_macros().end());
ASSERT_STREQ(a_resolved_itr->first.c_str(), MACRO_A_NAME);
ASSERT_EQ(a_resolved_itr->second, a_macro_pos);
auto b_resolved_itr = find_value(resolver.get_resolved_macros(), MACRO_B_NAME);
ASSERT_NE(b_resolved_itr, resolver.get_resolved_macros().end());
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_STREQ(b_resolved_itr->first.c_str(), MACRO_B_NAME);
ASSERT_EQ(b_resolved_itr->second, b_macro_pos);
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
// second run
ASSERT_FALSE(resolver.run(filter));
ASSERT_TRUE(resolver.get_resolved_macros().empty());
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
}
TEST(MacroResolver, should_find_unknown_macros)
{
libsinsp::filter::ast::pos_info macro_pos(9, 4, 2);
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> filter_and;
filter_and.push_back(libsinsp::filter::ast::unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(libsinsp::filter::ast::not_expr::create(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos)));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::and_expr::create(filter_and));
filter_macro_resolver resolver;
ASSERT_FALSE(resolver.run(filter));
ASSERT_EQ(resolver.get_unknown_macros().size(), 1);
ASSERT_STREQ(resolver.get_unknown_macros().begin()->first.c_str(), MACRO_NAME);
ASSERT_EQ(resolver.get_unknown_macros().begin()->second, macro_pos);
ASSERT_TRUE(resolver.get_resolved_macros().empty());
}
TEST(MacroResolver, should_find_unknown_nested_macros)
{
libsinsp::filter::ast::pos_info a_macro_pos(32, 84, 9);
libsinsp::filter::ast::pos_info b_macro_pos(1, 0, 5);
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> a_macro_and;
a_macro_and.push_back(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(libsinsp::filter::ast::value_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = std::move(libsinsp::filter::ast::and_expr::create(a_macro_and));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos));
auto expected_filter = clone(a_macro.get());
filter_macro_resolver resolver;
resolver.set_macro(MACRO_A_NAME, a_macro);
ASSERT_TRUE(resolver.run(filter));
ASSERT_EQ(resolver.get_resolved_macros().size(), 1);
ASSERT_STREQ(resolver.get_resolved_macros().begin()->first.c_str(), MACRO_A_NAME);
ASSERT_EQ(resolver.get_resolved_macros().begin()->second, a_macro_pos);
ASSERT_EQ(resolver.get_unknown_macros().size(), 1);
ASSERT_STREQ(resolver.get_unknown_macros().begin()->first.c_str(), MACRO_B_NAME);
ASSERT_EQ(resolver.get_unknown_macros().begin()->second, b_macro_pos);
ASSERT_TRUE(filter->is_equal(expected_filter.get()));
}
TEST(MacroResolver, should_undefine_macro)
{
libsinsp::filter::ast::pos_info macro_pos_1(12, 9, 3);
libsinsp::filter::ast::pos_info macro_pos_2(9, 6, 3);
std::shared_ptr<libsinsp::filter::ast::expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> a_filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos_1));
std::shared_ptr<libsinsp::filter::ast::expr> b_filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos_2));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
ASSERT_TRUE(resolver.run(a_filter));
ASSERT_EQ(resolver.get_resolved_macros().size(), 1);
ASSERT_STREQ(resolver.get_resolved_macros().begin()->first.c_str(), MACRO_NAME);
ASSERT_EQ(resolver.get_resolved_macros().begin()->second, macro_pos_1);
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(a_filter->is_equal(macro.get()));
resolver.set_macro(MACRO_NAME, NULL);
ASSERT_FALSE(resolver.run(b_filter));
ASSERT_TRUE(resolver.get_resolved_macros().empty());
ASSERT_EQ(resolver.get_unknown_macros().size(), 1);
ASSERT_STREQ(resolver.get_unknown_macros().begin()->first.c_str(), MACRO_NAME);
ASSERT_EQ(resolver.get_unknown_macros().begin()->second, macro_pos_2);
}
/* checks that the macro AST is cloned and not shared across resolved filters */
TEST(MacroResolver, should_clone_macro_AST)
{
libsinsp::filter::ast::pos_info macro_pos(5, 2, 8888);
std::shared_ptr<libsinsp::filter::ast::unary_check_expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
ASSERT_TRUE(resolver.run(filter));
ASSERT_EQ(resolver.get_resolved_macros().size(), 1);
ASSERT_STREQ(resolver.get_resolved_macros().begin()->first.c_str(), MACRO_NAME);
ASSERT_EQ(resolver.get_resolved_macros().begin()->second, macro_pos);
ASSERT_TRUE(resolver.get_unknown_macros().empty());
ASSERT_TRUE(filter->is_equal(macro.get()));
macro->field = "another.field";
ASSERT_FALSE(filter->is_equal(macro.get()));
}

View File

@@ -0,0 +1,42 @@
/*
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 ASSERTd 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 <gtest/gtest.h>
#include <engine/filter_warning_resolver.h>
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)
{
ASSERT_FALSE(warns("ka.field exists"));
ASSERT_FALSE(warns("some.field = <NA>"));
ASSERT_TRUE(warns("jevt.field = <NA>"));
ASSERT_TRUE(warns("ka.field = <NA>"));
ASSERT_TRUE(warns("ka.field == <NA>"));
ASSERT_TRUE(warns("ka.field != <NA>"));
ASSERT_TRUE(warns("ka.field in (<NA>)"));
ASSERT_TRUE(warns("ka.field in (otherval, <NA>)"));
ASSERT_TRUE(warns("ka.field intersects (<NA>)"));
ASSERT_TRUE(warns("ka.field intersects (otherval, <NA>)"));
ASSERT_TRUE(warns("ka.field pmatch (<NA>)"));
ASSERT_TRUE(warns("ka.field pmatch (otherval, <NA>)"));
}

View File

@@ -0,0 +1,238 @@
/*
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.
*/
#include <memory>
#include <engine/falco_engine.h>
#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)
{
std::unique_ptr<falco_engine> e(new falco_engine());
falco::load_result::rules_contents_t c = {{"test", ruleset_content}};
auto res = e->load_rules(c.begin()->second, c.begin()->first);
if(!res->successful())
{
return false;
}
return e->check_plugin_requirements(plugins, err);
}
TEST(PluginRequirements, check_plugin_requirements_success)
{
std::string error;
/* No requirement */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.1.0"}}, "")) << error << std::endl;
/* Single plugin */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
)")) << error
<< std::endl;
/* Single plugin newer version */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.2.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
)")) << error
<< std::endl;
/* Multiple plugins */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.1.0"}, {"json", "0.3.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- name: json
version: 0.3.0
)")) << error
<< std::endl;
/* Single plugin multiple versions */
ASSERT_TRUE(check_requirements(error, {{"k8saudit", "0.2.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 0.2.0
)")) << error
<< std::endl;
/* Single plugin with alternatives */
ASSERT_TRUE(check_requirements(error, {{"k8saudit-other", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
)")) << error
<< std::endl;
/* Multiple plugins with alternatives */
ASSERT_TRUE(check_requirements(error, {{"k8saudit-other", "0.5.0"}, {"json2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
)")) << error
<< std::endl;
/* Multiple plugins with alternatives with multiple versions */
ASSERT_TRUE(check_requirements(error, {{"k8saudit-other", "0.7.0"}, {"json2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 1.0.0
alternatives:
- name: k8saudit-other
version: 0.7.0
)")) << error
<< std::endl;
}
TEST(PluginRequirements, check_plugin_requirements_reject)
{
std::string error;
/* No plugin loaded */
ASSERT_FALSE(check_requirements(error, {}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
)")) << error
<< std::endl;
/* Single plugin wrong name */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit2
version: 0.1.0
)")) << error
<< std::endl;
/* Single plugin wrong version */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.2.0
)")) << error
<< std::endl;
/* Multiple plugins */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- name: json
version: 0.3.0
)")) << error
<< std::endl;
/* Single plugin multiple versions */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.1.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 0.2.0
)")) << error
<< std::endl;
/* Single plugin with alternatives */
ASSERT_FALSE(check_requirements(error, {{"k8saudit2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
)")) << error
<< std::endl;
/* Single plugin with overlapping alternatives */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit
version: 0.4.0
)")) << error
<< std::endl;
/* Multiple plugins with alternatives */
ASSERT_FALSE(check_requirements(error, {{"k8saudit-other", "0.5.0"}, {"json3", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.1.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
)")) << error
<< std::endl;
/* Multiple plugins with alternatives with multiple versions */
ASSERT_FALSE(check_requirements(error, {{"k8saudit", "0.7.0"}, {"json2", "0.5.0"}}, R"(
- required_plugin_versions:
- name: k8saudit
version: 0.4.0
alternatives:
- name: k8saudit-other
version: 0.4.0
- name: json
version: 0.3.0
alternatives:
- name: json2
version: 0.1.0
- required_plugin_versions:
- name: k8saudit
version: 1.0.0
alternatives:
- name: k8saudit-other
version: 0.7.0
)")) << error
<< std::endl;
}

View File

@@ -0,0 +1,177 @@
/*
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.
*/
#include <gtest/gtest.h>
#include <engine/evttype_index_ruleset.h>
#define RULESET_0 0
#define RULESET_1 1
#define RULESET_2 2
/* Helpers methods */
static std::shared_ptr<gen_event_filter_factory> create_factory()
{
std::shared_ptr<gen_event_filter_factory> ret(new sinsp_filter_factory(NULL));
return ret;
}
static std::shared_ptr<filter_ruleset> create_ruleset(std::shared_ptr<gen_event_filter_factory> f)
{
std::shared_ptr<filter_ruleset> ret(new evttype_index_ruleset(f));
return ret;
}
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(std::shared_ptr<gen_event_filter_factory> f)
{
libsinsp::filter::parser parser("evt.type=open");
std::shared_ptr<libsinsp::filter::ast::expr> ret(parser.parse());
return ret;
}
static std::shared_ptr<gen_event_filter> create_filter(
std::shared_ptr<gen_event_filter_factory> f,
std::shared_ptr<libsinsp::filter::ast::expr> ast)
{
sinsp_filter_compiler compiler(f, ast.get());
std::shared_ptr<gen_event_filter> filter(compiler.compile());
return filter;
}
TEST(Ruleset, enable_disable_rules_using_names)
{
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto filter = create_filter(f, ast);
falco_rule rule_A = {};
rule_A.name = "rule_A";
rule_A.source = falco_common::syscall_source;
falco_rule rule_B = {};
rule_B.name = "rule_B";
rule_B.source = falco_common::syscall_source;
falco_rule rule_C = {};
rule_C.name = "rule_C";
rule_C.source = falco_common::syscall_source;
r->add(rule_A, filter, ast);
r->add(rule_B, filter, ast);
r->add(rule_C, filter, ast);
/* Enable `rule_A` for RULESET_0 */
r->enable(rule_A.name, true, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Disable `rule_A` for RULESET_1, this should have no effect */
r->disable(rule_A.name, true, RULESET_1);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Enable a not existing rule for RULESET_2, this should have no effect */
r->disable("<NA>", true, RULESET_2);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Enable all rules for RULESET_0 */
r->enable("rule_", false, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 3);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Try to disable all rules with exact match for RULESET_0, this should have no effect */
r->disable("rule_", true, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 3);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Disable all rules for RULESET_0 */
r->disable("rule_", false, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Enable rule_C for RULESET_2 without exact_match */
r->enable("_C", false, RULESET_2);
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 1);
}
TEST(Ruleset, enable_disable_rules_using_tags)
{
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto filter = create_filter(f, ast);
falco_rule rule_A = {};
rule_A.name = "rule_A";
rule_A.source = falco_common::syscall_source;
rule_A.tags = {"first_rule_A_tag", "second_rule_A_tag", "common_tag"};
falco_rule rule_B = {};
rule_B.name = "rule_B";
rule_B.source = falco_common::syscall_source;
rule_B.tags = {"first_rule_B_tag", "second_rule_B_tag", "common_tag"};
r->add(rule_A, filter, ast);
r->add(rule_B, filter, ast);
/* Enable `rule_A` for RULESET_0 using its first tag */
r->enable_tags({"first_rule_A_tag"}, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Disable `rule_A` for RULESET_1 using its first tag, this should have no effect */
r->disable_tags({"first_rule_A_tag"}, RULESET_1);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Enable a not existing rule for RULESET_0, this should have no effect */
r->enable_tags({"<NA_tag>"}, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
/* Enable all rules for RULESET_2 */
r->enable_tags({"common_tag"}, RULESET_2);
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 2);
/* Disable `rule_A` for RULESET_0 using its second tag
* Note that we have previously enabled it using the first tag,
* so here we are using a different tag of the rule t disable it!
*/
r->disable_tags({"second_rule_A_tag"}, RULESET_0);
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 2);
/* Disable all rules for RULESET_2 */
r->disable_tags({"common_tag"}, RULESET_2);
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
}

View File

@@ -0,0 +1,7 @@
#pragma once
#include <gtest/gtest.h>
#include <falco/app/state.h>
#include <falco/app/actions/actions.h>
#define EXPECT_ACTION_OK(r) { EXPECT_TRUE(r.success); EXPECT_TRUE(r.proceed); EXPECT_EQ(r.errstr, ""); }
#define EXPECT_ACTION_FAIL(r) { EXPECT_FALSE(r.success); EXPECT_FALSE(r.proceed); EXPECT_NE(r.errstr, ""); }

View File

@@ -0,0 +1,428 @@
/*
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.
*/
#include <falco_engine.h>
#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_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({})); \
}
using strset_t = std::unordered_set<std::string>;
static std::set<std::string> _order(const strset_t& s)
{
return std::set<std::string>(s.begin(), s.end());
}
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"};
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)"};
// todo(jasondellaluce): once we have deeper and more modular
// control on the falco engine, make this a little nicer
static std::shared_ptr<falco_engine> mock_engine_from_filters(const strset_t& filters)
{
// craft a fake ruleset with the given filters
int n_rules = 0;
std::string dummy_rules;
falco::load_result::rules_contents_t content = {{"dummy_rules.yaml", dummy_rules}};
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";
}
// create a falco engine and load the ruleset
std::shared_ptr<falco_engine> res(new falco_engine());
auto filter_factory = std::shared_ptr<gen_event_filter_factory>(
new sinsp_filter_factory(nullptr));
auto formatter_factory = std::shared_ptr<gen_event_formatter_factory>(
new sinsp_evt_formatter_factory(nullptr));
res->add_source(s_sample_source, filter_factory, formatter_factory);
res->load_rules(dummy_rules, "dummy_rules.yaml");
res->enable_rule("", true, s_sample_ruleset);
return res;
}
TEST(ConfigureInterestingSets, engine_codes_syscalls_set)
{
auto engine = mock_engine_from_filters(s_sample_filters);
auto enabled_count = engine->num_rules_for_ruleset(s_sample_ruleset);
ASSERT_EQ(enabled_count, s_sample_filters.size());
// test if event code names were extracted from each rule in test ruleset.
auto rules_event_set = 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"}));
// 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 = 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"}));
}
TEST(ConfigureInterestingSets, preconditions_postconditions)
{
auto mock_engine = mock_engine_from_filters(s_sample_filters);
falco::app::state s1;
s1.engine = mock_engine;
s1.config = nullptr;
auto result = falco::app::actions::configure_interesting_sets(s1);
ASSERT_FALSE(result.success);
ASSERT_NE(result.errstr, "");
s1.engine = nullptr;
s1.config = std::make_shared<falco_configuration>();
result = falco::app::actions::configure_interesting_sets(s1);
ASSERT_FALSE(result.success);
ASSERT_NE(result.errstr, "");
s1.engine = mock_engine;
s1.config = std::make_shared<falco_configuration>();
result = falco::app::actions::configure_interesting_sets(s1);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
auto prev_selection_size = s1.selected_sc_set.size();
result = falco::app::actions::configure_interesting_sets(s1);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
ASSERT_EQ(prev_selection_size, s1.selected_sc_set.size());
}
TEST(ConfigureInterestingSets, 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());
auto engine = mock_engine_from_filters(filters);
auto enabled_count = engine->num_rules_for_ruleset(s_sample_ruleset);
ASSERT_EQ(enabled_count, filters.size());
auto rules_event_set = engine->event_codes_for_ruleset(s_sample_source);
auto rules_event_names = libsinsp::events::event_set_to_names(rules_event_set);
// note: including even one generic event will cause PPME_GENERIC_E to be
// included in the ruleset's event codes. As such, when translating to names,
// 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
expected_names.insert(generic_names.begin(), generic_names.end());
ASSERT_NAMES_EQ(rules_event_names, expected_names);
auto rules_sc_set = 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
}));
}
TEST(ConfigureInterestingSets, selection_not_allevents)
{
falco::app::state s2;
// run app action with fake engine and without the `-A` option
s2.engine = mock_engine_from_filters(s_sample_filters);
s2.options.all_events = false;
ASSERT_EQ(s2.options.all_events, false);
auto result = falco::app::actions::configure_interesting_sets(s2);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
// todo(jasondellaluce): once we have deeper control on falco's outputs,
// also check if a warning has been printed in stderr
// check that the final selected set is the one expected
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)
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
// check that all IO syscalls have been erased from the selection
auto ignored_set = falco::app::ignored_sc_set();
auto erased_sc_names = libsinsp::events::sc_set_to_event_names(ignored_set);
ASSERT_NAMES_NOCONTAIN(selected_sc_names, erased_sc_names);
// 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)
{
rule_set.remove(erased);
state_set.remove(erased);
}
auto union_set = state_set.merge(rule_set);
auto inter_set = state_set.intersect(rule_set);
EXPECT_EQ(s2.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
ASSERT_EQ(s2.selected_sc_set, union_set);
}
TEST(ConfigureInterestingSets, selection_allevents)
{
falco::app::state s3;
// run app action with fake engine and with the `-A` option
s3.engine = mock_engine_from_filters(s_sample_filters);
s3.options.all_events = true;
auto result = falco::app::actions::configure_interesting_sets(s3);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
// todo(jasondellaluce): once we have deeper control on falco's outputs,
// also check if a warning has not been printed in stderr
// check that the final selected set is the one expected
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)
});
ASSERT_NAMES_CONTAIN(selected_sc_names, expected_sc_names);
// check that final selected set is exactly sinsp state + ruleset
auto rule_set = s3.engine->sc_codes_for_ruleset(s_sample_source, s_sample_ruleset);
auto state_set = libsinsp::events::sinsp_state_sc_set();
auto union_set = state_set.merge(rule_set);
auto inter_set = state_set.intersect(rule_set);
EXPECT_EQ(s3.selected_sc_set.size(), state_set.size() + rule_set.size() - inter_set.size());
ASSERT_EQ(s3.selected_sc_set, union_set);
}
TEST(ConfigureInterestingSets, selection_generic_evts)
{
falco::app::state s4;
// run app action with fake engine and without the `-A` option
s4.options.all_events = false;
auto filters = s_sample_filters;
filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end());
s4.engine = mock_engine_from_filters(filters);
auto result = falco::app::actions::configure_interesting_sets(s4);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
// check that the final selected set is the one expected
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)
});
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());
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
}
// expected combinations precedence:
// - final selected set is the union of rules events and base events
// (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(ConfigureInterestingSets, selection_custom_base_set)
{
falco::app::state s5;
// run app action with fake engine and without the `-A` option
s5.options.all_events = true;
s5.engine = mock_engine_from_filters(s_sample_filters);
auto default_base_set = libsinsp::events::sinsp_state_sc_set();
// non-empty custom base set (both positive and negative)
s5.config->m_base_syscalls_repair = false;
s5.config->m_base_syscalls_custom_set = {"syncfs", "!accept"};
auto result = falco::app::actions::configure_interesting_sets(s5);
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"
});
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (both positive and negative with collision)
s5.config->m_base_syscalls_repair = false;
s5.config->m_base_syscalls_custom_set = {"syncfs", "accept", "!accept"};
result = falco::app::actions::configure_interesting_sets(s5);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
selected_sc_names = libsinsp::events::sc_set_to_event_names(s5.selected_sc_set);
// note: in case of collision, negation has priority, so the expected
// names are the same as the case above
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (only positive)
s5.config->m_base_syscalls_custom_set = {"syncfs"};
result = falco::app::actions::configure_interesting_sets(s5);
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"
});
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (only negative)
s5.config->m_base_syscalls_custom_set = {"!accept"};
result = falco::app::actions::configure_interesting_sets(s5);
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 = unordered_set_union(
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
expected_sc_names.erase("accept4");
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (positive, without -A)
s5.options.all_events = false;
s5.config->m_base_syscalls_custom_set = {"read"};
result = falco::app::actions::configure_interesting_sets(s5);
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"
});
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());
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
}
TEST(ConfigureInterestingSets, selection_custom_base_set_repair)
{
falco::app::state s6;
// run app action with fake engine and without the `-A` option
s6.options.all_events = false;
s6.engine = mock_engine_from_filters(s_sample_filters);
// note: here we use file syscalls (e.g. open, openat) and have a custom
// positive set, so we expect syscalls such as "close" to be selected as
// repaired. Also, given that we use some network syscalls, we expect "bind"
// to be selected event if we negate it, because repairment should have
// take precedence.
s6.config->m_base_syscalls_custom_set = {"openat", "!bind"};
s6.config->m_base_syscalls_repair = true;
auto result = falco::app::actions::configure_interesting_sets(s6);
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"
});
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());
ASSERT_NAMES_NOCONTAIN(selected_sc_names, unexpected_sc_names);
}
TEST(ConfigureInterestingSets, selection_empty_custom_base_set_repair)
{
falco::app::state s7;
// run app action with fake engine and with the `-A` option
s7.options.all_events = true;
s7.engine = mock_engine_from_filters(s_sample_filters);
// simulate empty custom set but repair option set.
s7.config->m_base_syscalls_custom_set = {};
s7.config->m_base_syscalls_repair = 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);
// 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);
}

View File

@@ -0,0 +1,55 @@
/*
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 ASSERTd 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 "app_action_helpers.h"
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)
{
FAIL() << "cannot get the number of online CPUs from the system\n";
}
// not modern bpf engine, we do nothing
{
falco::app::state s;
s.options.modern_bpf = false;
EXPECT_ACTION_OK(action(s));
}
// modern bpf engine, with an invalid number of CPUs
// default `m_cpus_for_each_syscall_buffer` to online CPU number
{
falco::app::state s;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus + 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus);
}
// modern bpf engine, with an valid number of CPUs
// we don't modify `m_cpus_for_each_syscall_buffer`
{
falco::app::state s;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus - 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus - 1);
}
}

View File

@@ -0,0 +1,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
http://www.apache.org/licenses/LICENSE-2.0
Unless ASSERTd 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 "app_action_helpers.h"
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));
}
// ignore source selection in capture mode
{
falco::app::state s;
s.options.trace_filename = "some_capture_file.scap";
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 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 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));
}
// 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

@@ -0,0 +1,131 @@
/*
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 ASSERTd 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 <gtest/gtest.h>
#include <future>
#include <thread>
#include <vector>
#include <memory>
#include <chrono>
#include <falco/atomic_signal_handler.h>
#include <falco/logger.h>
TEST(AtomicSignalHandler, lock_free_implementation)
{
ASSERT_TRUE(falco::atomic_signal_handler().is_lock_free());
}
TEST(AtomicSignalHandler, handle_once_wait_consistency)
{
constexpr const auto thread_num = 10;
constexpr const auto thread_wait_sec = 2;
constexpr const auto handler_wait_sec = 1;
// have a shared signal handler
falco::atomic_signal_handler handler;
// launch a bunch of threads all syncing on the same handler
typedef struct
{
bool handled;
uint64_t duration_secs;
} task_result_t;
std::vector<std::future<task_result_t>> futures;
std::vector<std::unique_ptr<std::thread>> threads;
for (int i = 0; i < thread_num; i++)
{
std::packaged_task<task_result_t()> task([&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 (std::chrono::seconds(thread_wait_sec));
});
}
}
auto diff = std::chrono::high_resolution_clock::now() - start;
res.duration_secs = std::chrono::duration_cast<std::chrono::seconds>(diff).count();
return res;
});
futures.push_back(task.get_future());
threads.emplace_back();
threads[i].reset(new std::thread(std::move(task)));
}
// wait a bit, then trigger the signal handler from the main thread
auto total_handled = 0;
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for (std::chrono::seconds(handler_wait_sec));
handler.trigger();
for (int i = 0; i < thread_num; i++)
{
// we need to check that all threads didn't quit before
// the handle() function finished executing
futures[i].wait();
threads[i]->join();
auto res = futures[i].get();
if (res.handled)
{
total_handled++;
}
ASSERT_GE(res.duration_secs, thread_wait_sec);
}
// check that the total time is consistent with the expectations
auto diff = std::chrono::high_resolution_clock::now() - start;
auto secs = std::chrono::duration_cast<std::chrono::seconds>(diff).count();
ASSERT_GE(secs, thread_wait_sec + handler_wait_sec);
// check that only one thread handled the signal
ASSERT_EQ(total_handled, 1);
}
TEST(AtomicSignalHandler, handle_and_reset)
{
auto do_nothing = []{};
falco::atomic_signal_handler handler;
ASSERT_FALSE(handler.triggered());
ASSERT_FALSE(handler.handled());
ASSERT_FALSE(handler.handle(do_nothing));
handler.trigger();
ASSERT_TRUE(handler.triggered());
ASSERT_FALSE(handler.handled());
ASSERT_TRUE(handler.handle(do_nothing));
ASSERT_TRUE(handler.triggered());
ASSERT_TRUE(handler.handled());
ASSERT_FALSE(handler.handle(do_nothing));
handler.trigger();
ASSERT_TRUE(handler.triggered());
ASSERT_FALSE(handler.handled());
ASSERT_TRUE(handler.handle(do_nothing));
ASSERT_TRUE(handler.triggered());
ASSERT_TRUE(handler.handled());
ASSERT_FALSE(handler.handle(do_nothing));
handler.reset();
ASSERT_FALSE(handler.triggered());
ASSERT_FALSE(handler.handled());
ASSERT_FALSE(handler.handle(do_nothing));
}

View File

@@ -0,0 +1,103 @@
/*
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 ASSERTd 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 <gtest/gtest.h>
#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";
TEST(Configuration, configuration_exceptions)
{
yaml_helper conf;
/* Broken YAML */
std::string sample_broken_yaml = sample_yaml + " / bad_symbol";
EXPECT_ANY_THROW(conf.load_from_string(sample_broken_yaml));
/* Right YAML */
EXPECT_NO_THROW(conf.load_from_string(sample_yaml));
}
TEST(Configuration, configuration_reload)
{
yaml_helper conf;
/* Clear and reload config */
conf.load_from_string(sample_yaml);
ASSERT_TRUE(conf.is_defined("base_value"));
conf.clear();
ASSERT_FALSE(conf.is_defined("base_value"));
conf.load_from_string(sample_yaml);
ASSERT_TRUE(conf.is_defined("base_value"));
}
TEST(Configuration, read_yaml_fields)
{
yaml_helper conf;
conf.load_from_string(sample_yaml);
/* is_defined */
ASSERT_TRUE(conf.is_defined("base_value"));
ASSERT_TRUE(conf.is_defined("base_value_2"));
ASSERT_FALSE(conf.is_defined("unknown_base_value"));
/* get some fields */
ASSERT_EQ(conf.get_scalar<int>("base_value.id", -1), 1);
ASSERT_STREQ(conf.get_scalar<std::string>("base_value.name", "none").c_str(), "sample_name");
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");
/* get sequence */
std::vector<std::string> seq;
conf.get_sequence(seq, "base_value_2.sample_list");
ASSERT_EQ(seq.size(), 3);
ASSERT_STREQ(seq[0].c_str(), "elem1");
ASSERT_STREQ(seq[1].c_str(), "elem2");
ASSERT_STREQ(seq[2].c_str(), "elem3");
}
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);
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
/* 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);
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
}

View File

@@ -18,8 +18,8 @@ set(FALCO_ENGINE_SOURCE_FILES
json_evt.cpp
evttype_index_ruleset.cpp
formats.cpp
filter_details_resolver.cpp
filter_macro_resolver.cpp
filter_evttype_resolver.cpp
filter_warning_resolver.cpp
stats_manager.cpp
rule_loader.cpp
@@ -29,9 +29,7 @@ set(FALCO_ENGINE_SOURCE_FILES
add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES})
if(USE_BUNDLED_DEPS)
add_dependencies(falco_engine yamlcpp njson)
endif()
add_dependencies(falco_engine yamlcpp njson)
if(MINIMAL_BUILD)
target_include_directories(

View File

@@ -1,5 +1,5 @@
/*
Copyright (C) 2019 The Falco Authors.
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.
@@ -37,9 +37,6 @@ limitations under the License.
#undef strcat
#define strcat(a, b) BAN(strcat)
#undef strncat
#define strncat(a, b, c) BAN(strncat)
#undef strncpy
#define strncpy(a, b, c) BAN(strncpy)

View File

@@ -15,13 +15,10 @@ limitations under the License.
*/
#include "evttype_index_ruleset.h"
#include "filter_evttype_resolver.h"
#include "banned.h" // This raises a compilation error when certain functions are used
#include <algorithm>
using namespace std;
evttype_index_ruleset::evttype_index_ruleset(
std::shared_ptr<gen_event_filter_factory> f): m_filter_factory(f)
{
@@ -68,14 +65,14 @@ void evttype_index_ruleset::ruleset_filters::remove_wrapper_from_list(filter_wra
void evttype_index_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_wrapper> wrap)
{
if(wrap->evttypes.empty())
if(wrap->event_codes.empty())
{
// Should run for all event types
add_wrapper_to_list(m_filter_all_event_types, wrap);
}
else
{
for(auto &etype : wrap->evttypes)
for(auto &etype : wrap->event_codes)
{
if(m_filter_by_event_type.size() <= etype)
{
@@ -91,13 +88,13 @@ void evttype_index_ruleset::ruleset_filters::add_filter(std::shared_ptr<filter_w
void evttype_index_ruleset::ruleset_filters::remove_filter(std::shared_ptr<filter_wrapper> wrap)
{
if(wrap->evttypes.empty())
if(wrap->event_codes.empty())
{
remove_wrapper_from_list(m_filter_all_event_types, wrap);
}
else
{
for(auto &etype : wrap->evttypes)
for(auto &etype : wrap->event_codes)
{
if( etype < m_filter_by_event_type.size() )
{
@@ -141,14 +138,24 @@ bool evttype_index_ruleset::ruleset_filters::run(gen_event *evt, falco_rule& mat
return false;
}
void evttype_index_ruleset::ruleset_filters::evttypes_for_ruleset(std::set<uint16_t> &evttypes)
libsinsp::events::set<ppm_sc_code> evttype_index_ruleset::ruleset_filters::sc_codes()
{
evttypes.clear();
libsinsp::events::set<ppm_sc_code> res;
for(auto &wrap : m_filters)
{
evttypes.insert(wrap->evttypes.begin(), wrap->evttypes.end());
res.insert(wrap->sc_codes.begin(), wrap->sc_codes.end());
}
return res;
}
libsinsp::events::set<ppm_event_code> evttype_index_ruleset::ruleset_filters::event_codes()
{
libsinsp::events::set<ppm_event_code> res;
for(auto &wrap : m_filters)
{
res.insert(wrap->event_codes.begin(), wrap->event_codes.end());
}
return res;
}
void evttype_index_ruleset::add(
@@ -163,18 +170,20 @@ void evttype_index_ruleset::add(
wrap->filter = filter;
if(rule.source == falco_common::syscall_source)
{
filter_evttype_resolver resolver;
resolver.evttypes(condition, wrap->evttypes);
wrap->sc_codes = libsinsp::filter::ast::ppm_sc_codes(condition.get());
wrap->event_codes = libsinsp::filter::ast::ppm_event_codes(condition.get());
}
else
{
wrap->evttypes = { ppm_event_type::PPME_PLUGINEVENT_E };
wrap->sc_codes = { };
wrap->event_codes = { ppm_event_code::PPME_PLUGINEVENT_E };
}
wrap->event_codes.insert(ppm_event_code::PPME_ASYNCEVENT_E);
m_filters.insert(wrap);
}
catch (const sinsp_exception& e)
{
throw falco_exception(string(e.what()));
throw falco_exception(std::string(e.what()));
}
}
@@ -193,17 +202,17 @@ void evttype_index_ruleset::clear()
m_filters.clear();
}
void evttype_index_ruleset::enable(const string &substring, bool match_exact, uint16_t ruleset_id)
void evttype_index_ruleset::enable(const std::string &substring, bool match_exact, uint16_t ruleset_id)
{
enable_disable(substring, match_exact, true, ruleset_id);
}
void evttype_index_ruleset::disable(const string &substring, bool match_exact, uint16_t ruleset_id)
void evttype_index_ruleset::disable(const std::string &substring, bool match_exact, uint16_t ruleset_id)
{
enable_disable(substring, match_exact, false, ruleset_id);
}
void evttype_index_ruleset::enable_disable(const string &substring, bool match_exact, bool enabled, uint16_t ruleset_id)
void evttype_index_ruleset::enable_disable(const std::string &substring, bool match_exact, bool enabled, uint16_t ruleset_id)
{
while(m_rulesets.size() < (size_t)ruleset_id + 1)
{
@@ -223,7 +232,7 @@ void evttype_index_ruleset::enable_disable(const string &substring, bool match_e
}
else
{
matches = (substring == "" || (wrap->rule.name.find(substring) != string::npos));
matches = (substring == "" || (wrap->rule.name.find(substring) != std::string::npos));
}
if(matches)
@@ -240,17 +249,17 @@ void evttype_index_ruleset::enable_disable(const string &substring, bool match_e
}
}
void evttype_index_ruleset::enable_tags(const set<string> &tags, uint16_t ruleset_id)
void evttype_index_ruleset::enable_tags(const std::set<std::string> &tags, uint16_t ruleset_id)
{
enable_disable_tags(tags, true, ruleset_id);
}
void evttype_index_ruleset::disable_tags(const set<string> &tags, uint16_t ruleset_id)
void evttype_index_ruleset::disable_tags(const std::set<std::string> &tags, uint16_t ruleset_id)
{
enable_disable_tags(tags, false, ruleset_id);
}
void evttype_index_ruleset::enable_disable_tags(const set<string> &tags, bool enabled, uint16_t ruleset_id)
void evttype_index_ruleset::enable_disable_tags(const std::set<std::string> &tags, bool enabled, uint16_t ruleset_id)
{
while(m_rulesets.size() < (size_t)ruleset_id + 1)
{
@@ -259,7 +268,7 @@ void evttype_index_ruleset::enable_disable_tags(const set<string> &tags, bool en
for(const auto &wrap : m_filters)
{
std::set<string> intersect;
std::set<std::string> intersect;
set_intersection(tags.begin(), tags.end(),
wrap->rule.tags.begin(), wrap->rule.tags.end(),
@@ -299,12 +308,29 @@ bool evttype_index_ruleset::run(gen_event *evt, falco_rule& match, uint16_t rule
return m_rulesets[ruleset_id]->run(evt, match);
}
void evttype_index_ruleset::enabled_evttypes(set<uint16_t> &evttypes, uint16_t ruleset_id)
void evttype_index_ruleset::enabled_evttypes(std::set<uint16_t> &evttypes, uint16_t ruleset_id)
{
if(m_rulesets.size() < (size_t)ruleset_id + 1)
evttypes.clear();
for (const auto& e : enabled_event_codes(ruleset_id))
{
return;
evttypes.insert((uint16_t) e);
}
return m_rulesets[ruleset_id]->evttypes_for_ruleset(evttypes);
}
libsinsp::events::set<ppm_sc_code> evttype_index_ruleset::enabled_sc_codes(uint16_t ruleset)
{
if(m_rulesets.size() < (size_t)ruleset + 1)
{
return {};
}
return m_rulesets[ruleset]->sc_codes();
}
libsinsp::events::set<ppm_event_code> evttype_index_ruleset::enabled_event_codes(uint16_t ruleset)
{
if(m_rulesets.size() < (size_t)ruleset + 1)
{
return {};
}
return m_rulesets[ruleset]->event_codes();
}

View File

@@ -70,11 +70,17 @@ public:
const std::set<std::string> &tags,
uint16_t rulset_id) override;
// evttypes for a ruleset
// note(jasondellaluce): this is deprecated, must use the new
// typing-improved `enabled_event_codes` and `enabled_sc_codes` instead
// todo(jasondellaluce): remove this in future code refactors
void enabled_evttypes(
std::set<uint16_t> &evttypes,
uint16_t ruleset) override;
libsinsp::events::set<ppm_sc_code> enabled_sc_codes(uint16_t ruleset) override;
libsinsp::events::set<ppm_event_code> enabled_event_codes(uint16_t ruleset) override;
private:
// Helper used by enable()/disable()
@@ -93,7 +99,8 @@ private:
struct filter_wrapper
{
falco_rule rule;
std::set<uint16_t> evttypes;
libsinsp::events::set<ppm_sc_code> sc_codes;
libsinsp::events::set<ppm_event_code> event_codes;
std::shared_ptr<gen_event_filter> filter;
};
@@ -113,7 +120,9 @@ private:
bool run(gen_event *evt, falco_rule& match);
void evttypes_for_ruleset(std::set<uint16_t> &evttypes);
libsinsp::events::set<ppm_sc_code> sc_codes();
libsinsp::events::set<ppm_event_code> event_codes();
private:
void add_wrapper_to_list(filter_wrapper_list &wrappers, std::shared_ptr<filter_wrapper> wrap);

View File

@@ -16,7 +16,7 @@ limitations under the License.
#include "falco_common.h"
static vector<string> priority_names = {
static std::vector<std::string> priority_names = {
"Emergency",
"Alert",
"Critical",
@@ -27,7 +27,7 @@ static vector<string> priority_names = {
"Debug"
};
bool falco_common::parse_priority(string v, priority_type& out)
bool falco_common::parse_priority(std::string v, priority_type& out)
{
for (size_t i = 0; i < priority_names.size(); i++)
{
@@ -44,7 +44,7 @@ bool falco_common::parse_priority(string v, priority_type& out)
return false;
}
falco_common::priority_type falco_common::parse_priority(string v)
falco_common::priority_type falco_common::parse_priority(std::string v)
{
falco_common::priority_type out;
if (!parse_priority(v, out))
@@ -54,7 +54,7 @@ falco_common::priority_type falco_common::parse_priority(string v)
return out;
}
bool falco_common::format_priority(priority_type v, string& out, bool shortfmt)
bool falco_common::format_priority(priority_type v, std::string& out, bool shortfmt)
{
if ((size_t) v < priority_names.size())
{
@@ -71,12 +71,12 @@ bool falco_common::format_priority(priority_type v, string& out, bool shortfmt)
return false;
}
string falco_common::format_priority(priority_type v, bool shortfmt)
std::string falco_common::format_priority(priority_type v, bool shortfmt)
{
string out;
std::string out;
if(!format_priority(v, out, shortfmt))
{
throw falco_exception("Unknown priority enum value: " + to_string(v));
throw falco_exception("Unknown priority enum value: " + std::to_string(v));
}
return out;
}

View File

@@ -52,7 +52,7 @@ struct falco_exception : std::exception
namespace falco_common
{
const string syscall_source = "syscall";
const std::string syscall_source = sinsp_syscall_event_source_name;
// Same as numbers/indices into the above vector
enum priority_type

View File

@@ -15,11 +15,21 @@ limitations under the License.
*/
#include <cstdlib>
#ifndef _WIN32
#include <unistd.h>
#else
#include <stdlib.h>
#include <io.h>
#define srandom srand
#define random rand
#endif
#include <string>
#include <fstream>
#include <functional>
#include <utility>
#include <vector>
#include <nlohmann/json.hpp>
#include <sinsp.h>
#include <plugin.h>
@@ -35,10 +45,10 @@ limitations under the License.
#include "utils.h"
#include "banned.h" // This raises a compilation error when certain functions are used
#include "evttype_index_ruleset.h"
#include "filter_details_resolver.h"
const std::string falco_engine::s_default_ruleset = "falco-default-ruleset";
using namespace std;
using namespace falco;
falco_engine::falco_engine(bool seed_rng)
@@ -85,7 +95,7 @@ const falco_source* falco_engine::find_source(std::size_t index) const
auto ret = m_sources.at(index);
if(!ret)
{
throw falco_exception("Unknown event source index " + to_string(index));
throw falco_exception("Unknown event source index " + std::to_string(index));
}
return ret;
}
@@ -169,7 +179,7 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
}
}
void falco_engine::load_rules(const string &rules_content, bool verbose, bool all_events)
void falco_engine::load_rules(const std::string &rules_content, bool verbose, bool all_events)
{
static const std::string no_name = "N/A";
@@ -189,11 +199,6 @@ std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_c
rule_loader::reader reader;
if (reader.read(cfg, m_rule_collector))
{
for (auto &src : m_sources)
{
src.ruleset = src.ruleset_factory->new_ruleset();
}
rule_loader::compiler compiler;
m_rules.clear();
compiler.compile(cfg, m_rule_collector, m_rules);
@@ -222,7 +227,7 @@ void falco_engine::load_rules_file(const std::string &rules_filename, bool verbo
interpret_load_result(res, rules_filename, rules_content, verbose);
}
std::unique_ptr<load_result> falco_engine::load_rules_file(const string &rules_filename)
std::unique_ptr<load_result> falco_engine::load_rules_file(const std::string &rules_filename)
{
std::string rules_content;
@@ -243,7 +248,7 @@ std::unique_ptr<load_result> falco_engine::load_rules_file(const string &rules_f
return load_rules(rules_content, rules_filename);
}
void falco_engine::enable_rule(const string &substring, bool enabled, const string &ruleset)
void falco_engine::enable_rule(const std::string &substring, bool enabled, const std::string &ruleset)
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
bool match_exact = false;
@@ -261,7 +266,7 @@ void falco_engine::enable_rule(const string &substring, bool enabled, const stri
}
}
void falco_engine::enable_rule_exact(const string &rule_name, bool enabled, const string &ruleset)
void falco_engine::enable_rule_exact(const std::string &rule_name, bool enabled, const std::string &ruleset)
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
bool match_exact = true;
@@ -279,7 +284,7 @@ void falco_engine::enable_rule_exact(const string &rule_name, bool enabled, cons
}
}
void falco_engine::enable_rule_by_tag(const set<string> &tags, bool enabled, const string &ruleset)
void falco_engine::enable_rule_by_tag(const std::set<std::string> &tags, bool enabled, const std::string &ruleset)
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
@@ -328,13 +333,23 @@ void falco_engine::evttypes_for_ruleset(std::string &source, std::set<uint16_t>
find_source(source)->ruleset->enabled_evttypes(evttypes, find_ruleset_id(ruleset));
}
libsinsp::events::set<ppm_sc_code> falco_engine::sc_codes_for_ruleset(const std::string &source, const std::string &ruleset)
{
return find_source(source)->ruleset->enabled_sc_codes(find_ruleset_id(ruleset));
}
libsinsp::events::set<ppm_event_code> falco_engine::event_codes_for_ruleset(const std::string &source, const std::string &ruleset)
{
return find_source(source)->ruleset->enabled_event_codes(find_ruleset_id(ruleset));
}
std::shared_ptr<gen_event_formatter> falco_engine::create_formatter(const std::string &source,
const std::string &output) const
{
return find_source(source)->formatter_factory->create_formatter(output);
}
unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t source_idx, gen_event *ev, uint16_t ruleset_id)
std::unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t source_idx, gen_event *ev, uint16_t ruleset_id)
{
// note: there are no thread-safety guarantees on the filter_ruleset::run()
// method, but the thread-safety assumptions of falco_engine::process_event()
@@ -360,10 +375,10 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t so
if(should_drop_evt() || !source || !source->ruleset->run(ev, source->m_rule, ruleset_id))
{
return unique_ptr<struct rule_result>();
return std::unique_ptr<struct rule_result>();
}
unique_ptr<struct rule_result> res(new rule_result());
std::unique_ptr<struct rule_result> res(new rule_result());
res->evt = ev;
res->rule = source->m_rule.name;
res->source = source->m_rule.source;
@@ -375,7 +390,7 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t so
return res;
}
unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t source_idx, gen_event *ev)
std::unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::size_t source_idx, gen_event *ev)
{
return process_event(source_idx, ev, m_default_ruleset_id);
}
@@ -411,30 +426,326 @@ std::size_t falco_engine::add_source(const std::string &source,
return m_sources.insert(src, source);
}
void falco_engine::describe_rule(string *rule) const
void falco_engine::describe_rule(std::string *rule, bool json) const
{
static const char* rule_fmt = "%-50s %s\n";
fprintf(stdout, rule_fmt, "Rule", "Description");
fprintf(stdout, rule_fmt, "----", "-----------");
if (!rule)
if(!json)
{
for (auto &r : m_rules)
static const char *rule_fmt = "%-50s %s\n";
fprintf(stdout, rule_fmt, "Rule", "Description");
fprintf(stdout, rule_fmt, "----", "-----------");
if(!rule)
{
auto str = falco::utils::wrap_text(r.description, 51, 110) + "\n";
fprintf(stdout, rule_fmt, r.name.c_str(), str.c_str());
for(auto &r : m_rules)
{
auto str = falco::utils::wrap_text(r.description, 51, 110) + "\n";
fprintf(stdout, rule_fmt, r.name.c_str(), str.c_str());
}
}
else
{
auto r = m_rules.at(*rule);
if(r == nullptr)
{
return;
}
auto str = falco::utils::wrap_text(r->description, 51, 110) + "\n";
fprintf(stdout, rule_fmt, r->name.c_str(), str.c_str());
}
return;
}
std::unique_ptr<sinsp> insp(new sinsp());
Json::FastWriter writer;
std::string json_str;
if(!rule)
{
// In this case we build json information about
// all rules, macros and lists
Json::Value output;
// Store required engine version
auto required_engine_version = m_rule_collector.required_engine_version();
output["required_engine_version"] = std::to_string(required_engine_version.version);
// Store required plugin versions
Json::Value plugin_versions = Json::arrayValue;
auto required_plugin_versions = m_rule_collector.required_plugin_versions();
for(const auto& req : required_plugin_versions)
{
Json::Value r;
r["name"] = req.at(0).name;
r["version"] = req.at(0).version;
Json::Value alternatives = Json::arrayValue;
for(size_t i = 1; i < req.size(); i++)
{
Json::Value alternative;
alternative["name"] = req[i].name;
alternative["version"] = req[i].version;
alternatives.append(alternative);
}
r["alternatives"] = alternatives;
plugin_versions.append(r);
}
output["required_plugin_versions"] = plugin_versions;
// Store information about rules
Json::Value rules_array = Json::arrayValue;
for(const auto& r : m_rules)
{
auto ri = m_rule_collector.rules().at(r.name);
Json::Value rule;
get_json_details(r, *ri, insp.get(), rule);
// Append to rule array
rules_array.append(rule);
}
output["rules"] = rules_array;
// Store information about macros
Json::Value macros_array;
for(const auto &m : m_rule_collector.macros())
{
Json::Value macro;
get_json_details(m, macro);
macros_array.append(macro);
}
output["macros"] = macros_array;
// Store information about lists
Json::Value lists_array = Json::arrayValue;
for(const auto &l : m_rule_collector.lists())
{
Json::Value list;
get_json_details(l, list);
lists_array.append(list);
}
output["lists"] = lists_array;
json_str = writer.write(output);
}
else
{
auto r = m_rules.at(*rule);
auto str = falco::utils::wrap_text(r->description, 51, 110) + "\n";
fprintf(stdout, rule_fmt, r->name.c_str(), str.c_str());
// build json information for just the specified rule
auto ri = m_rule_collector.rules().at(*rule);
if(ri == nullptr)
{
throw falco_exception("Rule \"" + *rule + "\" is not loaded");
}
auto r = m_rules.at(ri->name);
Json::Value rule;
get_json_details(*r, *ri, insp.get(), rule);
json_str = writer.write(rule);
}
fprintf(stdout, "%s", json_str.c_str());
}
void falco_engine::get_json_details(const falco_rule &r,
const rule_loader::rule_info &ri,
sinsp *insp,
Json::Value &rule) const
{
Json::Value rule_info;
// Fill general rule information
rule_info["name"] = r.name;
rule_info["condition"] = ri.cond;
rule_info["priority"] = format_priority(r.priority, false);
rule_info["output"] = r.output;
rule_info["description"] = r.description;
rule_info["enabled"] = ri.enabled;
rule_info["source"] = r.source;
Json::Value tags = Json::arrayValue;
for(const auto &t : ri.tags)
{
tags.append(t);
}
rule_info["tags"] = tags;
rule["info"] = rule_info;
// Parse rule condition and build the AST
// Assumption: no exception because rules have already been loaded.
auto ast = libsinsp::filter::parser(ri.cond).parse();
Json::Value json_details;
get_json_details(ast.get(), json_details);
rule["details"] = json_details;
// Get fields from output string
auto fmt = create_formatter(r.source, r.output);
std::vector<std::string> out_fields;
fmt->get_field_names(out_fields);
Json::Value outputFields = Json::arrayValue;
for(const auto &of : out_fields)
{
outputFields.append(of);
}
rule["details"]["output_fields"] = outputFields;
// Get fields from exceptions
Json::Value exception_fields = Json::arrayValue;
for(const auto &f : r.exception_fields)
{
exception_fields.append(f);
}
rule["details"]["exception_fields"] = exception_fields;
// Get names and operators from exceptions
Json::Value exception_names = Json::arrayValue;
Json::Value exception_operators = Json::arrayValue;
for(const auto &e : ri.exceptions)
{
exception_names.append(e.name);
if(e.comps.is_list)
{
for(const auto& c : e.comps.items)
{
if(c.is_list)
{
// considering max two levels of lists
for(const auto& i : c.items)
{
exception_operators.append(i.item);
}
}
else
{
exception_operators.append(c.item);
}
}
}
else
{
exception_operators.append(e.comps.item);
}
}
rule["details"]["exceptions"] = exception_names;
rule["details"]["exception_operators"] = exception_operators;
if(ri.source == falco_common::syscall_source)
{
// Store event types
Json::Value events;
get_json_evt_types(ast.get(), events);
rule["details"]["events"] = events;
}
}
void falco_engine::get_json_details(const rule_loader::macro_info& m,
Json::Value& macro) const
{
Json::Value macro_info;
macro_info["name"] = m.name;
macro_info["condition"] = m.cond;
macro["info"] = macro_info;
// Assumption: no exception because rules have already been loaded.
auto ast = libsinsp::filter::parser(m.cond).parse();
Json::Value json_details;
get_json_details(ast.get(), json_details);
macro["details"] = json_details;
// Store event types
Json::Value events;
get_json_evt_types(ast.get(), events);
macro["details"]["events"] = events;
}
void falco_engine::get_json_details(const rule_loader::list_info& l,
Json::Value& list) const
{
Json::Value list_info;
list_info["name"] = l.name;
Json::Value items = Json::arrayValue;
Json::Value lists = Json::arrayValue;
for(const auto &i : l.items)
{
if(m_rule_collector.lists().at(i) != nullptr)
{
lists.append(i);
continue;
}
items.append(i);
}
list_info["items"] = items;
list["info"] = list_info;
list["details"]["lists"] = lists;
}
void falco_engine::get_json_details(libsinsp::filter::ast::expr* ast,
Json::Value& output) const
{
filter_details details;
for(const auto &m : m_rule_collector.macros())
{
details.known_macros.insert(m.name);
}
for(const auto &l : m_rule_collector.lists())
{
details.known_lists.insert(l.name);
}
// Resolve the AST details
filter_details_resolver resolver;
resolver.run(ast, details);
Json::Value macros = Json::arrayValue;
for(const auto &m : details.macros)
{
macros.append(m);
}
output["macros"] = macros;
Json::Value operators = Json::arrayValue;
for(const auto &o : details.operators)
{
operators.append(o);
}
output["operators"] = operators;
Json::Value condition_fields = Json::arrayValue;
for(const auto &f : details.fields)
{
condition_fields.append(f);
}
output["condition_fields"] = condition_fields;
Json::Value lists = Json::arrayValue;
for(const auto &l : details.lists)
{
lists.append(l);
}
output["lists"] = lists;
details.reset();
}
void falco_engine::get_json_evt_types(libsinsp::filter::ast::expr* ast,
Json::Value& output) const
{
output = Json::arrayValue;
auto evtcodes = libsinsp::filter::ast::ppm_event_codes(ast);
auto syscodes = libsinsp::filter::ast::ppm_sc_codes(ast);
auto syscodes_to_evt_names = libsinsp::events::sc_set_to_event_names(syscodes);
auto evtcodes_to_evt_names = libsinsp::events::event_set_to_names(evtcodes, false);
for (const auto& n : unordered_set_union(syscodes_to_evt_names, evtcodes_to_evt_names))
{
output.append(n);
}
}
void falco_engine::print_stats() const
{
string out;
std::string out;
m_rule_stats_manager.format(m_rules, out);
// todo(jasondellaluce): introduce a logging callback in Falco
fprintf(stdout, "%s", out.c_str());
@@ -447,7 +758,7 @@ bool falco_engine::is_source_valid(const std::string &source) const
void falco_engine::read_file(const std::string& filename, std::string& contents)
{
ifstream is;
std::ifstream is;
is.open(filename);
if (!is.is_open())
@@ -455,8 +766,8 @@ void falco_engine::read_file(const std::string& filename, std::string& contents)
throw falco_exception("Could not open " + filename + " for reading");
}
contents.assign(istreambuf_iterator<char>(is),
istreambuf_iterator<char>());
contents.assign(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>());
}
void falco_engine::interpret_load_result(std::unique_ptr<load_result>& res,
@@ -559,7 +870,7 @@ void falco_engine::set_sampling_multiplier(double sampling_multiplier)
m_sampling_multiplier = sampling_multiplier;
}
void falco_engine::set_extra(string &extra, bool replace_container_info)
void falco_engine::set_extra(std::string &extra, bool replace_container_info)
{
m_extra = extra;
m_replace_container_info = replace_container_info;

View File

@@ -37,6 +37,7 @@ limitations under the License.
#include "falco_common.h"
#include "falco_source.h"
#include "falco_load_result.h"
#include "filter_details_resolver.h"
//
// This class acts as the primary interface between a program and the
@@ -123,7 +124,7 @@ public:
// Print details on the given rule. If rule is NULL, print
// details on all rules.
//
void describe_rule(std::string *rule) const;
void describe_rule(std::string *rule, bool json) const;
//
// Print statistics on how many events matched each rule.
@@ -147,10 +148,10 @@ public:
// of all output expressions. You can also choose to replace
// %container.info with the extra information or add it to the
// end of the expression. This is used in open source falco to
// add k8s/mesos/container information to outputs when
// add k8s/container information to outputs when
// available.
//
void set_extra(string &extra, bool replace_container_info);
void set_extra(std::string &extra, bool replace_container_info);
// Represents the result of matching an event against a set of
// rules.
@@ -222,11 +223,30 @@ public:
//
// Given an event source and ruleset, fill in a bitset
// containing the event types for which this ruleset can run.
// note(jasondellaluce): this is deprecated, must use the new
// typing-improved `enabled_event_codes` and `enabled_sc_codes` instead
// todo(jasondellaluce): remove this in future code refactors
//
void evttypes_for_ruleset(std::string &source,
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);
//
// 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);
//
// Given a source and output string, return an
// gen_event_formatter that can format output strings for an
@@ -279,12 +299,26 @@ private:
//
inline bool should_drop_evt() const;
// Retrieve json details from rules, macros, lists
void get_json_details(const falco_rule& r,
const rule_loader::rule_info& ri,
sinsp* insp,
Json::Value& rule) const;
void get_json_details(const rule_loader::macro_info& m,
Json::Value& macro) const;
void get_json_details(const rule_loader::list_info& l,
Json::Value& list) const;
void get_json_details(libsinsp::filter::ast::expr* ast,
Json::Value& output) const;
void get_json_evt_types(libsinsp::filter::ast::expr* ast,
Json::Value& output) const;
rule_loader::collector m_rule_collector;
indexed_vector<falco_rule> m_rules;
stats_manager m_rule_stats_manager;
uint16_t m_next_ruleset_id;
std::map<string, uint16_t> m_known_rulesets;
std::map<std::string, uint16_t> m_known_rulesets;
falco_common::priority_type m_min_priority;
//

View File

@@ -16,9 +16,9 @@ limitations under the License.
// The version of rules/filter fields/etc supported by this Falco
// engine.
#define FALCO_ENGINE_VERSION (15)
#define FALCO_ENGINE_VERSION (17)
// This is the result of running "falco --list -N | sha256sum" and
// represents the fields supported by this version of Falco. It's used
// at build time to detect a changed set of fields.
#define FALCO_FIELDS_CHECKSUM "cc9d32916c719ce5aea164cdadb56207cbeff20033e278b99101964be7aa77a1"
#define FALCO_FIELDS_CHECKSUM "dd438e1713ebf8abc09a2c89da77bb43ee3886ad1ba69802595a5f18e3854550"

View File

@@ -23,12 +23,109 @@ limitations under the License.
#include "utils.h"
#include "banned.h" // This raises a compilation error when certain functions are used
#include <re2/re2.h>
#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
// standard time unit conversions to milliseconds
#define ONE_MS_TO_MS 1UL
#define ONE_SECOND_TO_MS 1000UL
#define ONE_MINUTE_TO_MS ONE_SECOND_TO_MS * 60UL
#define ONE_HOUR_TO_MS ONE_MINUTE_TO_MS * 60UL
#define ONE_DAY_TO_MS ONE_HOUR_TO_MS * 24UL
#define ONE_WEEK_TO_MS ONE_DAY_TO_MS * 7UL
#define ONE_YEAR_TO_MS ONE_DAY_TO_MS * 365UL
namespace falco
{
namespace utils
{
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());
if(!interval_str.empty())
{
/* Option 1: Passing interval directly in ms. Will be deprecated in the future. */
if(std::all_of(interval_str.begin(), interval_str.end(), ::isdigit))
{
/* todo: deprecate for Falco 0.36. */
interval = std::stoull(interval_str, nullptr, 0);
}
/* Option 2: Passing a Prometheus compliant time duration.
* https://prometheus.io/docs/prometheus/latest/querying/basics/#time-durations
*/
else
{
re2::StringPiece input(interval_str);
std::string args[14];
re2::RE2::Arg arg0(&args[0]);
re2::RE2::Arg arg1(&args[1]);
re2::RE2::Arg arg2(&args[2]);
re2::RE2::Arg arg3(&args[3]);
re2::RE2::Arg arg4(&args[4]);
re2::RE2::Arg arg5(&args[5]);
re2::RE2::Arg arg6(&args[6]);
re2::RE2::Arg arg7(&args[7]);
re2::RE2::Arg arg8(&args[8]);
re2::RE2::Arg arg9(&args[9]);
re2::RE2::Arg arg10(&args[10]);
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 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 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++)
{
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())
{
cur_interval_str = args[group_it->second - 1];
if(!cur_interval_str.empty())
{
cur_interval = std::stoull(cur_interval_str, nullptr, 0);
}
if(cur_interval > 0)
{
interval += cur_interval * all_prometheus_time_conversions[i];
}
}
}
}
}
return interval;
}
std::string wrap_text(const std::string& in, uint32_t indent, uint32_t line_len)
{
std::istringstream is(in);

View File

@@ -24,6 +24,10 @@ limitations under the License.
#include <iostream>
#include <string>
#include <thread>
#include <unordered_set>
#include <set>
#include <vector>
#include <string>
#ifdef __GNUC__
#define likely(x) __builtin_expect(!!(x), 1)
@@ -39,6 +43,8 @@ namespace falco
namespace utils
{
uint64_t parse_prometheus_interval(std::string interval_str);
std::string wrap_text(const std::string& in, uint32_t indent, uint32_t linelen);
void readfile(const std::string& filename, std::string& data);

View File

@@ -0,0 +1,103 @@
/*
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.
*/
#include "filter_details_resolver.h"
using namespace libsinsp::filter;
void filter_details::reset()
{
fields.clear();
macros.clear();
operators.clear();
lists.clear();
}
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++)
{
m_expect_macro = true;
e->children[i]->accept(this);
m_expect_macro = false;
}
}
void filter_details_resolver::visitor::visit(ast::or_expr* e)
{
for(size_t i = 0; i < e->children.size(); i++)
{
m_expect_macro = true;
e->children[i]->accept(this);
m_expect_macro = false;
}
}
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())
{
m_details.lists.insert(item);
}
}
}
}
void filter_details_resolver::visitor::visit(ast::binary_check_expr* e)
{
m_expect_macro = false;
m_details.fields.insert(e->field);
m_details.operators.insert(e->op);
m_expect_list = true;
e->value->accept(this);
m_expect_list = false;
}
void filter_details_resolver::visitor::visit(ast::unary_check_expr* e)
{
m_expect_macro = false;
m_details.fields.insert(e->field);
m_details.operators.insert(e->op);
}
void filter_details_resolver::visitor::visit(ast::value_expr* e)
{
if(m_expect_macro)
{
auto it = m_details.known_macros.find(e->value);
if(it == m_details.known_macros.end())
{
return;
}
m_details.macros.insert(e->value);
}
}

View File

@@ -0,0 +1,79 @@
/*
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.
*/
#pragma once
#include <filter/parser.h>
#include <string>
#include <unordered_set>
#include <unordered_map>
struct filter_details
{
// input macros and lists
std::unordered_set<std::string> known_macros;
std::unordered_set<std::string> known_lists;
// output details
std::unordered_set<std::string> fields;
std::unordered_set<std::string> macros;
std::unordered_set<std::string> operators;
std::unordered_set<std::string> lists;
void reset();
};
/*!
\brief Helper class for getting details about rules' filters.
*/
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.
*/
void run(libsinsp::filter::ast::expr* filter,
filter_details& details);
private:
struct visitor : public libsinsp::filter::ast::expr_visitor
{
visitor(filter_details& details) :
m_details(details),
m_expect_list(false),
m_expect_macro(false) {}
visitor(visitor&&) = default;
visitor& operator = (visitor&&) = default;
visitor(const visitor&) = delete;
visitor& operator = (const visitor&) = delete;
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::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;
filter_details& m_details;
bool m_expect_list;
bool m_expect_macro;
};
};

View File

@@ -1,164 +0,0 @@
/*
Copyright (C) 2022 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.
*/
#include "filter_evttype_resolver.h"
#include <sinsp.h>
using namespace libsinsp::filter;
extern sinsp_evttables g_infotables;
static bool is_evttype_operator(const std::string& op)
{
return op == "==" || op == "=" || op == "!=" || op == "in";
}
size_t falco_event_types::get_ppm_event_max()
{
return PPM_EVENT_MAX;
}
void filter_evttype_resolver::visitor::inversion(falco_event_types& types)
{
falco_event_types all_types;
evttypes("", all_types);
if (types != all_types) // we don't invert the "all types" set
{
types = all_types.diff(types);
}
}
void filter_evttype_resolver::visitor::evttypes(const std::string& evtname, falco_event_types& out)
{
// Fill in from 2 to PPM_EVENT_MAX-1. 0 and 1 are excluded as
// those are PPM_GENERIC_E/PPME_GENERIC_X
const struct ppm_event_info* etable = g_infotables.m_event_info;
for(uint16_t i = 2; i < PPM_EVENT_MAX; i++)
{
// Skip unused events or events not matching the requested evtname
if(!sinsp::is_unused_event(i) && (evtname.empty() || std::string(etable[i].name) == evtname))
{
out.insert(i);
}
}
}
void filter_evttype_resolver::evttypes(
ast::expr* filter,
std::set<uint16_t>& out) const
{
visitor v;
v.m_expect_value = false;
v.m_last_node_evttypes.clear();
filter->accept(&v);
v.m_last_node_evttypes.for_each([&out](uint16_t val){out.insert(val); return true;});
}
void filter_evttype_resolver::evttypes(
shared_ptr<ast::expr> filter,
std::set<uint16_t>& out) const
{
visitor v;
v.m_expect_value = false;
v.m_last_node_evttypes.clear();
filter.get()->accept(&v);
v.m_last_node_evttypes.for_each([&out](uint16_t val){out.insert(val); return true;} );
}
// "and" nodes evttypes are the intersection of the evttypes of their children.
// we initialize the set with "all event types"
void filter_evttype_resolver::visitor::visit(ast::and_expr* e)
{
falco_event_types types;
evttypes("", types);
m_last_node_evttypes.clear();
for (auto &c : e->children)
{
falco_event_types inters;
c->accept(this);
types = types.intersect(m_last_node_evttypes);
}
m_last_node_evttypes = types;
}
// "or" nodes evttypes are the union of the evttypes their children
void filter_evttype_resolver::visitor::visit(ast::or_expr* e)
{
falco_event_types types;
m_last_node_evttypes.clear();
for (auto &c : e->children)
{
c->accept(this);
types.merge(m_last_node_evttypes);
}
m_last_node_evttypes = types;
}
void filter_evttype_resolver::visitor::visit(ast::not_expr* e)
{
m_last_node_evttypes.clear();
e->child->accept(this);
inversion(m_last_node_evttypes);
}
void filter_evttype_resolver::visitor::visit(ast::binary_check_expr* e)
{
m_last_node_evttypes.clear();
if (e->field == "evt.type" && is_evttype_operator(e->op))
{
m_expect_value = true;
e->value->accept(this);
m_expect_value = false;
if (e->op == "!=")
{
inversion(m_last_node_evttypes);
}
return;
}
evttypes("", m_last_node_evttypes);
}
void filter_evttype_resolver::visitor::visit(ast::unary_check_expr* e)
{
m_last_node_evttypes.clear();
evttypes("", m_last_node_evttypes);
}
void filter_evttype_resolver::visitor::visit(ast::value_expr* e)
{
m_last_node_evttypes.clear();
if (m_expect_value)
{
evttypes(e->value, m_last_node_evttypes);
return;
}
evttypes("", m_last_node_evttypes);
}
void filter_evttype_resolver::visitor::visit(ast::list_expr* e)
{
m_last_node_evttypes.clear();
if (m_expect_value)
{
for (auto &v : e->values)
{
evttypes(v, m_last_node_evttypes);
}
return;
}
evttypes("", m_last_node_evttypes);
}

View File

@@ -1,210 +0,0 @@
/*
Copyright (C) 2022 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.
*/
#pragma once
#include <filter/parser.h>
#include <string>
#include <set>
#include <memory>
#include <functional>
#include <stdexcept>
class falco_event_types
{
private:
using vec_t = std::vector<uint8_t>;
vec_t m_types{};
static inline void check_range(uint16_t e)
{
static const auto enum_max = get_ppm_event_max();
if(e > enum_max)
{
throw std::range_error("invalid event type");
}
}
public:
falco_event_types(falco_event_types&&) = default;
falco_event_types(const falco_event_types&) = default;
falco_event_types& operator=(falco_event_types&&) = default;
falco_event_types& operator=(const falco_event_types&) = default;
static size_t get_ppm_event_max();
inline falco_event_types():
m_types(get_ppm_event_max() + 1, 0)
{
}
inline void insert(uint16_t e)
{
check_range(e);
m_types[e] = 1;
}
void merge(const falco_event_types& other)
{
for(size_t i = 0; i <= get_ppm_event_max(); ++i)
{
m_types[i] |= other.m_types[i];
}
}
void merge(const std::set<uint16_t>& other)
{
for(const auto& e : other)
{
insert(e);
}
}
inline bool contains(uint16_t e) const
{
check_range(e);
return m_types[e] != 0;
}
void clear()
{
for(auto& v : m_types)
{
v = 0;
}
}
bool equals(const falco_event_types& other) const
{
return m_types == other.m_types;
}
falco_event_types diff(const falco_event_types& other)
{
falco_event_types ret;
for(size_t i = 0; i <= get_ppm_event_max(); ++i)
{
if(m_types[i] == 1 && other.m_types[i] == 0)
{
ret.m_types[i] = 1;
}
}
return ret;
}
falco_event_types intersect(const falco_event_types& other)
{
falco_event_types ret;
for(size_t i = 0; i <= get_ppm_event_max(); ++i)
{
if(m_types[i] == 1 && other.m_types[i] == 1)
{
ret.m_types[i] = 1;
}
}
return ret;
}
void for_each(std::function<bool(uint16_t)> consumer) const
{
for(uint16_t i = 0; i < m_types.size(); ++i)
{
if(m_types[i] != 0)
{
if(!consumer(i))
{
return;
}
}
}
}
};
inline bool operator==(const falco_event_types& lhs, const falco_event_types& rhs)
{
return lhs.equals(rhs);
}
inline bool operator!=(const falco_event_types& lhs, const falco_event_types& rhs)
{
return !(lhs == rhs);
}
/*!
\brief Helper class for finding event types
*/
class filter_evttype_resolver
{
public:
/*!
\brief Collects the evttypes related to the provided event name.
The event types are inserted in the set provided as parameter.
The set is not cleared before inserting the elements.
\param evtname The event name used to search event types. If an empty
string is passed, all the available evttypes are collected
\param out The set to be filled with the evttypes
*/
inline void evttypes(const std::string& evtname, falco_event_types& out) const
{
falco_event_types evt_types;
visitor().evttypes(evtname, evt_types);
evt_types.for_each([&out](uint16_t val)
{out.insert(val); return true; });
}
/*!
\brief Visits a filter AST and collects all the evttypes for which
the filter expression can be evaluated as true. The event types are
inserted in the set provided as parameter. The set is not cleared before
inserting the elements.
\param filter The filter AST to be explored
\param out The set to be filled with the evttypes
*/
void evttypes(
libsinsp::filter::ast::expr* filter,
std::set<uint16_t>& out) const;
/*!
\brief Overloaded version of evttypes() that supports filters wrapped
in shared pointers
*/
void evttypes(
std::shared_ptr<libsinsp::filter::ast::expr> filter,
std::set<uint16_t>& out) const;
private:
struct visitor : public libsinsp::filter::ast::expr_visitor
{
visitor(): m_expect_value(false) {}
visitor(visitor&&) = default;
visitor& operator = (visitor&&) = default;
visitor(const visitor&) = default;
visitor& operator = (const visitor&) = default;
bool m_expect_value;
falco_event_types m_last_node_evttypes;
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::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 inversion(falco_event_types& types);
void evttypes(const std::string& evtname, falco_event_types& out);
};
};

View File

@@ -17,7 +17,6 @@ limitations under the License.
#include "filter_macro_resolver.h"
#include "falco_common.h"
using namespace std;
using namespace libsinsp::filter;
bool filter_macro_resolver::run(libsinsp::filter::ast::expr*& filter)
@@ -54,8 +53,8 @@ bool filter_macro_resolver::run(std::shared_ptr<libsinsp::filter::ast::expr>& fi
}
void filter_macro_resolver::set_macro(
string name,
shared_ptr<libsinsp::filter::ast::expr> macro)
std::string name,
std::shared_ptr<libsinsp::filter::ast::expr> macro)
{
m_macros[name] = macro;
}

View File

@@ -21,6 +21,7 @@ limitations under the License.
#include <filter.h>
#include <event.h>
#include <gen_filter.h>
#include <events/sinsp_events.h>
/*!
\brief Manages a set of rulesets. A ruleset is a set of
@@ -83,10 +84,29 @@ public:
\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;
/*!
\brief Find those rules matching the provided substring and enable

View File

@@ -21,13 +21,13 @@ using namespace falco;
static const char* no_value = "<NA>";
static inline bool is_unsafe_field(const string& f)
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 string& op)
static inline bool is_equality_operator(const std::string& op)
{
return op == "==" || op == "=" || op == "!="
|| op == "in" || op == "intersects" || op == "pmatch";

View File

@@ -33,11 +33,11 @@ falco_formats::~falco_formats()
{
}
string falco_formats::format_event(gen_event *evt, const std::string &rule, const std::string &source,
std::string falco_formats::format_event(gen_event *evt, const std::string &rule, const std::string &source,
const std::string &level, const std::string &format, std::set<std::string> &tags,
const std::string &hostname) const
{
string line;
std::string line;
std::shared_ptr<gen_event_formatter> formatter;
@@ -48,7 +48,7 @@ string falco_formats::format_event(gen_event *evt, const std::string &rule, cons
if(formatter->get_output_format() == gen_event_formatter::OF_JSON)
{
string json_line;
std::string json_line;
// Format the event into a json object with all fields resolved
formatter->tostring(evt, json_line);
@@ -67,14 +67,14 @@ string falco_formats::format_event(gen_event *evt, const std::string &rule, cons
Json::Value event;
Json::Value rule_tags;
Json::FastWriter writer;
string full_line;
std::string full_line;
unsigned int rule_tags_idx = 0;
// Convert the time-as-nanoseconds to a more json-friendly ISO8601.
time_t evttime = evt->get_ts() / 1000000000;
char time_sec[20]; // sizeof "YYYY-MM-DDTHH:MM:SS"
char time_ns[12]; // sizeof ".sssssssssZ"
string iso8601evttime;
std::string iso8601evttime;
strftime(time_sec, sizeof(time_sec), "%FT%T", gmtime(&evttime));
snprintf(time_ns, sizeof(time_ns), ".%09luZ", evt->get_ts() % 1000000000);
@@ -131,14 +131,14 @@ string falco_formats::format_event(gen_event *evt, const std::string &rule, cons
return line.c_str();
}
map<string, string> falco_formats::get_field_values(gen_event *evt, const std::string &source,
std::map<std::string, std::string> falco_formats::get_field_values(gen_event *evt, const std::string &source,
const std::string &format) const
{
std::shared_ptr<gen_event_formatter> formatter;
formatter = m_falco_engine->create_formatter(source, format);
map<string, string> ret;
std::map<std::string, std::string> ret;
if (! formatter->get_field_values(evt, ret))
{

View File

@@ -33,7 +33,7 @@ public:
const std::string &level, const std::string &format, std::set<std::string> &tags,
const std::string &hostname) const;
map<string, string> get_field_values(gen_event *evt, const std::string &source,
std::map<std::string, std::string> get_field_values(gen_event *evt, const std::string &source,
const std::string &format) const ;
protected:

View File

@@ -19,6 +19,7 @@ limitations under the License.
#include <map>
#include <string>
#include <vector>
#include <unordered_map>
/*!
\brief Simple wrapper of std::vector that allows random access

View File

@@ -26,6 +26,7 @@ limitations under the License.
#include <nlohmann/json.hpp>
#include "falco_common.h"
#include "prefix_search.h"
#include <sinsp.h>
@@ -48,7 +49,7 @@ public:
inline uint16_t get_type() const
{
// All k8s audit events have the single tag "1". - see falco_engine::process_k8s_audit_event
return ppm_event_type::PPME_PLUGINEVENT_E;
return ppm_event_code::PPME_PLUGINEVENT_E;
}
protected:
@@ -435,6 +436,10 @@ public:
bool tostring(gen_event *evt, std::string &output) override;
bool tostring_withformat(gen_event *evt, std::string &output, gen_event_formatter::output_format of) override;
bool get_field_values(gen_event *evt, std::map<std::string, std::string> &fields) override;
void get_field_names(std::vector<std::string> &fields) override
{
throw falco_exception("json_event_formatter::get_field_names operation not supported");
}
output_format get_output_format() override;
std::string tojson(json_event *ev);

View File

@@ -297,6 +297,7 @@ namespace rule_loader
*/
struct engine_version_info
{
engine_version_info() : ctx("no-filename-given"), version(0) { };
engine_version_info(context &ctx);
~engine_version_info() = default;
engine_version_info(engine_version_info&&) = default;

View File

@@ -116,6 +116,11 @@ const std::vector<rule_loader::plugin_version_info::requirement_alternatives>& r
return m_required_plugin_versions;
}
const rule_loader::engine_version_info& rule_loader::collector::required_engine_version() const
{
return m_required_engine_version;
}
const indexed_vector<rule_loader::list_info>& rule_loader::collector::lists() const
{
return m_list_infos;
@@ -137,6 +142,10 @@ void rule_loader::collector::define(configuration& cfg, engine_version_info& inf
THROW(v < info.version, "Rules require engine version "
+ std::to_string(info.version) + ", but engine version is " + std::to_string(v),
info.ctx);
if(m_required_engine_version.version < info.version)
{
m_required_engine_version = info;
}
}
void rule_loader::collector::define(configuration& cfg, plugin_version_info& info)

View File

@@ -46,6 +46,11 @@ public:
*/
virtual const std::vector<plugin_version_info::requirement_alternatives>& required_plugin_versions() const;
/*!
\brief Returns the required engine versions
*/
virtual const engine_version_info& required_engine_version() const;
/*!
\brief Returns the list of defined lists
*/
@@ -92,6 +97,7 @@ private:
indexed_vector<macro_info> m_macro_infos;
indexed_vector<list_info> m_list_infos;
std::vector<plugin_version_info::requirement_alternatives> m_required_plugin_versions;
engine_version_info m_required_engine_version;
};
}; // namespace rule_loader

View File

@@ -21,7 +21,6 @@ limitations under the License.
#include "rule_loader_compiler.h"
#include "filter_macro_resolver.h"
#include "filter_evttype_resolver.h"
#include "filter_warning_resolver.h"
#define MAX_VISIBILITY ((uint32_t) -1)
@@ -70,7 +69,7 @@ static bool is_format_valid(const falco_source& source, std::string fmt, std::st
formatter = source.formatter_factory->create_formatter(fmt);
return true;
}
catch(exception &e)
catch(std::exception &e)
{
err = e.what();
return false;
@@ -455,7 +454,7 @@ void rule_loader::compiler::compile_rule_infos(
// failure.
sinsp_filter_compiler compiler(cfg.sources.at(r.source)->filter_factory, ast.get());
try {
shared_ptr<gen_event_filter> filter(compiler.compile());
std::shared_ptr<gen_event_filter> filter(compiler.compile());
source->ruleset->add(*out.at(rule_id), filter, ast);
}
catch (const sinsp_exception& e)
@@ -496,13 +495,10 @@ void rule_loader::compiler::compile_rule_infos(
}
// populate set of event types and emit an special warning
std::set<uint16_t> evttypes = { ppm_event_type::PPME_PLUGINEVENT_E };
if(rule.source == falco_common::syscall_source)
{
evttypes.clear();
filter_evttype_resolver().evttypes(ast, evttypes);
if ((evttypes.empty() || evttypes.size() > 100)
&& r.warn_evttypes)
auto evttypes = libsinsp::filter::ast::ppm_event_codes(ast.get());
if ((evttypes.empty() || evttypes.size() > 100) && r.warn_evttypes)
{
cfg.res->add_warning(
falco::load_result::load_result::LOAD_NO_EVTTYPE,

View File

@@ -21,7 +21,6 @@ limitations under the License.
#define THROW(cond, err, ctx) { if ((cond)) { throw rule_loader::rule_load_exception(falco::load_result::LOAD_ERR_YAML_VALIDATE, (err), (ctx)); } }
// Don't call this directly, call decode_val/decode_optional_val instead.
template <typename T>
static void decode_val_generic(const YAML::Node& item, const char *key, T& out, const rule_loader::context& ctx, bool optional)
@@ -88,7 +87,7 @@ static void decode_seq(const YAML::Node& item, const char *key,
}
template <typename T>
static void decode_items(const YAML::Node& item, vector<T>& out,
static void decode_items(const YAML::Node& item, std::vector<T>& out,
const rule_loader::context& ctx)
{
bool optional = false;
@@ -101,7 +100,7 @@ static void decode_items(const YAML::Node& item, vector<T>& out,
}
template <typename T>
static void decode_tags(const YAML::Node& item, set<T>& out,
static void decode_tags(const YAML::Node& item, std::set<T>& out,
const rule_loader::context& ctx)
{
bool optional = true;
@@ -136,7 +135,7 @@ static void decode_exception_info_entry(
{
THROW(val.Scalar().empty(), "Value must be non-empty", valctx);
out.is_list = false;
THROW(!YAML::convert<string>::decode(val, out.item), "Could not decode scalar value", valctx);
THROW(!YAML::convert<std::string>::decode(val, out.item), "Could not decode scalar value", valctx);
}
if (val.IsSequence())
{
@@ -400,7 +399,7 @@ static void read_item(
}
else
{
string priority;
std::string priority;
// All of these are required
decode_val(item, "condition", v.cond, ctx);

View File

@@ -17,8 +17,6 @@ limitations under the License.
#include "stats_manager.h"
#include "falco_common.h"
using namespace std;
stats_manager::stats_manager()
: m_total(0)
{
@@ -38,9 +36,9 @@ void stats_manager::clear()
void stats_manager::format(
const indexed_vector<falco_rule>& rules,
string& out) const
std::string& out) const
{
string fmt;
std::string fmt;
out = "Events detected: " + to_string(m_total) + "\n";
out += "Rule counts by severity:\n";
for (size_t i = 0; i < m_by_priority.size(); i++)
@@ -51,7 +49,7 @@ void stats_manager::format(
falco_common::format_priority(
(falco_common::priority_type) i, fmt, true);
transform(fmt.begin(), fmt.end(), fmt.begin(), ::toupper);
out += " " + fmt + ": " + to_string(val) + "\n";
out += " " + fmt + ": " + std::to_string(val) + "\n";
}
}
out += "Triggered rules by rule name:\n";
@@ -60,7 +58,7 @@ void stats_manager::format(
auto val = m_by_rule_id[i].get()->load();
if (val > 0)
{
out += " " + rules.at(i)->name + ": " + to_string(val) + "\n";
out += " " + rules.at(i)->name + ": " + std::to_string(val) + "\n";
}
}
}
@@ -70,12 +68,12 @@ void stats_manager::on_rule_loaded(const falco_rule& rule)
while (m_by_rule_id.size() <= rule.id)
{
m_by_rule_id.emplace_back();
m_by_rule_id[m_by_rule_id.size() - 1].reset(new atomic<uint64_t>(0));
m_by_rule_id[m_by_rule_id.size() - 1].reset(new std::atomic<uint64_t>(0));
}
while (m_by_priority.size() <= (size_t) rule.priority)
{
m_by_priority.emplace_back();
m_by_priority[m_by_priority.size() - 1].reset(new atomic<uint64_t>(0));
m_by_priority[m_by_priority.size() - 1].reset(new std::atomic<uint64_t>(0));
}
}

View File

@@ -67,7 +67,7 @@ public:
std::string& out) const;
private:
atomic<uint64_t> m_total;
std::vector<std::unique_ptr<atomic<uint64_t>>> m_by_priority;
std::vector<std::unique_ptr<atomic<uint64_t>>> m_by_rule_id;
std::atomic<uint64_t> m_total;
std::vector<std::unique_ptr<std::atomic<uint64_t>>> m_by_priority;
std::vector<std::unique_ptr<std::atomic<uint64_t>>> m_by_rule_id;
};

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