Compare commits

..

156 Commits

Author SHA1 Message Date
Leonardo Di Giovanna
5ebc79fcd6 fix(proposals): specify correct stable falco version
Updated the stable Falco version from 0.43.0 to 0.42.1 in the deprecation policy section.

Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2026-01-08 12:11:20 +01:00
Leonardo Di Giovanna
48c7bc78b6 docs(proposals): add proposal for legacy probe, gVisor engine and gRPC output deprecation
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2026-01-08 12:04:17 +01:00
poiana
50d4c4c879 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-01-07 14:39:12 +01:00
Leonardo Di Giovanna
e34a6b28eb chore(cmake): bump libs/drivers to 0.23.0/9.1.0+driver
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-12-24 09:36:41 +01:00
Adnan Ali
f4df5681fd fix(metrics): Add null check for state.outputs in metrics collection
This change adds a defensive null check before accessing state.outputs->get_outputs_queue_num_drops() to prevent segfaults if outputs is destroyed while metrics are being collected.

Signed-off-by: Adnan Ali <adduali1310@hotmail.com>
2025-12-23 15:18:38 +01:00
Leonardo Di Giovanna
fd4609884a chore(cmake): bump libs to 0.23.0-rc2
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-12-23 10:46:38 +01:00
Leonardo Di Giovanna
817551ee25 chore(cmake): bump libs/drivers to 0.23.0-rc1/9.1.0-rc1+driver
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-12-19 14:58:17 +01:00
Leonardo Grasso
6a152d338b chore(scripts/falcoctl): increase follow interval to 1 week
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-12-18 18:27:12 +01:00
irozzo-1A
11e8f82c6c Revert "fix(.github): ghcr.io rate-limit mitigation"
This reverts commit 2d9f1f1abc.

Signed-off-by: irozzo-1A <iacopo@sysdig.com>
2025-12-12 13:08:39 +01:00
irozzo-1A
03adda8656 Revert "chore(build): attempt mitigation to rate-limiter issuo on ghcr.io"
This reverts commit a9e8063e58.

Signed-off-by: irozzo-1A <iacopo@sysdig.com>
2025-12-12 13:08:39 +01:00
poiana
1582018a2c update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-12 11:07:38 +01:00
dependabot[bot]
0c6b926cd6 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `d919107` to `0116b86`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](d919107be6...0116b8608c)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-12-05 17:48:36 +01:00
Julien Francoz
0b2724450f Reduce image size
rm falcoctl in the same image layer, divides the image size by 2.

Signed-off-by: Julien Francoz <julien@les-tilleuls.coop>
2025-12-05 12:33:35 +01:00
irozzo-1A
a9e8063e58 chore(build): attempt mitigation to rate-limiter issuo on ghcr.io
Signed-off-by: irozzo-1A <iacopo@sysdig.com>
2025-12-01 12:54:18 +01:00
irozzo-1A
5b53681d2f chore(engine): add deprecation warning for evt.latency when used in conditions
Emit a deprecation warning when `evt.latency` is detected in a rule
condition.

Signed-off-by: irozzo-1A <iacopo@sysdig.com>
2025-12-01 12:54:18 +01:00
Leonardo Grasso
2d9f1f1abc fix(.github): ghcr.io rate-limit mitigation
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-11-27 19:14:54 +01:00
Leonardo Grasso
df3beba2e4 fix(cmake): correct falcoctl.yaml path in debian conffiles
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-11-27 19:14:54 +01:00
Leonardo Grasso
ecbf70b354 fix(.github/workflow): upgrade (no more available) systemd-rpm-macros package
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-31 16:09:47 +01:00
Leonardo Grasso
01fe75b0fd chore: revert submodules/rules change
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-31 16:09:47 +01:00
Leonardo Di Giovanna
1b1b391724 docs(CHANGELOG.md): update changelog for 0.42.0 release
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-10-31 16:09:47 +01:00
Leonardo Di Giovanna
bf60a61c52 docs(RELEASE.md): specify target branch association upon release creation
Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2025-10-23 15:56:50 +02:00
Leonardo Di Giovanna
6091fb18a0 docs(RELEASE.md): fix rn2md cmd generating changelogs
Remove branch specification from `rn2md` command example for changelogs generation. This results in taking into account PR merged on the master branch.

Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2025-10-23 15:55:50 +02:00
Leonardo Di Giovanna
d79ed7b951 docs(RELEASE.md): fix PRs filtering expr for checking release notes
Fix PRs filtering expression for checking the presence and the conformance of release notes.

Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2025-10-23 15:54:51 +02:00
Leonardo Di Giovanna
bda65653cc docs(RELEASE.md): fix PR filtering expression text
Fix PR filtering expression to match the corresponding link expression

Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2025-10-23 15:53:50 +02:00
Leonardo Grasso
933fb7e823 fix(userspace/falco): correct default duration calculation
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-21 20:53:44 +02:00
Iacopo Rozzo
c9e920b1f7 chore(falcoctl): update falco rules to version 5
Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
Co-authored-by: Leonardo Grasso <leonardo.grasso@sysdig.com>
Co-authored-by: Leonardo DiGiovanna <leonardo.digiovanna@sysdig.com>
2025-10-21 15:05:42 +02:00
Iacopo Rozzo
9e188d75bc chore(build): update falco libs dependency to 0.22.1
Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-10-20 14:59:34 +02:00
Iacopo Rozzo
5d6f6135ac chore(build): remove the compile option related to RTLD_DEEPBIND
Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-10-20 14:59:34 +02:00
Iacopo Rozzo
9eacf5e58f chore(deps): bump libs version to 0.22.0
Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-10-17 15:09:15 +02:00
Iacopo Rozzo
45ffa8e315 chore(deps): bump driver version to 9.0.0+driver
Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-10-17 15:09:15 +02:00
dependabot[bot]
18e8e264a0 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `db9405d` to `d919107`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](db9405d6c2...d919107be6)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-17 13:37:15 +02:00
Leonardo Grasso
d443201229 chore(cmake/modules): bump rules to v5.0.0
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-16 17:15:55 +02:00
Iacopo Rozzo
1717a98749 feat(engine): emit warning when a rule output uses deprecated "evt.dir"
Emit a warning when a rule uses the deprecated "evt.dir" field in output.

Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-10-14 09:46:43 +02:00
Leonardo Grasso
9ca8268c55 chore(cmake/modules): update rules to 5.0.0-rc1
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-13 19:06:38 +02:00
Leonardo Di Giovanna
94cd97e701 chore(docker): use new ENV syntax in place of deprecated one
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-10-13 15:10:37 +02:00
Leonardo Grasso
b39f88167a update(cmake): update libs to latest 0.22 dev
Adds some last-minute fixes.

Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-13 12:32:37 +02:00
Leonardo Grasso
0c3ff11a62 fix(cmake/modules): add DISABLE_RTLD_DEEPBIND when USE_ASAN is On
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-13 12:32:37 +02:00
Leonardo Grasso
38be8ba5d2 update(cmake): update libs and driver to 0.22 dev
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-13 12:32:37 +02:00
poiana
e099dc73f9 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-10-13 12:32:37 +02:00
Iacopo Rozzo
8c4e5aa854 Use generic DEPRECATED_ITEM warning code
Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-10-09 14:06:12 +02:00
Iacopo Rozzo
42085c9d7a feat(engine): emit warning when a condition uses deprecated "evt.dir"
Emit a warning when a rule with a condition using "evt.dir" field is
encountered.
The direction have been deprecated in the scope of enter event
suppression initiative.

Signed-off-by: Iacopo Rozzo <iacopo.rozzo@iacopo.rozzo>
2025-10-09 14:06:12 +02:00
Leonardo Grasso
aa16a0109e fix(cmake/modules): bump falcoctl to v0.11.4
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-09 12:33:12 +02:00
dependabot[bot]
ab91c52ca0 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `72cc635` to `db9405d`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](72cc635100...db9405d6c2)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-09 12:32:11 +02:00
Leonardo Di Giovanna
82f09d045a docs(OWNERS): add ekoops(Leonardo Di Giovanna) as approver
Signed-off-by: Leonardo Di Giovanna <41296180+ekoops@users.noreply.github.com>
2025-10-09 11:54:11 +02:00
dependabot[bot]
ade529709e chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `be38001` to `72cc635`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](be3800132f...72cc635100)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-03 18:12:33 +02:00
Leonardo Grasso
c830b5a0c2 docs(falco.yaml): enanche consistency and style
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-03 15:08:33 +02:00
Leonardo Grasso
63cb5fc1cd docs(falco.yaml): refactor config inline documentation
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-10-03 15:08:33 +02:00
Leonardo Grasso
573871955c chore(userspace/engine): bump Falco engine version to 0.56.0
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-09-30 18:52:12 +02:00
poiana
2c21e2c877 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-30 18:52:12 +02:00
Tero Kauppinen
eee4acc488 fix(userspace/falco): fix actions taken when events are dropped
User can configure a list of actions that are taken when Falco
detects a threshold exceeding value in drop statistics.

However, the logic that handles the list of configured actions
is designed to process only a single action; it takes only the
first action of the list. This approach has the problem that the
order of the actions comes as the deciding factor in choosing
which action is taken in case there are more than one action.

This fix enables Falco to process all actions on the list.

Signed-off-by: Tero Kauppinen <tero.kauppinen@est.tech>
2025-09-30 18:36:12 +02:00
Iacopo Rozzo
7fb9986e5a fix(prometheus): deprecate enter events drop stats
Enter events are no longer tracked by the Falco libs, this change
deprecates the Prometheus metrics related to enter event drops.

Signed-off-by: Iacopo Rozzo <iacopo@sysdig.com>
2025-09-23 10:37:08 +02:00
Leonardo Di Giovanna
4fa53452c3 fix(userspace/engine): fix logger date format
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-09-18 14:54:46 +02:00
Leonardo Di Giovanna
4d3b685c8b feat: make libs internal auto thread purging intervals configurable
Make Falco's libs internal auto thread purging interval and timeout
configurable and set their default values to 5 minutes. This helps
controlling the memory impact of process exit events dropping and
events re-ordering.

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-09-16 15:42:34 +02:00
Samuel Gaist
5faef4e65a fix(ci): install NSIS for building Windows package
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
7c7196f1f0 chore: pre-commit cleanup
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
e34caee3f8 Revert "refactor(userspace/falco): remove duplicate condition test"
This reverts commit 0ae61528fb.

Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
909122a849 refactor(userspace/falco): remove duplicate condition test
handled is test a second time for the same while it's already
part of the initial entry condition.

Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
e8c527f204 refactor(userspace/falco): comment out unused variable names
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
179234e08e refactor(userspace/falco): add missing override
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
d6fde4ac16 refactore(userspace/falco): use static_cast rather than c style cast
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
cdea5ad35f refactor(userspace/falco): correct variable scope
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
07438534e7 refactor(userspace/falco): add missing initial value
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
dadf81ed9d fix(userspace/falco): use correct qualifier for size_t in printf
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
3b91cb685f refactor(userspace/falco): const correctness
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
e5654849d4 refactor(userspace/engine): port from asctime to strftime
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
0cc39ac5e7 refactor(userspace/engine): make constructor explicit
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
d9f561cd7b refactor(userspace/engine): remove unused variable
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
668bbfc9de refactor(userpsace/engine): add missing override
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
4d03686999 refactor(userspace/engine): fix variable scope
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
2da40e798b refactor(userspace/engine): const correctness
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
01d2976b0a refactor(unit_tests): move initialization to initialization list
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
Samuel Gaist
9a65ef220c refactor(unit_tests): remove unused variable
Signed-off-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-09-16 09:38:29 +02:00
poiana
782a833795 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-18 17:32:18 +02:00
poiana
6adc54c92f update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-12 11:49:42 +02:00
Leonardo Grasso
1d3ac2871e docs(falco.yaml): update config index
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
fda1430afb fix(userspace/falco): smart pointer for sinsp_dumper
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
7cb23e0191 feat(unit_tests): add test for capture feature
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
97d88d12f1 chore(userspace/engine): initialize bool member for falco_rule
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
3af03998eb fix(userspace/falco): correct typo in type
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
aa501437a4 fix(userspace/engine): adding capture members to to the rule equility operator
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
504d52e694 fix(userspace/falco): address init ordering warning for falco_configuration
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
8dbd04816d fix(userspace/falco): add "capture" in config schema
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
63d27fbe1b chore: fix formatting
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
81f26b7e5d chore(userspace/falco): fix codespell
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
15e8a746cb new(userspace/falco): capture feature impl
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
a818d48806 new(userspace/falco): add file name generator helper for capture
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
1da5514012 new(userspapace/engine): add capture and capture_duration to the engine
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
21350a282c new(userspapace/engine): add capture and capture_duration to rules loader
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
e6cd74995c new(userspace/falco): config parsing
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
Leonardo Grasso
5ebfa1b05b new: add config options and docs for capture feature
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-08-12 11:25:43 +02:00
José Carlos Chávez
bff2f619df fix: indentation
Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch>
Signed-off-by: José Carlos Chávez <jcchavezs@gmail.com>
2025-08-11 10:46:35 +02:00
José Carlos Chávez
845e998ab4 fix: moves falco version up as it is duplicated
Signed-off-by: José Carlos Chávez <jcchavezs@gmail.com>
2025-08-11 10:46:35 +02:00
José Carlos Chávez
801e8bdbff chore: adds labels to falco-debian, driver-loader and driver-loader-buster
Signed-off-by: José Carlos Chávez <jcchavezs@gmail.com>
2025-08-11 10:46:35 +02:00
José Carlos Chávez
1fb0c85b19 feat: includes sha on the image labels
Signed-off-by: José Carlos Chávez <jcchavezs@gmail.com>
2025-08-11 10:46:35 +02:00
Federico Di Pierro
539294595e update(userspace/engine): bump engine version and checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-08-04 17:12:50 +02:00
Federico Di Pierro
154cde354f fix(userspace/falco): use proper API to fetch event param[0] as uint32_t.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-08-04 17:12:50 +02:00
poiana
ce8a67a5f4 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-08-04 17:12:50 +02:00
Federico Di Pierro
ec24062b71 chore(userspace/falco): print plugin version info too at plugin loading.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-08-01 18:27:30 +02:00
Federico Di Pierro
08b9e0f065 chore(ci): disable mimalloc for master builds.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-07-28 11:31:05 +02:00
Federico Di Pierro
3dce2f030d fix(cmake,userspace): fix usage and build of mimalloc.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-07-25 16:58:43 +02:00
Federico Di Pierro
687c3e147d update(cmake): bump mimalloc to 3.1.5.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-07-25 16:58:43 +02:00
Federico Di Pierro
e13e384d37 new(ci): add optional input to reusable_build_packages workflow to enable jemalloc or mimalloc.
Enable mimalloc in all CIs but release CI (keep it with jemalloc for now).

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-07-25 16:58:43 +02:00
Federico Di Pierro
6a4fa5dfce new(cmake,userspace/falco): add mimalloc allocator library support.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-07-25 16:58:43 +02:00
dependabot[bot]
cf792a0700 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `1208816` to `be38001`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](120881647a...be3800132f)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-25 10:56:44 +02:00
Leonardo Grasso
8dee7a075e docs(falco.yaml): avoid out-of-sync config options for container plugin
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-07-24 17:00:41 +02:00
Mariell Hoversholm
c3fc9e0d0f fix(restart_handler): disable if there is no work
When there is no work to do, i.e. when all config watching is disabled,
there is no need to keep the restart_handler running. Disable it in this
case.

This is helpful to do on nodes where there is little to no headroom in
terms of open inotify watches (as per the inotify/max_user_instances
configuration), as can happen on nodes populated with other software
that also watch the filesystem for changes. If Falco is run on such a
node, it may fail to start due to functionality the app does not even
intend on using.

This has one change in terms of behaviour, however: the dry-run restarts
will no longer occur. As there is still never going to happen a real
restart, I understand it as unlikely for there to be a proper need for
dry-run restarts.

Signed-off-by: Mariell Hoversholm <mariell@grafana.com>
2025-07-24 12:56:39 +02:00
Federico Di Pierro
5e2925bc95 update(cmake): bumped cpp-httplib dep to v0.23.1 (latest release).
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-07-22 14:32:28 +02:00
Leonardo Di Giovanna
ca291b0eaf update(userspace/engine): update falco engine version and checksum
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-07-22 14:30:29 +02:00
poiana
4deb2bdf31 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-22 11:40:29 +02:00
Leonardo Di Giovanna
8956279d47 build: fix debian:buster apt debian repo URL in driver-loader-buster
As buster reached its EOL, the official debian repo URL doesn't
host anymore buster packages info. For this reason, change the URLs
to point to the `20250630T203427Z` snapshot, which still contains
them.

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-07-18 12:02:10 +02:00
poiana
0c12b44bc6 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-07-02 17:22:29 +02:00
Leonardo Di Giovanna
33e6e1ef61 update(CHANGELOG.md): release 0.41.3
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-07-02 16:29:30 +02:00
dependabot[bot]
25be186548 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `4d51b18` to `1208816`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](4d51b1813f...120881647a)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-02 12:22:28 +02:00
Federico Di Pierro
ea9e86d9e0 update(userspace): bump engine version and checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-30 14:25:18 +02:00
Federico Di Pierro
b2c76769cf fix(userspace/falco): enforce filtercheck overlap check for static fields too against plugin fields.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Jason Dellaluce <jasondellaluce@gmail.com>
2025-06-30 14:25:18 +02:00
Federico Di Pierro
07266e1247 new(userspace/falco): append static filterchecks with static fields.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-30 14:25:18 +02:00
Federico Di Pierro
8d8ba5ba5c new(userspace/falco): add new static_fields config key + update schema.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-30 14:25:18 +02:00
Leonardo Di Giovanna
2ed1f0ffec docs(RELEASE.md): remove some unneeded old activities
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-06-18 15:38:05 +02:00
Leonardo Di Giovanna
f146204623 docs(RELEASE.md): fix falcosecurity/community repo link
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-06-18 15:38:05 +02:00
Leonardo Di Giovanna
56bf4933e7 docs(RELEASE.md): fix rn2md command documentation
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-06-18 15:38:05 +02:00
Leonardo Di Giovanna
d4e69e8c5a docs(RELEASE.md): fix release note checking procedure documentation
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-06-18 15:38:05 +02:00
poiana
a9386b37f2 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-17 16:22:45 +02:00
Leonardo Di Giovanna
25daddbf29 update(CHANGELOG.md): release 0.41.2
Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
2025-06-17 15:39:45 +02:00
Leonardo Grasso
720d3e61f2 chore(falco.yaml): clean up plugins config leftover
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-06-13 10:35:16 +02:00
Melissa Kilby
d55be4b29f doc(OWNERS): move incertum (Melissa Kilby) to emeritus_approvers
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-06-13 09:48:17 +02:00
dependabot[bot]
3d38e130fc chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `b4437c4` to `4d51b18`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](b4437c492f...4d51b1813f)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-06-12 09:45:10 +02:00
Federico Di Pierro
4418bf2101 update(userspace/engine): bump engine version and checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-09 12:19:53 +02:00
poiana
43cd120030 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-09 12:19:53 +02:00
Denis Romanenko
5b1c6886e5 Fix alpine build
Signed-off-by: Denis Romanenko <denis.romanenko@flant.com>
2025-06-09 12:18:54 +02:00
Federico Di Pierro
f3b4f68ecd update(docs): bump CHANGELOG.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-05 14:48:30 +02:00
Federico Di Pierro
7a349a3e87 update(userspace/engine): bump engine version and checksum.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-03 11:12:11 +02:00
FedeDP
0eb0b40c45 update(cmake): update libs and driver to latest master.
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-06-03 11:12:11 +02:00
Federico Di Pierro
9055811d79 fix(userspace/falco): when collecting metrics for stats_writer, create a libs_metrics_collector for each source.
In case multiple sources are enabled, each source has its own `libs_metrics_collector`
with correct flags, so that it can retrieve all metrics.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-06-02 10:42:59 +02:00
Federico Di Pierro
2346a397f7 chore(userspace/falco): fix build for non linux minimal builds.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-30 19:05:38 +02:00
Federico Di Pierro
24f92dfdbc fix(userspace/falco): only enable prometheus metrics once all inspectors have been opened.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-30 19:05:38 +02:00
Federico Di Pierro
1d51203c29 update(docs): bumped changelog for release.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-29 11:12:24 +02:00
Federico Di Pierro
a7433e032b chore(userspace/falco): make re2 patterns statically lived.
Moreover, rename `falco_metrics::` methods to better expose
they return prometheus metrics.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch>
2025-05-28 09:47:16 +02:00
Federico Di Pierro
bac052f5d2 cleanup(userspace/falco): only push metrics for enabled sources.
Refactor `::to_text` a bit to be more clear.
Also, we will push agent_info and machine_info only for the first
inspector that exposes them, to avoid duplicated entries in the prometheus text.

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-28 09:47:16 +02:00
Melissa Kilby
0ffe864e42 fix(metrics/prometheus): non-duplicate evt_source retrieval
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-28 09:47:16 +02:00
Melissa Kilby
4ef697b2c6 cleanup(metrics/prometheus): add detailed logic explanation wrt inspector loop
Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-28 09:47:16 +02:00
Melissa Kilby
b90f3cc18e update(metrics/prometheus): place syscalls inspector (if applicable) at index 0 of loop
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-28 09:47:16 +02:00
Melissa Kilby
4c12c2b1b5 fix(metrics/prometheus): gracefully handle multiple event sources, avoid erroneous duplicate metrics
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-28 09:47:16 +02:00
Luca Guerra
8f86f20d17 chore(build): update falcoctl, rules for artifact follow
Signed-off-by: Luca Guerra <luca@guerra.sh>
2025-05-27 16:53:12 +02:00
dependabot[bot]
70b0167f76 chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `cb17833` to `b4437c4`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](cb17833316...b4437c492f)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-27 08:51:10 +02:00
Federico Di Pierro
38cb34edc6 update(cmake): bumped falcoctl to 0.11.1 and rules to 4.0.0.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-26 18:50:06 +02:00
Luca Guerra
8a10bd52e6 update(containers): add labels
Signed-off-by: Luca Guerra <luca@guerra.sh>
2025-05-26 13:16:04 +02:00
Federico Di Pierro
8c703602c1 chore(userspace/falco): initialize m_falco_reload_ts to 0.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>

Co-authored-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
Melissa Kilby
faee56fc1a cleanup: apply minor code pilot suggestions
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
Melissa Kilby
c4dcf9e4e8 cleanup(configs): move runtime generated configs to section w/ clear comments
Co-authored-by: Samuel Gaist <samuel.gaist@idiap.ch>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
Melissa Kilby
309ccf65d3 cleanup(metrics): simplify logic around immediate metrics logging after start/reload
* For consistency don't make first run metrics log special
* Remove firt tick variable altogether to enable metrics logging immediately after startup/reload

Co-authored-by: Federico Di Pierro <nierro92@gmail.com>
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
Melissa Kilby
22d40e2a65 clenaup(metrics): rename new restart_ts to reload_ts to reflect hot relaod conditions
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
Melissa Kilby
c86a45e2ca update(metrics): introduce restart ts metric to statistically inspect restart/hot_reload conditions
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
Melissa Kilby
7b8fdd8f97 update(metrics): introduce immediate initial metrics msg (output_rule or output_file) upon start/restart/hot_reload
Signed-off-by: Melissa Kilby <melissa.kilby.oss@gmail.com>
2025-05-26 13:00:05 +02:00
dependabot[bot]
2250c0135b chore(deps): Bump submodules/falcosecurity-rules
Bumps [submodules/falcosecurity-rules](https://github.com/falcosecurity/rules) from `4ccf111` to `cb17833`.
- [Release notes](https://github.com/falcosecurity/rules/releases)
- [Commits](4ccf111c36...cb17833316)

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

Signed-off-by: dependabot[bot] <support@github.com>
2025-05-26 10:09:25 +02:00
Leonardo Grasso
917a477ec2 update(cmake/rules): bump to falco-rules-4.0.0-rc1
Signed-off-by: Leonardo Grasso <me@leonardograsso.com>
2025-05-20 19:05:29 +02:00
Federico Di Pierro
831e804473 cleanup(userspace/falco): drop unused libs_metrics_collector variable.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-05-20 17:34:29 +02:00
81 changed files with 1864 additions and 703 deletions

View File

@@ -27,6 +27,7 @@ jobs:
version: ${{ needs.fetch-version.outputs.version }}
enable_debug: true
enable_sanitizers: true
use_mimalloc: true
build-dev-packages-arm64:
needs: [fetch-version]
@@ -35,6 +36,7 @@ jobs:
arch: aarch64
version: ${{ needs.fetch-version.outputs.version }}
enable_debug: true
use_mimalloc: true
test-dev-packages:
needs: [fetch-version, build-dev-packages-x86_64]

View File

@@ -56,6 +56,7 @@ jobs:
with:
arch: x86_64
version: ${{ github.event.release.tag_name }}
use_jemalloc: true
secrets: inherit
build-packages-arm64:
@@ -64,6 +65,7 @@ jobs:
with:
arch: aarch64
version: ${{ github.event.release.tag_name }}
use_jemalloc: true
secrets: inherit
test-packages:

View File

@@ -46,6 +46,7 @@ jobs:
docker build -f docker/falco/Dockerfile -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg VERSION_BUCKET=bin${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg FALCO_COMMIT_SHA=${{ github.sha }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-${{ inputs.arch }}.tar
@@ -55,6 +56,7 @@ jobs:
docker build -f docker/falco-debian/Dockerfile -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}-debian \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg FALCO_COMMIT_SHA=${{ github.sha }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}-debian --output /tmp/falco-${{ inputs.arch }}-debian.tar
@@ -63,6 +65,8 @@ jobs:
run: |
docker build -f docker/driver-loader/Dockerfile -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg FALCO_IMAGE_TAG=${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg FALCO_COMMIT_SHA=${{ github.sha }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-driver-loader-${{ inputs.arch }}.tar
@@ -72,6 +76,7 @@ jobs:
docker build -f docker/driver-loader-buster/Dockerfile -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}-buster \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg FALCO_COMMIT_SHA=${{ github.sha }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}-buster --output /tmp/falco-driver-loader-${{ inputs.arch }}-buster.tar

View File

@@ -20,8 +20,18 @@ on:
required: false
type: boolean
default: false
use_jemalloc:
description: Use jemalloc memory allocator
required: false
type: boolean
default: false
use_mimalloc:
description: Use mimalloc memory allocator
required: false
type: boolean
default: false
permissions:
permissions:
contents: read
jobs:
@@ -63,8 +73,8 @@ jobs:
- name: Install systemd rpm macros
run: |
wget https://www.rpmfind.net/linux/centos-stream/9-stream/BaseOS/${{ inputs.arch }}/os/Packages/systemd-rpm-macros-252-51.el9.noarch.rpm
sudo alien -d -i systemd-rpm-macros-252-51.el9.noarch.rpm
wget https://www.rpmfind.net/linux/centos-stream/9-stream/BaseOS/${{ inputs.arch }}/os/Packages/systemd-rpm-macros-252-59.el9.noarch.rpm
sudo alien -d -i systemd-rpm-macros-252-59.el9.noarch.rpm
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
@@ -88,7 +98,8 @@ jobs:
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=ON \
-DUSE_JEMALLOC=${{ inputs.use_jemalloc }} \
-DUSE_MIMALLOC=${{ inputs.use_mimalloc }} \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
@@ -160,7 +171,8 @@ jobs:
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=On \
-DUSE_JEMALLOC=${{ inputs.use_jemalloc }} \
-DUSE_MIMALLOC=${{ inputs.use_mimalloc }} \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
@@ -209,6 +221,7 @@ jobs:
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=Off \
-DUSE_MIMALLOC=Off \
-DUSE_ASAN=On \
-DFALCO_VERSION=${{ inputs.version }}
@@ -253,7 +266,8 @@ jobs:
-DCMAKE_BUILD_TYPE=Release \
-DCPACK_GENERATOR=TGZ \
-DBUILD_BPF=Off -DBUILD_DRIVER=Off \
-DUSE_JEMALLOC=On \
-DUSE_JEMALLOC=${{ inputs.use_jemalloc }} \
-DUSE_MIMALLOC=${{ inputs.use_mimalloc }} \
-DUSE_BUNDLED_DEPS=On \
-DMUSL_OPTIMIZED_BUILD=On \
-DFALCO_ETC_DIR=/etc/falco \
@@ -339,6 +353,9 @@ jobs:
with:
fetch-depth: 0
- name: Install NSIS
run: choco install nsis -y
# NOTE: Backslash doesn't work as line continuation on Windows.
- name: Prepare project
run: |

View File

@@ -1,5 +1,144 @@
# Change Log
## v0.42.0
Released on 2025-10-22
### Major Changes
* feat: add `falco_libs.thread_table_auto_purging_interval_s` and `thread_table_auto_purging_thread_timeout_s` configuration options [[#3670](https://github.com/falcosecurity/falco/pull/3670)] - [@ekoops](https://github.com/ekoops)
* feat: log plugin version info at loading time [[#3657](https://github.com/falcosecurity/falco/pull/3657)] - [@FedeDP](https://github.com/FedeDP)
* feat: ability to add statically defined fields via `static_fields` configuration [[#3557](https://github.com/falcosecurity/falco/pull/3557)] - [@FedeDP](https://github.com/FedeDP)
* feat(engine): emit warning when a rule containing the `evt.dir` field in output is encountered [[#3697](https://github.com/falcosecurity/falco/pull/3697)] - [@irozzo-1A](https://github.com/irozzo-1A)
* feat(engine): emit warning when a rule containing a condition on the deprecated `evt.dir` field is encountered [[#3690](https://github.com/falcosecurity/falco/pull/3690)] - [@irozzo-1A](https://github.com/irozzo-1A)
* new: ability to record `.scap` files (capture feature) [[#3645](https://github.com/falcosecurity/falco/pull/3645)] - [@leogr](https://github.com/leogr)
* new(docker): includes sha on the image labels [[#3658](https://github.com/falcosecurity/falco/pull/3658)] - [@jcchavezs](https://github.com/jcchavezs)
* new(cmake,userspace,ci): add mimalloc support [[#3616](https://github.com/falcosecurity/falco/pull/3616)] - [@FedeDP](https://github.com/FedeDP)
### Minor Changes
* docs(falco.yaml): refactor config documentation [[#3685](https://github.com/falcosecurity/falco/pull/3685)] - [@leogr](https://github.com/leogr)
* build: fix `debian:buster` apt debian repo URL in `:driver-loader-buster` container image [[#3644](https://github.com/falcosecurity/falco/pull/3644)] - [@ekoops](https://github.com/ekoops)
* build: updagrade libs to version 0.22.1 [[#3705](https://github.com/falcosecurity/falco/pull/3705)] - [@irozzo-1A](https://github.com/irozzo-1A)
* build: upgrade drivers to v9.0.0+driver [[#3701](https://github.com/falcosecurity/falco/pull/3701)] - [@irozzo-1A](https://github.com/irozzo-1A)
* build: upgrade cpp-httplib to v0.23.1 [[#3647](https://github.com/falcosecurity/falco/pull/3647)] - [@FedeDP](https://github.com/FedeDP)
* update: upgrade default ruleset to v5.0.0 [[#3700](https://github.com/falcosecurity/falco/pull/3700)] - [@leogr](https://github.com/leogr)
* build: upgrade `falcoctl` to v0.11.4 [[#3694](https://github.com/falcosecurity/falco/pull/3694)] - [@leogr](https://github.com/leogr)
* chore(prometheus): deprecate enter events drop stats [[#3675](https://github.com/falcosecurity/falco/pull/3675)] - [@irozzo-1A](https://github.com/irozzo-1A)
### Bug Fixes
* fix(cmake): correct abseil-cpp for alpine build [[#3598](https://github.com/falcosecurity/falco/pull/3598)] - [@RomanenkoDenys](https://github.com/RomanenkoDenys)
* fix: enable handling of multiple actions configured with `syscall_event_drops.actions` [[#3676](https://github.com/falcosecurity/falco/pull/3676)] - [@terror96](https://github.com/terror96)
* fix: disable dry-run restarts when Falco runs with config-watching disabled [[#3640](https://github.com/falcosecurity/falco/pull/3640)] - [@Proximyst](https://github.com/Proximyst)
### Non user-facing changes
* fix(userspace/falco): correct default duration calculation [[#3715](https://github.com/falcosecurity/falco/pull/3715)] - [@leogr](https://github.com/leogr)
* chore(falcoctl): update falco rules to version 5 [[#3712](https://github.com/falcosecurity/falco/pull/3712)] - [@irozzo-1A](https://github.com/irozzo-1A)
* doc(OWNERS): move incertum (Melissa Kilby) to emeritus_approvers [[#3605](https://github.com/falcosecurity/falco/pull/3605)] - [@incertum](https://github.com/incertum)
* update(cmake): update libs and driver to latest master [[#3689](https://github.com/falcosecurity/falco/pull/3689)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* chore(docker): use new `ENV` syntax in place of deprecated one [[#3696](https://github.com/falcosecurity/falco/pull/3696)] - [@ekoops](https://github.com/ekoops)
* chore(cmake/modules): update rules to 5.0.0-rc1 [[#3698](https://github.com/falcosecurity/falco/pull/3698)] - [@leogr](https://github.com/leogr)
* fix(userspace/engine): fix logger date format [[#3672](https://github.com/falcosecurity/falco/pull/3672)] - [@ekoops](https://github.com/ekoops)
* docs(OWNERS): add `ekoops`(Leonardo Di Giovanna) as approver [[#3688](https://github.com/falcosecurity/falco/pull/3688)] - [@ekoops](https://github.com/ekoops)
* update(cmake): update libs and driver to latest master [[#3665](https://github.com/falcosecurity/falco/pull/3665)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* Refactor: cppcheck cleanups [[#3649](https://github.com/falcosecurity/falco/pull/3649)] - [@sgaist](https://github.com/sgaist)
* update(userspace/engine): update falco engine version and checksum [[#3648](https://github.com/falcosecurity/falco/pull/3648)] - [@ekoops](https://github.com/ekoops)
* update(cmake): update libs and driver to latest master [[#3662](https://github.com/falcosecurity/falco/pull/3662)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3661](https://github.com/falcosecurity/falco/pull/3661)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3653](https://github.com/falcosecurity/falco/pull/3653)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* chore(ci): disable mimalloc for master builds. [[#3655](https://github.com/falcosecurity/falco/pull/3655)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `1208816` to `be38001` [[#3651](https://github.com/falcosecurity/falco/pull/3651)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* docs(falco.yaml): avoid out-of-sync config options for `container` pl… [[#3650](https://github.com/falcosecurity/falco/pull/3650)] - [@leogr](https://github.com/leogr)
* update(cmake): update libs and driver to latest master [[#3636](https://github.com/falcosecurity/falco/pull/3636)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(CHANGELOG.md): release 0.41.3 (cherry-pick) [[#3634](https://github.com/falcosecurity/falco/pull/3634)] - [@ekoops](https://github.com/ekoops)
* update(cmake): update libs and driver to latest master [[#3628](https://github.com/falcosecurity/falco/pull/3628)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(CHANGELOG.md): release 0.41.2 (cherry-pick) [[#3623](https://github.com/falcosecurity/falco/pull/3623)] - [@ekoops](https://github.com/ekoops)
* update(cmake): update libs and driver to latest master [[#3618](https://github.com/falcosecurity/falco/pull/3618)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3602](https://github.com/falcosecurity/falco/pull/3602)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* chore(falco.yaml): clean up plugins config leftover [[#3596](https://github.com/falcosecurity/falco/pull/3596)] - [@leogr](https://github.com/leogr)
* chore(deps): Bump submodules/falcosecurity-rules from `b4437c4` to `4d51b18` [[#3607](https://github.com/falcosecurity/falco/pull/3607)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(docs): cherry pick CHANGELOG. [[#3600](https://github.com/falcosecurity/falco/pull/3600)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3592](https://github.com/falcosecurity/falco/pull/3592)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(docs): bumped changelog for release 0.41.0, master sync [[#3586](https://github.com/falcosecurity/falco/pull/3586)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `cb17833` to `b4437c4` [[#3578](https://github.com/falcosecurity/falco/pull/3578)] - [@dependabot[bot]](https://github.com/apps/dependabot)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 29 |
| Release note | 23 |
| Total | 52 |
## v0.41.3
Released on 2025-07-01
### Minor Changes
* update: bump container plugin to v0.3.1 [[#3629](https://github.com/falcosecurity/falco/pull/3629)] - [@FedeDP](https://github.com/FedeDP)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 0 |
| Release note | 1 |
| Total | 1 |
## v0.41.2
Released on 2025-06-17
### Minor Changes
* update(build): update container plugin to 0.3.0 [[#3619](https://github.com/falcosecurity/falco/pull/3619)] - [@ekoops](https://github.com/ekoops)
### Non user-facing changes
* update(build): update container plugin to 0.2.6 [[#3611](https://github.com/falcosecurity/falco/pull/3611)] - [@leogr](https://github.com/leogr)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 1 |
| Release note | 1 |
| Total | 2 |
## v0.41.1
Released on 2025-06-05
### Bug Fixes
* fix(userspace/falco): when collecting metrics for stats_writer, create a `libs_metrics_collector` for each source [[#3585](https://github.com/falcosecurity/falco/pull/3585)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/falco): only enable prometheus metrics once all inspectors have been opened [[#3588](https://github.com/falcosecurity/falco/pull/3588)] - [@FedeDP](https://github.com/FedeDP)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 0 |
| Release note | 2 |
| Total | 2 |
## v0.41.0
Released on 2025-05-29

View File

@@ -29,7 +29,18 @@ option(BUILD_FALCO_UNIT_TESTS "Build falco unit tests" OFF)
option(USE_ASAN "Build with AddressSanitizer" OFF)
option(USE_UBSAN "Build with UndefinedBehaviorSanitizer" OFF)
option(UBSAN_HALT_ON_ERROR "Halt on error when building with UBSan" ON)
option(USE_JEMALLOC "Use jemalloc allocator" OFF)
# Mem allocators - linux only for now
if(NOT WIN32
AND NOT APPLE
AND NOT MINIMAL_BUILD
AND NOT EMSCRIPTEN
)
# If one enables multiple allocators, cmake will fail since all of the allocators cmake modules
# create a `malloc` target.
option(USE_JEMALLOC "Use jemalloc allocator, linux only" OFF)
option(USE_MIMALLOC "Use mimalloc (microsoft) allocator, linux only" OFF)
endif()
if(WIN32)
if(POLICY CMP0091)
@@ -142,19 +153,29 @@ set(CMD_MAKE make)
include(ExternalProject)
if(USE_JEMALLOC)
if(USE_ASAN)
message(WARNING "Jemalloc and ASAN are known to have issues when combined")
endif()
include(jemalloc)
endif()
# libs
include(falcosecurity-libs)
# compute FALCO_VERSION (depends on libs)
include(falco-version)
# Mem allocators - linux only for now
if(NOT WIN32
AND NOT APPLE
AND NOT MINIMAL_BUILD
AND NOT EMSCRIPTEN
)
if(USE_JEMALLOC)
include(jemalloc)
endif()
if(USE_MIMALLOC)
include(mimalloc)
endif()
message(STATUS "Will use mem allocator library: ${MALLOC_LIB}")
endif()
# nlohmann-json
include(njson)
@@ -267,12 +288,6 @@ if(NOT WIN32
AND NOT MUSL_OPTIMIZED_BUILD
)
include(falcoctl)
set(CONTAINER_VERSION "0.2.4")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(CONTAINER_HASH "2b6cf7c014fa29dffbc063582343402b863581218e704ca8021bc971c3e029fc")
else() # arm64
set(CONTAINER_HASH "ad96c2baa299fa51b6be07a93b21dd03fe6e2a9bea44cc13ea50a346e5d22774")
endif()
include(container_plugin)
# Generate a binary_dir/falco.yaml that automatically enables the plugin to be used for local

3
OWNERS
View File

@@ -4,12 +4,13 @@ approvers:
- jasondellaluce
- fededp
- andreagit97
- incertum
- LucaGuerra
- sgaist
- ekoops
reviewers:
- kaizhe
emeritus_approvers:
- fntlnz
- kris-nova
- leodido
- incertum

View File

@@ -66,7 +66,7 @@ Changes and new features are organized into [milestones](https://github.com/falc
The release process is mostly automated, requiring only a few manual steps to initiate and complete.
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).
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 [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:
@@ -84,11 +84,15 @@ Before proceeding with the release, make sure to complete the following preparat
### 1. Release notes
- Find the previous release date (`YYYY-MM-DD`) by looking at the [Falco releases](https://github.com/falcosecurity/falco/releases)
- Check the release note block of every PR matching the `is:pr is:merged closed:>YYYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+closed%3A%3EYYYY-MM-DD)
- Double-check, by using the following filters, if there is any closed issue/merge PR with no milestone assigned:
- `is:issue state:closed no:milestone closed:>YYYY-MM-DD`
[filter](https://github.com/falcosecurity/falco/issues?q=is%3Aissue%20state%3Aclosed%20no%3Amilestone%20closed%3A%3EYYYY-MM-DD)
- `is:pr is:merged no:milestone closed:>YYYY-MM-DD`
[filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+no%3Amilestone+closed%3A%3EYYYY-MM-DD)
- Assign any issue/PR identified in the previous point to the milestone corresponding to the currently undergoing release
- Check the release note block of every PR matching the `is:pr is:merged milestone:M.m.p` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+milestone%3AM.m.p)
- Ensure the release note block follows the [commit convention](https://github.com/falcosecurity/.github/blob/master/CONTRIBUTING.md#commit-convention), otherwise fix its content
- If the PR has no milestone, assign it to the milestone currently undergoing release
- Check issues without a milestone (using `is:pr is:merged no:milestone closed:>YYYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+no%3Amilestone+closed%3A%3EYYYY-MM-DD) ) and add them to the milestone currently undergoing release
- Double-check that there are no more merged PRs without the target milestone assigned with the `is:pr is:merged no:milestone closed:>YYYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+no%3Amilestone+closed%3A%3EYYYY-MM-DD), if any, update those missing
### 2. Milestones
@@ -102,7 +106,7 @@ 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!
Double-check that any PR that should be part of the tag has been cherry-picked from master!
### 4. Release PR
@@ -112,7 +116,7 @@ The release PR is meant to be made against the respective `release/M.m.x` branch
- If any, manually correct it then open an issue to automate version number bumping later
- Versions table in the `README.md` updates itself automatically
- Generate the change log using [rn2md](https://github.com/leodido/rn2md):
- Execute `rn2md -o falcosecurity -m <version> -r falco`
- Execute `rn2md -r falcosecurity/falco -m M.m.p`
- In case `rn2md` emits error try to generate an GitHub OAuth access token and provide it with the `-t` flag
- Add the latest changes on top the previous `CHANGELOG.md`
- Submit a PR with the above modifications
@@ -125,16 +129,18 @@ The release PR is meant to be made against the respective `release/M.m.x` branch
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`.)
The pre-release must be associated with a newly created tag. The tag is intended to be created while drafting the new pre-release through the GitHub form (this is indeed the only way to correctly associate the tag with a target branch; more on this below).
The pre-release tag must be formatted as `M.m.p-r`, where `r` is the pre-release version information (e.g. `0.35.0-rc1`).
To do so:
To create both pre-release tag and pre-release, do the following:
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
- Use `M.m.p-r` both as tag version and release title.
- Use `M.m.p-r` both as tag version and release title
- Associate `release/M.m.x` as "target branch" for the new tag
- 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.
- 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.
@@ -146,6 +152,7 @@ Assume `M.m.p` is the new version.
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
- Use `M.m.p` both as tag version and release title
- Associate `release/M.m.x` as "target branch" for the new tag
- Do NOT fill body, since it will be autogenerated by the [github release workflow](.github/workflows/release.yaml)
- Publish the release!
- The release pipeline will start automatically upon publication and all packages and container images will be uploaded to the stable repositories.
@@ -158,7 +165,7 @@ 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-M.m.p.md`
- Add the entire content of the document to a new file in [github.com/falcosecurity/community/tree/main/meeting-notes](https://github.com/falcosecurity/community/tree/main/meeting-notes) as a new file labeled `release-M.m.p.md`
- Open up a pull request with the new change.
@@ -166,10 +173,10 @@ For each release we archive the meeting notes in git for historical purposes.
Announce the new release to the world!
- IFF the ongoing release introduces a **new minor version**, [archive a snapshot of the Falco website](https://github.com/falcosecurity/falco-website/blob/master/release.md#documentation-versioning)
- Publish a blog on [Falco website](https://github.com/falcosecurity/falco-website) ([example](https://github.com/falcosecurity/falco-website/blob/master/content/en/blog/falco-0-28-1.md))
- Send an announcement to cncf-falco-dev@lists.cncf.io (plain text, please)
- Let folks in the slack #falco channel know about a new release came out
- IFF the on going release introduces a **new minor version**, [archive a snapshot of the Falco website](https://github.com/falcosecurity/falco-website/blob/master/release.md#documentation-versioning)
## Falco Components Versioning
@@ -181,9 +188,7 @@ This section provides more details around the versioning of the components that
- 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 and loading logic, and/or when `FALCO_ENGINE_CHECKSUM` has changed. The checksum is computed by considering the available rules fields (see currently supported [Falco fields](https://falco.org/docs/reference/rules/supported-fields/)), the event types (see currently supported [Falco events](https://falco.org/docs/reference/rules/supported-events/)), and the supported driver schema version. A checksum indicates that something 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. Breaking changes introduced in the Falco engine are not necessarily tied to the drivers or libs versions. The version number must be incremented every time and only when a single change or an atomic group of changes - which meet the criteria described above - is included in the `master` branch. Thus, a version bump can occur multiple times during the development and testing phases of a given release cycle. A given version bump must not group multiple changes that occurred sporadically during 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).
```

View File

@@ -1,3 +1,3 @@
/etc/falco/falco.yaml
/etc/falco/falcoctl.yaml
/etc/falco/falco_rules.local.yaml
/etc/falcoctl/falcoctl.yaml

View File

@@ -20,11 +20,14 @@ if(USE_BUNDLED_CPPHTTPLIB)
set(HTTPLIB_REQUIRE_BROTLI OFF)
set(HTTPLIB_USE_ZLIB_IF_AVAILABLE OFF)
set(HTTPLIB_REQUIRE_ZLIB OFF)
set(HTTPLIB_USE_ZSTD_IF_AVAILABLE OFF)
set(HTTPLIB_REQUIRE_ZSTD OFF)
set(HTTPLIB_USE_NON_BLOCKING_GETADDRINFO OFF)
include(FetchContent)
FetchContent_Declare(
cpp-httplib
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.15.3.tar.gz
URL_HASH SHA256=2121bbf38871bb2aafb5f7f2b9b94705366170909f434428352187cb0216124e
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.23.1.tar.gz
URL_HASH SHA256=410a1347ed6bcbcc4a19af8ed8ad3873fe9fa97731d52db845c4c78f3f9c31e6
)
FetchContent_MakeAvailable(cpp-httplib)
else()

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 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
@@ -35,9 +35,9 @@ else()
# FALCOSECURITY_LIBS_VERSION. In case you want to test against another driver version (or
# branch, or commit) just pass the variable - ie., `cmake -DDRIVER_VERSION=dev ..`
if(NOT DRIVER_VERSION)
set(DRIVER_VERSION "8.1.0+driver")
set(DRIVER_VERSION "9e6a8ccd4e4f5796f45ad486decd00b4996129b7")
set(DRIVER_CHECKSUM
"SHA256=182e6787bf86249a846a3baeb4dcd31578b76d4a13efa16ce3f44d66b18a77a6"
"SHA256=87902814e29718529094b89ff2a3ddbd4ee7aa77da824d4acbaad0d863e04ce9"
)
endif()

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 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
@@ -20,16 +20,16 @@ option(ADD_FALCOCTL_DEPENDENCY "Add falcoctl dependency while building falco" ON
if(ADD_FALCOCTL_DEPENDENCY)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} FALCOCTL_SYSTEM_NAME)
set(FALCOCTL_VERSION "0.11.2")
set(FALCOCTL_VERSION "0.11.4")
message(STATUS "Building with falcoctl: ${FALCOCTL_VERSION}")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "8d55818987c90e54f7406e1c1441a18df1f485db858bb0b3efda5db217be3b48")
set(FALCOCTL_HASH "8015cadcb4328abcbf140c3ca88031cd46426f7f3279d2802f0937ab1e41d66c")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "7c36404b5b7a515df25e7dc6d827a74ebc8526b1b49850954bbdd40860961bc2")
set(FALCOCTL_HASH "246874f1168abb7a8463509c6191ede460e5a2b8a39058ef5c4a17b67cb86c85")
endif()
ExternalProject_Add(

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2025 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
@@ -42,9 +42,9 @@ else()
# version (or branch, or commit) just pass the variable - ie., `cmake
# -DFALCOSECURITY_LIBS_VERSION=dev ..`
if(NOT FALCOSECURITY_LIBS_VERSION)
set(FALCOSECURITY_LIBS_VERSION "0.21.0")
set(FALCOSECURITY_LIBS_VERSION "9e6a8ccd4e4f5796f45ad486decd00b4996129b7")
set(FALCOSECURITY_LIBS_CHECKSUM
"SHA256=9e977001dd42586df42a5dc7e7a948c297124865a233402e44bdec68839d322a"
"SHA256=87902814e29718529094b89ff2a3ddbd4ee7aa77da824d4acbaad0d863e04ce9"
)
endif()

View File

@@ -181,6 +181,10 @@ else()
sh
-c
"sed -i '20s/^/#include <cstdint>/' ${GRPC_SRC}/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h"
&&
sh
-c
"sed -i 's|off64_t|off_t|g' ${GRPC_SRC}/third_party/abseil-cpp/absl/base/internal/direct_mmap.h"
)
# Zig workaround: Add a PATCH_COMMAND to grpc cmake to fixup emitted -march by abseil-cpp

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2024 The Falco Authors.
# Copyright (C) 2025 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
@@ -25,9 +25,9 @@ elseif(NOT USE_BUNDLED_JEMALLOC)
else()
set(JEMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
find_library(JEMALLOC_LIB NAMES libjemalloc${JEMALLOC_LIB_SUFFIX})
if(JEMALLOC_LIB)
message(STATUS "Found JEMALLOC: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}")
find_library(MALLOC_LIB NAMES libjemalloc${JEMALLOC_LIB_SUFFIX})
if(MALLOC_LIB)
message(STATUS "Found system jemalloc: include: ${JEMALLOC_INCLUDE}, lib: ${MALLOC_LIB}")
else()
message(FATAL_ERROR "Couldn't find system jemalloc")
endif()
@@ -38,15 +38,15 @@ else()
set(JEMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
set(JEMALLOC_SRC "${PROJECT_BINARY_DIR}/jemalloc-prefix/src")
set(JEMALLOC_LIB "${JEMALLOC_SRC}/jemalloc/lib/libjemalloc${JEMALLOC_LIB_SUFFIX}")
set(JEMALLOC_INCLUDE "${JEMALLOC_SRC}/jemalloc/include/jemalloc")
set(MALLOC_LIB "${JEMALLOC_SRC}/malloc/lib/libjemalloc${JEMALLOC_LIB_SUFFIX}")
set(JEMALLOC_INCLUDE "${JEMALLOC_SRC}/malloc/include/jemalloc")
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
set(JEMALLOC_ARCH_SPECIFIC_CONFIGURE_ARGS --with-lg-page=14)
else()
set(JEMALLOC_ARCH_SPECIFIC_CONFIGURE_ARGS "")
endif()
ExternalProject_Add(
jemalloc
malloc
PREFIX "${PROJECT_BINARY_DIR}/jemalloc-prefix"
URL "https://github.com/jemalloc/jemalloc/archive/refs/tags/5.3.0.tar.gz"
URL_HASH "SHA256=ef6f74fd45e95ee4ef7f9e19ebe5b075ca6b7fbe0140612b2a161abafb7ee179"
@@ -56,11 +56,10 @@ else()
BUILD_COMMAND make build_lib_static
INSTALL_COMMAND ""
UPDATE_COMMAND ""
BUILD_BYPRODUCTS ${JEMALLOC_LIB}
BUILD_BYPRODUCTS ${MALLOC_LIB}
)
message(STATUS "Using bundled jemalloc: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}")
install(
FILES "${JEMALLOC_LIB}"
FILES "${MALLOC_LIB}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
@@ -68,8 +67,8 @@ endif()
# We add a custom target, in this way we can always depend on `jemalloc` without distinguishing
# between "bundled" and "not-bundled" case
if(NOT TARGET jemalloc)
add_custom_target(jemalloc)
if(NOT TARGET malloc)
add_custom_target(malloc)
endif()
include_directories(${JEMALLOC_INCLUDE})

View File

@@ -0,0 +1,92 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
option(USE_BUNDLED_MIMALLOC "Use bundled mimalloc (microsoft) allocator" ${USE_BUNDLED_DEPS})
if(MIMALLOC_INCLUDE)
# we already have MIMALLOC
elseif(NOT USE_BUNDLED_MIMALLOC)
find_path(MIMALLOC_INCLUDE mimalloc/mimalloc.h)
set(MIMALLOC_INCLUDE ${MIMALLOC_INCLUDE}/mimalloc)
if(BUILD_SHARED_LIBS)
set(MIMALLOC_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
else()
set(MIMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
find_library(MALLOC_LIB NAMES libmimalloc${MIMALLOC_LIB_SUFFIX})
if(MALLOC_LIB)
message(STATUS "Found system mimalloc: include: ${MIMALLOC_INCLUDE}, lib: ${MALLOC_LIB}")
else()
message(FATAL_ERROR "Couldn't find system mimalloc")
endif()
else()
if(BUILD_SHARED_LIBS)
set(BUILD_STATIC Off)
set(MIMALLOC_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
else()
set(BUILD_STATIC On)
set(MIMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
set(MIMALLOC_SRC "${PROJECT_BINARY_DIR}/mimalloc-prefix/src")
string(TOLOWER "${CMAKE_BUILD_TYPE}" _build_type)
if(_build_type STREQUAL "debug")
set(MIMALLOC_LIB_BASENAME "libmimalloc-debug")
else()
set(MIMALLOC_LIB_BASENAME "libmimalloc")
endif()
set(MALLOC_LIB "${MIMALLOC_SRC}/malloc-build/${MIMALLOC_LIB_BASENAME}${MIMALLOC_LIB_SUFFIX}")
set(MIMALLOC_INCLUDE ${MIMALLOC_SRC}/malloc/include/)
# To avoid recent clang versions complaining with "error: expansion of date or time macro is not
# reproducible" while building mimalloc, we force-set both variables.
string(TIMESTAMP DATE "%Y%m%d")
string(TIMESTAMP TIME "%H:%M")
set(MIMALLOC_EXTRA_CPPDEFS __DATE__="${DATE}",__TIME__="${TIME}")
# We disable arch specific optimization because of issues with building with zig. Optimizations
# would be only effective on arm64. See MI_NO_OPT_ARCH=On.
ExternalProject_Add(
malloc
PREFIX "${PROJECT_BINARY_DIR}/mimalloc-prefix"
URL "https://github.com/microsoft/mimalloc/archive/refs/tags/v3.1.5.tar.gz"
URL_HASH "SHA256=1c6949032069d5ebea438ec5cedd602d06f40a92ddf0f0d9dcff0993e5f6635c"
LIST_SEPARATOR "," # to pass MIMALLOC_EXTRA_CPPDEFS as list
CMAKE_ARGS -DBUILD_SHARED_LIBS=${BUILD_SHARED_LIBS}
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DMI_BUILD_SHARED=${BUILD_SHARED_LIBS}
-DMI_BUILD_STATIC=${BUILD_STATIC}
-DMI_BUILD_TESTS=Off
-DMI_BUILD_OBJECT=Off
-DMI_NO_OPT_ARCH=On
-DMI_EXTRA_CPPDEFS=${MIMALLOC_EXTRA_CPPDEFS}
INSTALL_COMMAND ""
UPDATE_COMMAND ""
BUILD_BYPRODUCTS ${MALLOC_LIB}
)
install(
FILES "${MALLOC_LIB}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
endif()
# We add a custom target, in this way we can always depend on `mimalloc` without distinguishing
# between "bundled" and "not-bundled" case
if(NOT TARGET malloc)
add_custom_target(malloc)
endif()
include_directories(${MIMALLOC_INCLUDE})
add_compile_definitions(HAS_MIMALLOC)

View File

@@ -18,9 +18,9 @@ include(ExternalProject)
if(NOT DEFINED FALCOSECURITY_RULES_FALCO_PATH)
# falco_rules.yaml
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-4.0.0")
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-5.0.0")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM
"SHA256=132320ddbfa1e2580981ed1bdd3ee3d0128a1e2306b2bee8978d1f0a930d6127"
"SHA256=ca87d972e102a9f960fed41f90d2736a73079fcc7e787187028f455ad58b1637"
)
set(FALCOSECURITY_RULES_FALCO_PATH
"${PROJECT_BINARY_DIR}/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml"

View File

@@ -1,26 +1,37 @@
FROM debian:buster
ARG FALCO_COMMIT_SHA
ARG FALCO_VERSION=latest
LABEL org.opencontainers.image.authors='The Falco Authors https://falco.org' \
org.opencontainers.image.url='https://falco.org' \
org.opencontainers.image.source='https://github.com/falcosecurity/falco' \
org.opencontainers.image.vendor='Falco Organization' \
org.opencontainers.image.licenses='Apache-2.0' \
org.opencontainers.image.revision=${FALCO_COMMIT_SHA} \
org.opencontainers.image.version=${FALCO_VERSION} \
maintainer="cncf-falco-dev@lists.cncf.io"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader:latest-buster [driver] [options]"
ARG TARGETARCH
ARG FALCO_VERSION=latest
ARG VERSION_BUCKET=deb
ENV VERSION_BUCKET=${VERSION_BUCKET}
ENV FALCO_VERSION=${FALCO_VERSION}
ENV HOST_ROOT /host
ENV HOME /root
ENV HOST_ROOT=/host
ENV HOME=/root
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
# Use 20250630T203427Z debian apt snapshot as it still contains support for buster.
RUN cat <<EOF > /etc/apt/sources.list
deb http://snapshot.debian.org/archive/debian/20250630T203427Z buster main
deb http://snapshot.debian.org/archive/debian-security/20250630T203427Z buster/updates main
deb http://snapshot.debian.org/archive/debian/20250630T203427Z buster-updates main
EOF
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash-completion \

View File

@@ -1,17 +1,22 @@
ARG FALCO_IMAGE_TAG=latest
FROM docker.io/falcosecurity/falco:${FALCO_IMAGE_TAG}-debian
ARG FALCO_COMMIT_SHA
ARG FALCO_VERSION
LABEL org.opencontainers.image.authors='The Falco Authors https://falco.org' \
org.opencontainers.image.url='https://falco.org' \
org.opencontainers.image.source='https://github.com/falcosecurity/falco' \
org.opencontainers.image.vendor='Falco Organization' \
org.opencontainers.image.licenses='Apache-2.0' \
org.opencontainers.image.revision=${FALCO_COMMIT_SHA} \
org.opencontainers.image.version=${FALCO_VERSION} \
maintainer="cncf-falco-dev@lists.cncf.io"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader:latest [driver] [options]"
ENV HOST_ROOT /host
ENV HOME /root
ENV HOST_ROOT=/host
ENV HOME=/root
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root

View File

@@ -1,22 +1,26 @@
FROM debian:12-slim
ARG FALCO_COMMIT_SHA
ARG FALCO_VERSION
LABEL org.opencontainers.image.authors='The Falco Authors https://falco.org' \
org.opencontainers.image.url='https://falco.org' \
org.opencontainers.image.source='https://github.com/falcosecurity/falco' \
org.opencontainers.image.vendor='Falco Organization' \
org.opencontainers.image.licenses='Apache-2.0' \
org.opencontainers.image.revision=${FALCO_COMMIT_SHA} \
org.opencontainers.image.version=${FALCO_VERSION} \
maintainer="cncf-falco-dev@lists.cncf.io"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /proc:/host/proc:ro -v /etc:/host/etc:ro falcosecurity/falco:latest-debian"
ARG FALCO_VERSION
ARG VERSION_BUCKET=deb
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
ENV HOST_ROOT /host
ENV HOME /root
ENV HOST_ROOT=/host
ENV HOME=/root
RUN apt-get -y update && apt-get -y install ca-certificates curl jq ca-certificates gnupg2 \
&& apt clean -y && rm -rf /var/lib/apt/lists/*

View File

@@ -1,22 +1,26 @@
FROM cgr.dev/chainguard/wolfi-base
ARG FALCO_COMMIT_SHA
ARG FALCO_VERSION
LABEL org.opencontainers.image.authors='The Falco Authors https://falco.org' \
org.opencontainers.image.url='https://falco.org' \
org.opencontainers.image.source='https://github.com/falcosecurity/falco' \
org.opencontainers.image.vendor='Falco Organization' \
org.opencontainers.image.licenses='Apache-2.0' \
org.opencontainers.image.revision=${FALCO_COMMIT_SHA} \
org.opencontainers.image.version=${FALCO_VERSION} \
maintainer="cncf-falco-dev@lists.cncf.io"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /proc:/host/proc:ro -v /etc:/host/etc:ro falcosecurity/falco:latest"
# NOTE: for the "least privileged" use case, please refer to the official documentation
ARG FALCO_VERSION
ARG VERSION_BUCKET=bin
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
ENV HOST_ROOT /host
ENV HOME /root
ENV HOST_ROOT=/host
ENV HOME=/root
RUN apk update && apk add curl ca-certificates jq libstdc++
@@ -30,12 +34,11 @@ RUN FALCO_VERSION_URLENCODED=$(echo -n ${FALCO_VERSION}|jq -sRr @uri) && \
mv falco-${FALCO_VERSION}-$(uname -m) falco && \
rm -rf /falco/usr/src/falco-* && \
cp -r /falco/* / && \
rm -rf /falco
rm -rf /falco && \
rm -rf /usr/bin/falcoctl /etc/falcoctl/
# Change the falco config within the container to enable ISO 8601 output.
ADD ./config/falco.iso8601_timeformat.yaml /etc/falco/config.d/
# Falcoctl is not included here.
RUN rm -rf /usr/bin/falcoctl /etc/falcoctl/
CMD ["/usr/bin/falco"]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,127 @@
# Legacy eBPF probe, gVisor libscap engine and gRPC output deprecations
## Summary
This proposal aims to formalize motivations and procedures for deprecating the legacy eBPF probe, the gRPC output and
the gVisor libscap engine.
One of the key objectives of Falco is to maintain a seamless user experience, regardless of the system call event source
actually used. This objective imposes strong requirements among all drivers and engines acting as system call source
(i.e.: gVisor libscap engine), feature parity, among each other, above all. Feature parity raises challenges from both
technical and maintainability perspectives, and these challenges are not justified if the driver/engine is no/little
used. For these reasons, this document aims for raising consensus regarding the legacy eBPF probe and gRPC output
deprecation.
Similar arguments could be raised in favor of the gRPC output deprecation: this output requires dependency on the
gRPC framework, that introduces a non-negligible build time overhead and maintainability burden (especially in a C++
codebase), not justified by the little usage of the output.
Upcoming evidences of non-negligible use of the gVisor engine and the gRPC output could be addressed by providing a
separate source plugin in case of gVisor, and a Falco Sidekick output as a replacement of the gRPC output.
## Motivation
### Legacy eBPF probe deprecation
The following matrix details the current minimum kernel version officially supported by each driver, for each
architecture:
| | Kernel module | legacy eBPF probe | Modern eBPF probe | Status |
| ----------- |----------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------| ----------------- | ------ |
| **x86_64** | >= 3.10 | >= 4.14 | >= 5.8 | _STABLE_ |
| **aarch64** | >= [3.16](https://github.com/torvalds/linux/commit/055b1212d141f1f398fca548f8147787c0b6253f) | >= 4.17 | >= 5.8 | _STABLE_ |
| **s390x** | >= 3.10 | >= [5.5](https://github.com/torvalds/linux/commit/6ae08ae3dea) | >= 5.8 | _EXPERIMENTAL_ |
| **riscv64** | >= [5.0](https://github.com/torvalds/linux/commit/5aeb1b36cedd3a1dfdbfe368629fed52dee34103) | N/A | N/A | _EXPERIMENTAL_ |
| **ppc64le** | >= 3.10 | >= [5.1](https://github.com/torvalds/linux/commit/ed1cd6deb013a11959d17a94e35ce159197632da) | >= 5.8 | _STABLE_ |
The legacy eBPF probe strives to provide a little more coverage than the modern eBPF one. This increased coverage comes
at cost of flexibility and maintainability. Indeed:
1. it cannot leverage CORE eBPF features - as a result, falcosecurity must maintain a great number of officially
supported eBPF objects, each one built for a specific officially-supported kernel flavor; this increases the
maintainability burden and makes the system less flexible to kernel configurations/structures changes
2. old kernel versions support is difficult to retain - the verifier imposes huge limitations on old kernel versions,
and any tiny change easily result in the verifier rejecting the code
3. it is difficult to keep it up to date with other drivers - some desired features cannot be implemented in any way
using eBPF on old kernel flavors, due to lack of eBPF helpers/program types or verifier limitations (e.g.: there is no
way of implementing a synchronous data harvesting mechanism like the one provided by BPF iterators). As falcosecurity
strives for feature parity among drivers, this imposes a big limitation on the other drivers. Please notice that:
1. the kernel module is unconstrained on the nature of feature it can support
2. the modern eBPF probe can easily rely on CORE features to probe for kernel features and use them if available
Besides the above, the legacy eBPF probe provides support for a range of versions that is entirely contained by the
kernel module supported range. Additionally, different distro kernel flavors already back-port features required by the
modern eBPF, enabling its usage on kernel older than `5.8`.
The above considerations, together with the evidence of its little usage, make the legacy eBPF probe a good candidate
for deprecation.
### gVisor libscap engine deprecation
gVisor libscap engine implements a system call event source by leveraging events coming from gVisor itself through gRPC.
There is evidence that this engine is little used. Moreover, gVisor doesn't provide all information required to build
all supported event types, indeed resulting in a system call source not completely equivalent to the ones provided by
drivers. Finally, it requires `falcosecurity/libs` being dependent on protobuf, this latter introducing a non-negligible
build time overhead and maintainability burden.
Deprecating it would allow to streamline system call event sources alignment, maintainability, and reduce build time for
both `falcosecurity/falco` and `falcosecurity/libs`.
### gRPC output deprecation
The gRPC output provides a mechanism through which a gRPC client can subscribe to the Falco alerts stream. This output
leverages a gRPC server embedded into Falco.
As for the legacy eBPF probe and the gVisor libscap engine, there is evidence that this output is little used. Also,
similarly to the gVisor libscap engine, this requires Falco being dependent on the protobuf, and additionally, on the
entire C++ gRPC framework. Finally, the little amount of data that is sent through the gRPC stream, and the
communication model (only involving a one-way communication from the server to the client) doesn't justify the need of
using gRPC.
Deprecating it would allow to reduce the build system, streamline maintainability, and reduce build time for
`falcosecurity/falco`.
## Goals
* Deprecate the legacy eBPF probe, the gVisor libscap engine, and the gRPC output
* Detail a plan to follow during the deprecation period, before completely remove any of the aforementioned components
## Non-goals
* Implement a gVisor source plugin as gVisor libscap engine alternative
* Implement the gRPC output as Falco Sidekick output
* Detail a plan to follow after taking the decision to completely remove any of the aforementioned components
## The plan
This section aims to detail the plan to follow contextually and after the deprecation mark, but before taking any
definitive removal decision about the legacy eBPF probe, the gVisor libscap engine, and the gRPC output (collectively
referred to hereinafter as "the components" or simply "components").
The deprecation of these components introduces user-facing changes that must be addressed as prescribed by the current
deprecation policy for "non-backward compatible user-facing changes" (see
[20231220-features-adoption-and-deprecation.md#deprecation-policy](./20231220-features-adoption-and-deprecation.md#deprecation-policy)).
All components are stable, and given that the current stable Falco version is `0.42.1` (ante `1.0.0`), the minimum
deprecation period length is 1 release: this means that components cannot be removed before Falco `0.44.0`.
At high level, the action plan is to inform users, during the deprecation period, about the deprecation: this is
achieved by emitting a deprecation notice if the user try to leverage any of the feature exposed by any component, and
by updating the website in any of the relevant areas.
During the deprecation period, but before taking decision to remove the components, projects belonging to the
`falcosecurity` organization will be updated to not use/rely on any of these. Specifically:
- on `falcosecurity/libs`, any CI job building and testing the legacy eBPF probe will be removed
- on `falcosecurity/kernel-testing`, playbooks will not build and test the legacy eBPF probe anymore
- on `falcosecurity/event-generator`, the internal gRPC alert retriever will be replaced with an HTTP alert retriever,
leveraging the existing HTTP output.
## The non-plan
This proposal does not address any design or implementation aspect of the gVisor engine and gRPC output replacement, nor
formalizes in any way the conditions under which a replacement should be delivered. Upcoming evidences of non-negligible
use of the gVisor engine and the gRPC output may be addressed by providing a separate source plugin in case of gVisor,
and a Falco Sidekick output as a replacement of the gRPC output, but these latter possibilities should be intended as
suggestions, and will not constraint in any way any related future choice.
Finally, this proposal doesn't detail any aspect of the eventual removal.

View File

@@ -7,10 +7,10 @@ driver:
hostroot: "/"
artifact:
follow:
every: 6h0m0s
every: 168h0m0s
falcoVersions: http://localhost:8765/versions
refs:
- falco-rules:4
- falco-rules:5
indexes:
- name: falcosecurity
url: https://falcosecurity.github.io/falcoctl/index.yaml

View File

@@ -45,6 +45,7 @@ add_executable(
engine/test_plugin_requirements.cpp
engine/test_rule_loader.cpp
engine/test_rulesets.cpp
falco/test_capture.cpp
falco/test_configuration.cpp
falco/test_configuration_rule_selection.cpp
falco/test_configuration_config_files.cpp

View File

@@ -15,14 +15,16 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include <string>
#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();
rule_loader::context ctx("test");
rule_loader::result res("test");
filter_warning_resolver().run(ctx, res, *ast.get());
return res.has_warnings();
}
TEST(WarningResolver, warnings_in_filtering_conditions) {
@@ -38,4 +40,8 @@ TEST(WarningResolver, warnings_in_filtering_conditions) {
ASSERT_TRUE(warns("ka.field intersects (otherval, <NA>)"));
ASSERT_TRUE(warns("ka.field pmatch (<NA>)"));
ASSERT_TRUE(warns("ka.field pmatch (otherval, <NA>)"));
ASSERT_TRUE(warns("evt.dir = <"));
ASSERT_TRUE(warns("evt.dir = >"));
ASSERT_TRUE(warns("proc.name=test and evt.dir = <"));
ASSERT_TRUE(warns("evt.dir = < and proc.name=test"));
}

View File

@@ -1327,3 +1327,36 @@ TEST_F(test_falco_engine, empty_string_source_addl_rule) {
EXPECT_TRUE(load_rules(rules_content, "rules.yaml"));
}
TEST_F(test_falco_engine, deprecated_field_in_output) {
std::string rules_content = R"END(
- rule: test_rule_with_evt_dir_in_output
desc: test rule with evt.dir in output
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name evt.dir=%evt.dir
priority: INFO
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
ASSERT_TRUE(has_warnings());
ASSERT_TRUE(check_warning_message(
"usage of deprecated field 'evt.dir' has been detected in the rule output"))
<< m_load_result_string;
EXPECT_EQ(num_rules_for_ruleset(), 1);
}
TEST_F(test_falco_engine, no_deprecated_field_warning_in_output) {
std::string rules_content = R"END(
- rule: test_rule_without_evt_dir
desc: test rule without evt.dir in output
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_VALIDATION_STATUS(yaml_helper::validation_ok) << m_load_result->schema_validation();
ASSERT_FALSE(check_warning_message("evt.dir")) << m_load_result_string;
EXPECT_EQ(num_rules_for_ruleset(), 1);
}

View File

@@ -0,0 +1,134 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2025 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/app/actions/helpers.h>
#include <falco/configuration.h>
#include <gtest/gtest.h>
TEST(Capture, generate_scap_file_path_realistic_scenario) {
// Simulate a realistic timestamp (nanoseconds since epoch)
uint64_t timestamp = 1648178040000000000ULL; // 2022-03-25 04:14:00 CET (03:14:00 UTC) in ns,
// birth date of my son Michelangelo :)
uint64_t evt_num = 1011;
std::string prefix = "/var/log/falco/captures/security_event";
std::string result = falco::app::actions::generate_scap_file_path(prefix, timestamp, evt_num);
std::string expected =
"/var/log/falco/captures/security_event_01648178040000000000_00000000000000001011.scap";
EXPECT_EQ(result, expected);
}
TEST(Capture, generate_scap_file_path_lexicographic_ordering) {
std::string prefix = "/tmp/test";
// Generate multiple file paths with different timestamps
std::string path1 = falco::app::actions::generate_scap_file_path(prefix, 1000, 1);
std::string path2 = falco::app::actions::generate_scap_file_path(prefix, 2000, 1);
std::string path3 = falco::app::actions::generate_scap_file_path(prefix, 10000, 1);
// Verify lexicographic ordering (important for file sorting)
EXPECT_LT(path1, path2);
EXPECT_LT(path2, path3);
// Also test with same timestamp but different event numbers
std::string path4 = falco::app::actions::generate_scap_file_path(prefix, 1000, 1);
std::string path5 = falco::app::actions::generate_scap_file_path(prefix, 1000, 2);
std::string path6 = falco::app::actions::generate_scap_file_path(prefix, 1000, 100);
EXPECT_LT(path4, path5);
EXPECT_LT(path5, path6);
}
TEST(Capture, generate_scap_file_path_empty_prefix) {
std::string prefix = "";
uint64_t timestamp = 123;
uint64_t evt_num = 456;
std::string result = falco::app::actions::generate_scap_file_path(prefix, timestamp, evt_num);
std::string expected = "_00000000000000000123_00000000000000000456.scap";
EXPECT_EQ(result, expected);
}
TEST(Capture, capture_config_disabled_by_default) {
std::string config_content = R"(
plugins:
)";
falco_configuration config;
config_loaded_res res;
ASSERT_NO_THROW(res = config.init_from_content(config_content, {}));
// Capture should be disabled by default
EXPECT_FALSE(config.m_capture_enabled);
EXPECT_EQ(config.m_capture_path_prefix, "/tmp/falco");
EXPECT_EQ(config.m_capture_mode, capture_mode_t::RULES);
EXPECT_EQ(config.m_capture_default_duration_ns, 5000 * 1000000LL); // 5 seconds in ns
}
TEST(Capture, capture_config_enabled_rules_mode) {
std::string config_content = R"(
capture:
enabled: true
path_prefix: /var/log/captures/falco
mode: rules
default_duration: 10000
)";
falco_configuration config;
config_loaded_res res;
ASSERT_NO_THROW(res = config.init_from_content(config_content, {}));
EXPECT_TRUE(config.m_capture_enabled);
EXPECT_EQ(config.m_capture_path_prefix, "/var/log/captures/falco");
EXPECT_EQ(config.m_capture_mode, capture_mode_t::RULES);
EXPECT_EQ(config.m_capture_default_duration_ns, 10000 * 1000000LL); // 10 seconds in ns
}
TEST(Capture, capture_config_enabled_all_rules_mode) {
std::string config_content = R"(
capture:
enabled: true
path_prefix: /tmp/debug/falco
mode: all_rules
default_duration: 30000
)";
falco_configuration config;
config_loaded_res res;
ASSERT_NO_THROW(res = config.init_from_content(config_content, {}));
EXPECT_TRUE(config.m_capture_enabled);
EXPECT_EQ(config.m_capture_path_prefix, "/tmp/debug/falco");
EXPECT_EQ(config.m_capture_mode, capture_mode_t::ALL_RULES);
EXPECT_EQ(config.m_capture_default_duration_ns, 30000 * 1000000LL); // 30 seconds in ns
}
TEST(Capture, capture_config_invalid_mode) {
std::string config_content = R"(
capture:
enabled: true
mode: invalid_mode
)";
falco_configuration config;
config_loaded_res res;
// Should throw an exception for invalid mode
EXPECT_THROW(res = config.init_from_content(config_content, {}), std::logic_error);
}

View File

@@ -92,7 +92,6 @@ TEST(Configuration, configuration_config_files_ok) {
outfile.close();
std::vector<std::string> cmdline_config_options;
std::vector<std::string> loaded_conf_files;
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));

View File

@@ -1,10 +1,9 @@
#include "test_falco_engine.h"
test_falco_engine::test_falco_engine() {
test_falco_engine::test_falco_engine(): m_engine(std::make_shared<falco_engine>()) {
// create a falco engine ready to load the ruleset
m_filter_factory = std::make_shared<sinsp_filter_factory>(&m_inspector, m_filterlist);
m_formatter_factory = std::make_shared<sinsp_evt_formatter_factory>(&m_inspector, m_filterlist);
m_engine = std::make_shared<falco_engine>();
m_engine->add_source(m_sample_source, m_filter_factory, m_formatter_factory);
}

View File

@@ -56,7 +56,7 @@ bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt,
filter_wrapper_list &wrappers,
uint16_t ruleset_id,
falco_rule &match) {
for(auto &wrap : wrappers) {
for(const auto &wrap : wrappers) {
if(wrap->m_filter->run(evt)) {
match = wrap->m_rule;
return true;
@@ -72,7 +72,7 @@ bool evttype_index_ruleset::run_wrappers(sinsp_evt *evt,
std::vector<falco_rule> &matches) {
bool match_found = false;
for(auto &wrap : wrappers) {
for(const auto &wrap : wrappers) {
if(wrap->m_filter->run(evt)) {
matches.push_back(wrap->m_rule);
match_found = true;

View File

@@ -43,7 +43,7 @@ struct evttype_index_wrapper {
class evttype_index_ruleset : public indexable_ruleset<evttype_index_wrapper> {
public:
explicit evttype_index_ruleset(std::shared_ptr<sinsp_filter_factory> factory);
virtual ~evttype_index_ruleset();
virtual ~evttype_index_ruleset() override;
// From filter_ruleset
void add(const falco_rule &rule,

View File

@@ -29,6 +29,8 @@ limitations under the License.
#define DEFAULT_OUTPUTS_QUEUE_CAPACITY_UNBOUNDED_MAX_LONG_VALUE std::ptrdiff_t(~size_t(0) / 2)
#define DEFAULT_FALCO_LIBS_THREAD_TABLE_SIZE 262144
#define DEFAULT_FALCO_LIBS_THREAD_TABLE_AUTO_PURGING_INTERVAL_S (5 * 60) // 5 minutes.
#define DEFAULT_FALCO_LIBS_THREAD_TABLE_AUTO_PURGING_THREAD_TIMEOUT_S (5 * 60) // 5 minutes.
//
// Most falco_* classes can throw exceptions. Unless directly related

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -413,6 +413,8 @@ std::unique_ptr<std::vector<falco_engine::rule_result>> falco_engine::process_ev
rule_result.source = rule.source;
rule_result.format = rule.output;
rule_result.priority_num = rule.priority;
rule_result.capture = rule.capture;
rule_result.capture_duration_ns = uint64_t(rule.capture_duration) * 1000000LL;
rule_result.tags = rule.tags;
rule_result.exception_fields = rule.exception_fields;
rule_result.extra_output_fields = rule.extra_output_fields;
@@ -568,6 +570,8 @@ void falco_engine::get_json_details(
rule_info["description"] = r.description;
rule_info["enabled"] = info.enabled;
rule_info["source"] = r.source;
rule_info["capture"] = r.capture;
rule_info["capture_duration"] = r.capture_duration;
rule_info["tags"] = sequence_to_json_array(info.tags);
out["info"] = std::move(rule_info);

View File

@@ -228,6 +228,8 @@ public:
std::set<std::string> exception_fields;
std::set<std::string> tags;
extra_output_field_t extra_output_fields;
bool capture;
uint64_t capture_duration_ns;
};
//

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -20,7 +20,7 @@ limitations under the License.
// The version of this Falco engine
#define FALCO_ENGINE_VERSION_MAJOR 0
#define FALCO_ENGINE_VERSION_MINOR 50
#define FALCO_ENGINE_VERSION_MINOR 58
#define FALCO_ENGINE_VERSION_PATCH 0
#define FALCO_ENGINE_VERSION \
@@ -36,4 +36,4 @@ limitations under the License.
// It represents the fields supported by this version of Falco,
// the event types, and the underlying driverevent schema. It's used to
// detetect changes in engine version in our CI jobs.
#define FALCO_ENGINE_CHECKSUM "c111251b08cfb00790515cd62fbe0b6c3d0b62035f7d9bbb1aea80f41d7986f9"
#define FALCO_ENGINE_CHECKSUM "952fa3356bfd266419810be51ae659eab48093a66da26fff3897022a9de2c08c"

View File

@@ -75,8 +75,14 @@ static const std::string warning_codes[] = {"LOAD_UNKNOWN_SOURCE",
"LOAD_INVALID_LIST_NAME",
"LOAD_COMPILE_CONDITION"};
// Compile-time check to ensure warning_codes array has the correct size
static_assert(std::size(warning_codes) ==
static_cast<int>(falco::load_result::warning_code::LOAD_COMPILE_CONDITION) +
1,
"warning_codes array size must match the last warning_code enum value + 1");
const std::string& falco::load_result::warning_code_str(warning_code wc) {
return warning_codes[wc];
return warning_codes[static_cast<int>(wc)];
}
static const std::string warning_strings[] = {"Unknown event source",
@@ -94,8 +100,14 @@ static const std::string warning_strings[] = {"Unknown event source",
"Invalid list name",
"Warning in rule condition"};
// Compile-time check to ensure warning_strings array has the correct size
static_assert(std::size(warning_strings) ==
static_cast<int>(falco::load_result::warning_code::LOAD_COMPILE_CONDITION) +
1,
"warning_strings array size must match the last warning_code enum value + 1");
const std::string& falco::load_result::warning_str(warning_code wc) {
return warning_strings[wc];
return warning_strings[static_cast<int>(wc)];
}
static const std::string warning_descs[] = {
@@ -121,6 +133,60 @@ static const std::string warning_descs[] = {
"A list is defined with an invalid name",
"A rule condition or output have been parsed with a warning"};
// Compile-time check to ensure warning_descs array has the correct size
static_assert(std::size(warning_descs) ==
static_cast<int>(falco::load_result::warning_code::LOAD_COMPILE_CONDITION) +
1,
"warning_descs array size must match the last warning_code enum value + 1");
const std::string& falco::load_result::warning_desc(warning_code wc) {
return warning_descs[wc];
return warning_descs[static_cast<int>(wc)];
}
static const std::string deprecated_fields[] = {"evt.dir",
"evt.latency",
"evt.latency.s",
"evt.latency.ns",
"evt.latency.human",
"evt.wait_latency"};
// Compile-time check to ensure deprecated_fields array has the correct size
static_assert(
std::size(deprecated_fields) ==
static_cast<int>(falco::load_result::deprecated_field::DEPRECATED_FIELD_NOT_FOUND),
"deprecated_fields array size must match DEPRECATED_FIELD_NOT_FOUND enum value");
const std::string& falco::load_result::deprecated_field_str(deprecated_field df) {
return deprecated_fields[static_cast<int>(df)];
}
// Shared description suffix for latency fields
static const std::string latency_field_desc_suffix =
"field is not available due to the drop of enter events.";
static const std::string deprecated_field_descs[] = {
"due to the drop of enter events, 'evt.dir = <' always evaluates to true, and 'evt.dir = "
">' always evaluates to false. The rule expression can be simplified by removing the "
"condition on 'evt.dir'",
latency_field_desc_suffix,
latency_field_desc_suffix,
latency_field_desc_suffix,
latency_field_desc_suffix,
latency_field_desc_suffix};
// Compile-time check to ensure deprecated_field_descs array has the correct size
static_assert(
std::size(deprecated_field_descs) ==
static_cast<int>(falco::load_result::deprecated_field::DEPRECATED_FIELD_NOT_FOUND),
"deprecated_field_descs array size must match DEPRECATED_FIELD_NOT_FOUND enum value");
const std::string& falco::load_result::deprecated_field_desc(deprecated_field df) {
return deprecated_field_descs[static_cast<int>(df)];
}
falco::load_result::deprecated_field falco::load_result::deprecated_field_from_str(
const std::string& f) {
return falco::load_result::deprecated_field(
std::find(std::begin(deprecated_fields), std::end(deprecated_fields), f) -
std::begin(deprecated_fields));
}

View File

@@ -46,7 +46,9 @@ public:
// impact.
static const std::string& error_desc(error_code ec);
enum warning_code {
virtual ~load_result() = default;
enum class warning_code {
LOAD_UNKNOWN_SOURCE = 0,
LOAD_UNSAFE_NA_CHECK,
LOAD_NO_EVTTYPE,
@@ -63,8 +65,6 @@ public:
LOAD_COMPILE_CONDITION
};
virtual ~load_result() = default;
// The warning code as a string
static const std::string& warning_code_str(warning_code ec);
@@ -75,6 +75,27 @@ public:
// impact.
static const std::string& warning_desc(warning_code ec);
enum class deprecated_field {
DEPRECATED_FIELD_EVT_DIR,
DEPRECATED_FIELD_EVT_LATENCY,
DEPRECATED_FIELD_EVT_LATENCY_S,
DEPRECATED_FIELD_EVT_LATENCY_NS,
DEPRECATED_FIELD_EVT_LATENCY_HUMAN,
DEPRECATED_FIELD_EVT_WAIT_LATENCY,
DEPRECATED_FIELD_NOT_FOUND
};
// The deprecated field as a string
static const std::string& deprecated_field_str(deprecated_field df);
// A longer description of what the deprecated field represents and the
// impact.
static const std::string& deprecated_field_desc(deprecated_field df);
// Return the deprecated field from a field string name, or DEPRECATED_FIELD_NOT_FOUND if the
// field is not deprecated
static deprecated_field deprecated_field_from_str(const std::string& f);
// If true, the rules were loaded successfully and can be used
// against events. If false, there were one or more
// errors--use one of the as_xxx methods to return information

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -77,7 +77,11 @@ struct falco_macro {
The rule ID must be unique across all the rules loaded in the engine.
*/
struct falco_rule {
falco_rule(): id(0), priority(falco_common::PRIORITY_DEBUG) {}
falco_rule():
id(0),
priority(falco_common::PRIORITY_DEBUG),
capture(false),
capture_duration(0) {}
falco_rule(falco_rule&&) = default;
falco_rule& operator=(falco_rule&&) = default;
falco_rule(const falco_rule&) = default;
@@ -91,7 +95,9 @@ struct falco_rule {
return (this->id == rhs.id && this->source == rhs.source && this->name == rhs.name &&
this->description == rhs.description && this->output == rhs.output &&
this->tags == rhs.tags && this->exception_fields == rhs.exception_fields &&
this->priority == rhs.priority && this->condition.get() == rhs.condition.get() &&
this->priority == rhs.priority && this->capture == rhs.capture &&
this->capture_duration == rhs.capture_duration &&
this->condition.get() == rhs.condition.get() &&
this->filter.get() == rhs.filter.get());
}
@@ -104,6 +110,8 @@ struct falco_rule {
std::set<std::string> tags;
std::set<std::string> exception_fields;
falco_common::priority_type priority;
bool capture;
uint32_t capture_duration;
std::shared_ptr<libsinsp::filter::ast::expr> condition;
std::shared_ptr<sinsp_filter> filter;
};

View File

@@ -120,11 +120,10 @@ uint64_t parse_prometheus_interval(std::string interval_str) {
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];
uint64_t cur_interval = 0;
std::string cur_interval_str = args[group_it->second - 1];
if(!cur_interval_str.empty()) {
cur_interval = std::stoull(cur_interval_str, nullptr, 0);
}

View File

@@ -15,6 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
#include <string>
#include <libsinsp/sinsp.h>
#include "filter_warning_resolver.h"
@@ -32,14 +33,30 @@ static inline bool is_equality_operator(const std::string& op) {
op == "pmatch";
}
bool filter_warning_resolver::run(libsinsp::filter::ast::expr* filter,
std::set<load_result::warning_code>& warnings) const {
visitor v;
auto size = warnings.size();
bool filter_warning_resolver::run(const rule_loader::context& ctx,
rule_loader::result& res,
libsinsp::filter::ast::expr& filter) const {
std::set<falco::load_result::warning_code> warnings;
std::set<falco::load_result::deprecated_field> deprecated_fields;
visitor v(warnings, deprecated_fields);
v.m_is_equality_check = false;
v.m_warnings = &warnings;
filter->accept(&v);
return warnings.size() > size;
filter.accept(&v);
for(auto& w : warnings) {
switch(w) {
case falco::load_result::warning_code::LOAD_DEPRECATED_ITEM:
// add a warning for each deprecated field
for(auto& deprecated_field : deprecated_fields) {
res.add_deprecated_field_warning(
deprecated_field,
falco::load_result::deprecated_field_desc(deprecated_field),
ctx);
}
break;
default:
res.add_warning(w, "", ctx);
}
}
return !warnings.empty();
}
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::binary_check_expr* e) {
@@ -54,17 +71,24 @@ void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::binary_check
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::field_expr* e) {
m_last_node_is_unsafe_field = is_unsafe_field(e->field);
// Check for deprecated dir field usage
if(auto df = falco::load_result::deprecated_field_from_str(e->field);
df != falco::load_result::deprecated_field::DEPRECATED_FIELD_NOT_FOUND) {
m_deprecated_fields->insert(df);
m_warnings->insert(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM);
}
}
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::value_expr* e) {
if(m_is_equality_check && e->value == no_value) {
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
m_warnings->insert(falco::load_result::warning_code::LOAD_UNSAFE_NA_CHECK);
}
}
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::list_expr* e) {
if(m_is_equality_check &&
std::find(e->values.begin(), e->values.end(), no_value) != e->values.end()) {
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
m_warnings->insert(falco::load_result::warning_code::LOAD_UNSAFE_NA_CHECK);
}
}

View File

@@ -23,6 +23,7 @@ limitations under the License.
#include <memory>
#include "falco_common.h"
#include "falco_load_result.h"
#include "rule_loader.h"
/*!
\brief Searches for bad practices in filter conditions and
@@ -31,25 +32,23 @@ limitations under the License.
class filter_warning_resolver {
public:
/*!
\brief Visits a filter AST and substitutes macro references
according with all the definitions added through set_macro(),
by replacing the reference with a clone of the macro AST.
\brief Runs the filter warning resolver on a filter AST and adds the warnings to the result
object \param ctx The context of the warning \param res The result to add the warnings to
\param filter The filter AST to be visited
\param warnings Set of strings to be filled with warning codes. This
is not cleared up before the visit
\param blocking Filled-out with true if at least one warning is
found and at least one warning prevents the filter from being loaded
\return true if at least one warning is generated
*/
bool run(libsinsp::filter::ast::expr* filter,
std::set<falco::load_result::warning_code>& warnings) const;
bool run(const rule_loader::context& ctx,
rule_loader::result& res,
libsinsp::filter::ast::expr& filter) const;
private:
struct visitor : public libsinsp::filter::ast::base_expr_visitor {
visitor():
visitor(std::set<falco::load_result::warning_code>& warnings,
std::set<falco::load_result::deprecated_field>& deprecated_fields):
m_is_equality_check(false),
m_last_node_is_unsafe_field(false),
m_warnings(nullptr) {}
m_warnings(&warnings),
m_deprecated_fields(&deprecated_fields) {}
visitor(visitor&&) = default;
visitor& operator=(visitor&&) = default;
visitor(const visitor&) = delete;
@@ -58,6 +57,7 @@ private:
bool m_is_equality_check;
bool m_last_node_is_unsafe_field;
std::set<falco::load_result::warning_code>* m_warnings;
std::set<falco::load_result::deprecated_field>* m_deprecated_fields;
void visit(libsinsp::filter::ast::value_expr* e) override;
void visit(libsinsp::filter::ast::list_expr* e) override;

View File

@@ -57,8 +57,6 @@ std::string falco_formats::format_event(sinsp_evt *evt,
message_format = "*" + message_format;
}
std::shared_ptr<sinsp_evt_formatter> formatter;
auto prefix_formatter = m_falco_engine->create_formatter(source, prefix_format);
auto message_formatter = m_falco_engine->create_formatter(source, message_format);

View File

@@ -46,7 +46,7 @@ template<class filter_wrapper>
class indexable_ruleset : public filter_ruleset {
public:
indexable_ruleset() = default;
virtual ~indexable_ruleset() = default;
virtual ~indexable_ruleset() override = default;
// Required to implement filter_ruleset
void clear() override {
@@ -229,7 +229,7 @@ private:
// A group of filters all having the same ruleset
class ruleset_filters {
public:
ruleset_filters(uint16_t ruleset_id): m_ruleset_id(ruleset_id) {}
explicit ruleset_filters(uint16_t ruleset_id): m_ruleset_id(ruleset_id) {}
virtual ~ruleset_filters() {};

View File

@@ -128,15 +128,9 @@ void falco_logger::log(falco_logger::level priority, const std::string&& msg) {
}
} else {
const struct tm* ltm = std::localtime(&result);
char* atime = (ltm ? std::asctime(ltm) : NULL);
std::string tstr;
if(atime) {
tstr = atime;
tstr = tstr.substr(0, 24); // remove trailing newline
} else {
tstr = "N/A";
}
fprintf(stderr, "%s: %s", tstr.c_str(), copy.c_str());
char tstr[std::size("WWW MMM DD HH:mm:ss YYYY")];
std::strftime(std::data(tstr), std::size(tstr), "%a %b %d %H:%M:%S %Y", ltm);
fprintf(stderr, "%s: %s", tstr, copy.c_str());
}
}
}

View File

@@ -74,6 +74,12 @@ const char rule_schema_string[] = LONG_STRING_CONST(
"priority": {
"$ref": "#/definitions/Priority"
},
"capture": {
"type": "boolean"
},
"capture_duration": {
"type": "integer"
},
"source": {
"type": "string"
},

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -116,7 +116,7 @@ void rule_loader::context::init(const std::string& name,
m_locs.push_back(loc);
}
std::string rule_loader::context::as_string() {
std::string rule_loader::context::as_string() const {
std::ostringstream os;
// All valid contexts should have at least one location.
@@ -142,7 +142,7 @@ std::string rule_loader::context::as_string() {
return os.str();
}
nlohmann::json rule_loader::context::as_json() {
nlohmann::json rule_loader::context::as_json() const {
nlohmann::json ret;
ret["locations"] = nlohmann::json::array();
@@ -282,9 +282,13 @@ void rule_loader::result::add_error(load_result::error_code ec,
void rule_loader::result::add_warning(load_result::warning_code wc,
const std::string& msg,
const context& ctx) {
warning warn = {wc, msg, ctx};
warnings.emplace_back(std::make_unique<warning>(wc, msg, ctx));
}
warnings.push_back(warn);
void rule_loader::result::add_deprecated_field_warning(load_result::deprecated_field df,
const std::string& msg,
const context& ctx) {
warnings.emplace_back(std::make_unique<deprecated_field_warning>(df, msg, ctx));
}
void rule_loader::result::set_schema_validation_status(const std::vector<std::string>& status) {
@@ -329,7 +333,7 @@ const std::string& rule_loader::result::as_summary_string() {
os << " " << schema_validation_status.size() << " schema warnings: [";
bool first = true;
for(auto& status : schema_validation_status) {
for(const auto& status : schema_validation_status) {
if(!first) {
os << " ";
}
@@ -369,8 +373,7 @@ const std::string& rule_loader::result::as_summary_string() {
}
first = false;
os << load_result::warning_code_str(warn.wc) << " ("
<< load_result::warning_str(warn.wc) << ")";
os << warn->code_string() << " (" << warn->as_string() << ")";
}
os << "]";
}
@@ -409,7 +412,7 @@ const std::string& rule_loader::result::as_verbose_string(const rules_contents_t
os << schema_validation_status.size() << " Schema warnings:" << std::endl;
for(auto& status : schema_validation_status) {
for(const auto& status : schema_validation_status) {
os << "------" << std::endl;
os << status << std::endl;
}
@@ -438,14 +441,13 @@ const std::string& rule_loader::result::as_verbose_string(const rules_contents_t
os << warnings.size() << " Warnings:" << std::endl;
for(auto& warn : warnings) {
os << warn.ctx.as_string();
os << warn->ctx.as_string();
os << "------" << std::endl;
os << warn.ctx.snippet(contents);
os << warn->ctx.snippet(contents);
os << "------" << std::endl;
os << load_result::warning_code_str(warn.wc) << " ("
<< load_result::warning_str(warn.wc) << "): " << warn.msg;
os << warn->code_string() << " (" << warn->as_string() << "): " << warn->msg;
os << std::endl;
}
}
@@ -492,16 +494,7 @@ const nlohmann::json& rule_loader::result::as_json(const rules_contents_t& conte
j["warnings"] = nlohmann::json::array();
for(auto& warn : warnings) {
nlohmann::json jwarn;
jwarn["context"] = warn.ctx.as_json();
jwarn["context"]["snippet"] = warn.ctx.snippet(contents);
jwarn["code"] = load_result::warning_code_str(warn.wc);
jwarn["codedesc"] = load_result::warning_desc(warn.wc);
jwarn["message"] = warn.msg;
j["warnings"].push_back(jwarn);
j["warnings"].push_back(warn->as_json(contents));
}
res_json = j;
@@ -532,6 +525,8 @@ rule_loader::rule_info::rule_info(context& ctx):
visibility(0),
unknown_source(false),
priority(falco_common::PRIORITY_DEBUG),
capture(false),
capture_duration(0),
enabled(true),
warn_evttypes(true),
skip_if_unknown_filter(false) {}

View File

@@ -154,8 +154,8 @@ public:
std::string snippet(const falco::load_result::rules_contents_t& rules_contents,
size_t snippet_width = default_snippet_width) const;
std::string as_string();
nlohmann::json as_json();
std::string as_string() const;
nlohmann::json as_json() const;
private:
void init(const std::string& name,
@@ -183,15 +183,52 @@ struct warning {
msg(m),
ctx(c) {}
warning(warning&&) = default;
warning& operator=(warning&&) = default;
warning(const warning&) = default;
warning& operator=(const warning&) = default;
virtual ~warning() = default;
virtual std::string code_string() const { return falco::load_result::warning_code_str(wc); };
virtual std::string as_string() const { return falco::load_result::warning_str(wc); };
virtual std::string description() const { return falco::load_result::warning_desc(wc); };
virtual nlohmann::json as_json(const falco::load_result::rules_contents_t& contents) const {
nlohmann::json jwarn;
jwarn["context"] = ctx.as_json();
jwarn["context"]["snippet"] = ctx.snippet(contents);
jwarn["code"] = falco::load_result::warning_code_str(wc);
jwarn["codedesc"] = falco::load_result::warning_desc(wc);
jwarn["message"] = msg;
return jwarn;
};
falco::load_result::warning_code wc;
std::string msg;
context ctx;
};
struct deprecated_field_warning : warning {
deprecated_field_warning(): warning() {}
deprecated_field_warning(falco::load_result::deprecated_field df,
const std::string& m,
const context& c):
warning(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM, m, c),
df(df) {}
std::string as_string() const override {
return warning::as_string() + ": field '" + falco::load_result::deprecated_field_str(df);
};
std::string description() const override {
return warning::description() + ": " + falco::load_result::deprecated_field_desc(df);
};
nlohmann::json as_json(const falco::load_result::rules_contents_t& contents) const override {
auto jwarn = warning::as_json(contents);
jwarn["deprecated_field"] = falco::load_result::deprecated_field_str(df);
return jwarn;
};
falco::load_result::deprecated_field df;
};
struct error {
error(): ec(falco::load_result::error_code::LOAD_ERR_FILE_READ), ctx("no-filename-given") {}
error(falco::load_result::error_code e, const std::string& m, const context& c):
@@ -228,7 +265,7 @@ public:
class result : public falco::load_result {
public:
explicit result(const std::string& name);
virtual ~result() = default;
virtual ~result() override = default;
result(result&&) = default;
result& operator=(result&&) = default;
result(const result&) = default;
@@ -248,6 +285,9 @@ public:
void add_warning(falco::load_result::warning_code ec,
const std::string& msg,
const context& ctx);
void add_deprecated_field_warning(falco::load_result::deprecated_field df,
const std::string& msg,
const context& ctx);
void set_schema_validation_status(const std::vector<std::string>& status);
std::string schema_validation() override;
@@ -260,7 +300,7 @@ protected:
std::vector<std::string> schema_validation_status;
std::vector<error> errors;
std::vector<warning> warnings;
std::vector<std::unique_ptr<warning>> warnings;
std::string res_summary_string;
std::string res_verbose_string;
@@ -460,6 +500,8 @@ struct rule_info {
std::set<std::string> tags;
std::vector<rule_exception_info> exceptions;
falco_common::priority_type priority;
bool capture;
uint32_t capture_duration;
bool enabled;
bool warn_evttypes;
bool skip_if_unknown_filter;
@@ -480,7 +522,8 @@ struct rule_update_info {
bool has_any_value() {
return cond.has_value() || output.has_value() || desc.has_value() || tags.has_value() ||
exceptions.has_value() || priority.has_value() || enabled.has_value() ||
warn_evttypes.has_value() || skip_if_unknown_filter.has_value();
capture.has_value() || capture_duration.has_value() || warn_evttypes.has_value() ||
skip_if_unknown_filter.has_value();
}
context ctx;
@@ -493,6 +536,8 @@ struct rule_update_info {
std::optional<std::set<std::string>> tags;
std::optional<std::vector<rule_exception_info>> exceptions;
std::optional<falco_common::priority_type> priority;
std::optional<bool> capture;
std::optional<uint32_t> capture_duration;
std::optional<bool> enabled;
std::optional<bool> warn_evttypes;
std::optional<bool> skip_if_unknown_filter;

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -188,7 +188,7 @@ void rule_loader::collector::define(configuration& cfg, rule_info& info) {
const auto* source = cfg.sources.at(info.source);
if(!source) {
info.unknown_source = true;
cfg.res->add_warning(falco::load_result::LOAD_UNKNOWN_SOURCE,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_UNKNOWN_SOURCE,
"Unknown source " + info.source + ", skipping",
info.ctx);
}
@@ -313,6 +313,14 @@ void rule_loader::collector::selective_replace(configuration& cfg, rule_update_i
prev->priority = *info.priority;
}
if(info.capture.has_value()) {
prev->capture = *info.capture;
}
if(info.capture_duration.has_value()) {
prev->capture_duration = *info.capture_duration;
}
if(info.enabled.has_value()) {
prev->enabled = *info.enabled;
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -19,7 +19,6 @@ limitations under the License.
#include <memory>
#include <set>
#include <vector>
#include <functional>
#include "rule_loader_compiler.h"
#include "filter_warning_resolver.h"
@@ -73,6 +72,24 @@ static bool is_format_valid(const falco_source& source, std::string fmt, std::st
}
}
static void check_deprecated_fields_in_output(const std::string& fmt,
const rule_loader::context& ctx,
rule_loader::result& res) {
// Check for evt.dir field usage in output format
for(int i = 0;
i < static_cast<int>(falco::load_result::deprecated_field::DEPRECATED_FIELD_NOT_FOUND);
i++) {
auto df = falco::load_result::deprecated_field(i);
if(fmt.find(falco::load_result::deprecated_field_str(df)) != std::string::npos) {
res.add_deprecated_field_warning(df,
"usage of deprecated field '" +
falco::load_result::deprecated_field_str(df) +
"' has been detected in the rule output",
ctx);
}
}
}
static void build_rule_exception_infos(
const std::vector<rule_loader::rule_exception_info>& exceptions,
std::set<std::string>& exception_fields,
@@ -160,13 +177,13 @@ static bool resolve_list(std::string& cnd, const falco_list& list) {
static std::string delims = blanks + "(),=";
std::string tmp;
std::string new_cnd;
size_t start, end;
size_t start;
bool used = false;
start = cnd.find(list.name);
while(start != std::string::npos) {
// the characters surrounding the name must
// be delims of beginning/end of string
end = start + list.name.length();
size_t end = start + list.name.length();
if((start == 0 || delims.find(cnd[start - 1]) != std::string::npos) &&
(end >= cnd.length() || delims.find(cnd[end]) != std::string::npos)) {
// shift pointers to consume all whitespaces
@@ -271,7 +288,7 @@ static std::shared_ptr<ast::expr> parse_condition(std::string condition,
}
}
void rule_loader::compiler::compile_list_infos(configuration& cfg,
void rule_loader::compiler::compile_list_infos(const configuration& cfg,
const collector& col,
indexed_vector<falco_list>& out) const {
std::list<std::string> used_names;
@@ -300,7 +317,7 @@ void rule_loader::compiler::compile_list_infos(configuration& cfg,
}
// note: there is a visibility ordering between macros
void rule_loader::compiler::compile_macros_infos(configuration& cfg,
void rule_loader::compiler::compile_macros_infos(const configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& out) const {
@@ -332,7 +349,7 @@ static bool err_is_unknown_type_or_field(const std::string& err) {
err.find("unknown event type") != std::string::npos;
}
bool rule_loader::compiler::compile_condition(configuration& cfg,
bool rule_loader::compiler::compile_condition(const configuration& cfg,
filter_macro_resolver& macro_resolver,
indexed_vector<falco_list>& lists,
const indexed_vector<rule_loader::macro_info>& macros,
@@ -356,11 +373,7 @@ bool rule_loader::compiler::compile_condition(configuration& cfg,
parent_ctx);
// check for warnings in the filtering condition
if(warn_resolver.run(ast_out.get(), warn_codes)) {
for(const auto& w : warn_codes) {
cfg.res->add_warning(w, "", parent_ctx);
}
}
warn_resolver.run(cond_ctx, *cfg.res, *ast_out.get());
// validate the rule's condition: we compile it into a sinsp filter
// on-the-fly and we throw an exception with details on failure
@@ -373,23 +386,23 @@ bool rule_loader::compiler::compile_condition(configuration& cfg,
std::string err = e.what();
rule_loader::context ctx(compiler.get_pos(), condition, cond_ctx);
if(err_is_unknown_type_or_field(err) && allow_unknown_fields) {
cfg.res->add_warning(falco::load_result::load_result::LOAD_UNKNOWN_FILTER, err, ctx);
cfg.res->add_warning(falco::load_result::warning_code::LOAD_UNKNOWN_FILTER, err, ctx);
return false;
}
throw rule_loader::rule_load_exception(
falco::load_result::load_result::LOAD_ERR_COMPILE_CONDITION,
falco::load_result::error_code::LOAD_ERR_COMPILE_CONDITION,
err,
ctx);
}
for(const auto& w : compiler.get_warnings()) {
rule_loader::context ctx(w.pos, condition, cond_ctx);
cfg.res->add_warning(falco::load_result::load_result::LOAD_COMPILE_CONDITION, w.msg, ctx);
cfg.res->add_warning(falco::load_result::warning_code::LOAD_COMPILE_CONDITION, w.msg, ctx);
}
return true;
}
void rule_loader::compiler::compile_rule_infos(configuration& cfg,
void rule_loader::compiler::compile_rule_infos(const configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& macros,
@@ -438,7 +451,7 @@ void rule_loader::compiler::compile_rule_infos(configuration& cfg,
}
if(rule.output.find(s_container_info_fmt) != std::string::npos) {
cfg.res->add_warning(falco::load_result::load_result::LOAD_DEPRECATED_ITEM,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM,
"%container.info is deprecated and no more useful, and will be "
"dropped by Falco 1.0.0. "
"The container plugin will automatically add required fields to "
@@ -473,23 +486,28 @@ void rule_loader::compiler::compile_rule_infos(configuration& cfg,
// skip the rule silently if skip_if_unknown_filter is true and
// we encountered some specific kind of errors
if(err_is_unknown_type_or_field(err) && r.skip_if_unknown_filter) {
cfg.res->add_warning(falco::load_result::load_result::LOAD_UNKNOWN_FILTER,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_UNKNOWN_FILTER,
err,
r.output_ctx);
continue;
}
throw rule_load_exception(falco::load_result::load_result::LOAD_ERR_COMPILE_OUTPUT,
throw rule_load_exception(falco::load_result::error_code::LOAD_ERR_COMPILE_OUTPUT,
err,
r.output_ctx);
}
// check for deprecated fields in output format
check_deprecated_fields_in_output(rule.output, r.output_ctx, *cfg.res);
// validate the rule's extra fields if any
for(auto const& ef : rule.extra_output_fields) {
if(!is_format_valid(*cfg.sources.at(r.source), ef.second.first, err)) {
throw rule_load_exception(falco::load_result::load_result::LOAD_ERR_COMPILE_OUTPUT,
throw rule_load_exception(falco::load_result::error_code::LOAD_ERR_COMPILE_OUTPUT,
err,
r.output_ctx);
}
// check for deprecated fields in extra output fields
check_deprecated_fields_in_output(ef.second.first, r.output_ctx, *cfg.res);
}
if(!compile_condition(cfg,
@@ -511,7 +529,7 @@ void rule_loader::compiler::compile_rule_infos(configuration& cfg,
if(r.source == falco_common::syscall_source) {
auto evttypes = libsinsp::filter::ast::ppm_event_codes(rule.condition.get());
if((evttypes.empty() || evttypes.size() > 100) && r.warn_evttypes) {
cfg.res->add_warning(falco::load_result::load_result::LOAD_NO_EVTTYPE,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_NO_EVTTYPE,
"Rule matches too many evt.type values. This has a "
"significant performance penalty.",
r.ctx);
@@ -523,6 +541,8 @@ void rule_loader::compiler::compile_rule_infos(configuration& cfg,
rule.source = r.source;
rule.description = r.desc;
rule.priority = r.priority;
rule.capture = r.capture;
rule.capture_duration = r.capture_duration;
rule.tags = r.tags;
auto rule_id = out.insert(rule, rule.name);
out.at(rule_id)->id = rule_id;
@@ -549,14 +569,14 @@ void rule_loader::compiler::compile(configuration& cfg,
// print info on any dangling lists or macros that were not used anywhere
for(const auto& m : out.macros) {
if(!m.used) {
cfg.res->add_warning(falco::load_result::load_result::LOAD_UNUSED_MACRO,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_UNUSED_MACRO,
"Macro not referred to by any other rule/macro",
macro_info_from_name(col, m.name)->ctx);
}
}
for(const auto& l : out.lists) {
if(!l.used) {
cfg.res->add_warning(falco::load_result::LOAD_UNUSED_LIST,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_UNUSED_LIST,
"List not referred to by any other rule/macro",
list_info_from_name(col, l.name)->ctx);
}

View File

@@ -56,7 +56,7 @@ protected:
ast_out/filter_out with the compiled filter + ast. Returns false if
the condition could not be compiled and should be skipped.
*/
bool compile_condition(configuration& cfg,
bool compile_condition(const configuration& cfg,
filter_macro_resolver& macro_resolver,
indexed_vector<falco_list>& lists,
const indexed_vector<rule_loader::macro_info>& macros,
@@ -70,16 +70,16 @@ protected:
std::shared_ptr<sinsp_filter>& filter_out) const;
private:
void compile_list_infos(configuration& cfg,
void compile_list_infos(const configuration& cfg,
const collector& col,
indexed_vector<falco_list>& out) const;
void compile_macros_infos(configuration& cfg,
void compile_macros_infos(const configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& out) const;
void compile_rule_infos(configuration& cfg,
void compile_rule_infos(const configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& macros,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -356,10 +356,10 @@ static void read_rule_exceptions(rule_loader::configuration& cfg,
v_ex.name = name;
// Check if an exception with the same name has already been defined
for(auto& exception : exceptions) {
for(const auto& exception : exceptions) {
if(v_ex.name == exception.name) {
cfg.res->add_warning(
falco::load_result::LOAD_EXCEPTION_NAME_NOT_UNIQUE,
falco::load_result::warning_code::LOAD_EXCEPTION_NAME_NOT_UNIQUE,
"Multiple definitions of exception '" + v_ex.name + "' in the same rule",
ex_ctx);
}
@@ -385,7 +385,7 @@ static void read_rule_exceptions(rule_loader::configuration& cfg,
v_ex.values.push_back(v_ex_val);
}
} else if(append) {
cfg.res->add_warning(falco::load_result::LOAD_APPEND_NO_VALUES,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_APPEND_NO_VALUES,
"Overriding/appending exception with no values",
ex_ctx);
}
@@ -524,7 +524,7 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
bool invalid_name = !re2::RE2::FullMatch(name, s_rgx_barestr);
if(invalid_name) {
cfg.res->add_warning(falco::load_result::LOAD_INVALID_LIST_NAME,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_INVALID_LIST_NAME,
"List has an invalid name. List names should match a regular "
"expression: " RGX_BARESTR,
ctx);
@@ -538,7 +538,9 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
decode_optional_val(item, "append", append, ctx);
if(append) {
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM, WARNING_APPEND, ctx);
cfg.res->add_warning(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_APPEND,
ctx);
}
std::set<std::string> override_append, override_replace;
@@ -567,7 +569,7 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
bool invalid_name = !re2::RE2::FullMatch(name, s_rgx_identifier);
if(invalid_name) {
cfg.res->add_warning(falco::load_result::LOAD_INVALID_MACRO_NAME,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_INVALID_MACRO_NAME,
"Macro has an invalid name. Macro names should match a regular "
"expression: " RGX_IDENTIFIER,
ctx);
@@ -587,7 +589,9 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
decode_optional_val(item, "append", append, ctx);
if(append) {
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM, WARNING_APPEND, ctx);
cfg.res->add_warning(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_APPEND,
ctx);
}
std::set<std::string> override_append, override_replace;
@@ -621,7 +625,9 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
bool has_append_flag = false;
decode_optional_val(item, "append", has_append_flag, ctx);
if(has_append_flag) {
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM, WARNING_APPEND, ctx);
cfg.res->add_warning(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_APPEND,
ctx);
}
std::set<std::string> override_append, override_replace;
@@ -634,6 +640,8 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
"output",
"desc",
"priority",
"capture",
"capture_duration",
"tags",
"exceptions",
"enabled",
@@ -756,6 +764,22 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
v.priority = parsed_priority;
}
if(check_update_expected(expected_keys,
override_replace,
"replace",
"capture",
ctx)) {
decode_val(item, "capture", v.capture, ctx);
}
if(check_update_expected(expected_keys,
override_replace,
"replace",
"capture_duration",
ctx)) {
decode_val(item, "capture_duration", v.capture_duration, ctx);
}
if(check_update_expected(expected_keys,
override_replace,
"replace",
@@ -818,6 +842,8 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
rule_loader::rule_info v(ctx);
v.name = name;
v.enabled = true;
v.capture = false;
v.capture_duration = 0;
v.warn_evttypes = true;
v.skip_if_unknown_filter = false;
@@ -829,7 +855,7 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
if(!item["condition"].IsDefined() && !item["output"].IsDefined() &&
!item["desc"].IsDefined() && !item["priority"].IsDefined()) {
decode_val(item, "enabled", v.enabled, ctx);
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM,
cfg.res->add_warning(falco::load_result::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_ENABLED,
ctx);
collector.enable(cfg, v);
@@ -863,6 +889,8 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
prictx);
decode_optional_val(item, "source", v.source, ctx);
decode_optional_val(item, "enabled", v.enabled, ctx);
decode_optional_val(item, "capture", v.capture, ctx);
decode_optional_val(item, "capture_duration", v.capture_duration, ctx);
decode_optional_val(item, "warn_evttypes", v.warn_evttypes, ctx);
decode_optional_val(item, "skip-if-unknown-filter", v.skip_if_unknown_filter, ctx);
decode_tags(item, v.tags, ctx);
@@ -872,7 +900,9 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
}
} else {
rule_loader::context ctx(item, rule_loader::context::RULES_CONTENT_ITEM, "", parent);
cfg.res->add_warning(falco::load_result::LOAD_UNKNOWN_ITEM, "Unknown top level item", ctx);
cfg.res->add_warning(falco::load_result::warning_code::LOAD_UNKNOWN_ITEM,
"Unknown top level item",
ctx);
}
}

View File

@@ -383,13 +383,11 @@ private:
*/
void get_node(YAML::Node& ret, const std::string& key, bool can_append = false) const {
try {
char c;
bool should_shift;
std::string nodeKey;
ret.reset(m_root);
for(std::string::size_type i = 0; i < key.size(); ++i) {
c = key[i];
should_shift = c == '.' || c == '[' || i == key.size() - 1;
char c = key[i];
bool should_shift = c == '.' || c == '[' || i == key.size() - 1;
if(c != '.' && c != '[') {
if(i > 0 && nodeKey.empty() && key[i - 1] != '.') {
@@ -458,11 +456,6 @@ namespace YAML {
template<>
struct convert<nlohmann::json> {
static bool decode(const Node& node, nlohmann::json& res) {
int int_val;
double double_val;
bool bool_val;
std::string str_val;
switch(node.Type()) {
case YAML::NodeType::Map:
for(auto&& it : node) {
@@ -478,7 +471,11 @@ struct convert<nlohmann::json> {
res.emplace_back(sub);
}
break;
case YAML::NodeType::Scalar:
case YAML::NodeType::Scalar: {
int int_val;
double double_val;
bool bool_val;
std::string str_val;
if(YAML::convert<int>::decode(node, int_val)) {
res = int_val;
} else if(YAML::convert<double>::decode(node, double_val)) {
@@ -488,6 +485,7 @@ struct convert<nlohmann::json> {
} else if(YAML::convert<std::string>::decode(node, str_val)) {
res = str_val;
}
}
default:
break;
}

View File

@@ -70,9 +70,9 @@ set(FALCO_INCLUDE_DIRECTORIES
set(FALCO_DEPENDENCIES cxxopts)
set(FALCO_LIBRARIES falco_engine)
if(USE_JEMALLOC)
list(APPEND FALCO_DEPENDENCIES jemalloc)
list(APPEND FALCO_LIBRARIES ${JEMALLOC_LIB})
if(USE_JEMALLOC OR USE_MIMALLOC)
list(APPEND FALCO_DEPENDENCIES malloc)
list(APPEND FALCO_LIBRARIES ${MALLOC_LIB})
endif()
if(NOT WIN32)

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -20,6 +20,7 @@ limitations under the License.
#include "../state.h"
#include "../run_result.h"
#include <string>
#include <nlohmann/json.hpp>
namespace falco {
@@ -34,6 +35,44 @@ void check_for_ignored_events(falco::app::state& s);
void format_plugin_info(std::shared_ptr<sinsp_plugin> p, std::ostream& os);
void format_described_rules_as_text(const nlohmann::json& v, std::ostream& os);
inline std::string generate_scap_file_path(const std::string& prefix,
uint64_t timestamp,
uint64_t evt_num) {
// File path in format: <prefix>_<timestamp>_<evt_num>.scap
// Example: "/tmp/falco_00000001234567890_00000000000000042.scap"
// Add underscore separator between prefix and timestamp
std::string path = prefix + "_";
// Zero-pad timestamp to 20 digits for proper lexicographic sorting
// Build digits from right to left in a buffer, then append to path
char digits[21]; // 20 digits + null terminator
digits[20] = '\0';
uint64_t t = timestamp;
for(int i = 19; i >= 0; --i) {
digits[i] = '0' + (t % 10);
t /= 10;
}
path += digits;
// Add underscore separator between timestamp and evt_num
path += "_";
// Zero-pad evt_num to 20 digits for proper lexicographic sorting
// Build digits from right to left in a buffer, then append to path
t = evt_num;
for(int i = 19; i >= 0; --i) {
digits[i] = '0' + (t % 10);
t /= 10;
}
path += digits;
// Add file extension
path += ".scap";
return path;
}
falco::app::run_result open_offline_inspector(falco::app::state& s);
falco::app::run_result open_live_inspector(falco::app::state& s,
std::shared_ptr<sinsp> inspector,

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -20,6 +20,7 @@ limitations under the License.
#include <libsinsp/plugin_manager.h>
#include <unordered_set>
#include <cstdint>
using namespace falco::app;
using namespace falco::app::actions;

View File

@@ -50,6 +50,12 @@ falco::app::run_result falco::app::actions::open_live_inspector(falco::app::stat
s.config->m_falco_libs_thread_table_size);
}
inspector->set_auto_threads_purging(true);
inspector->set_auto_threads_purging_interval_s(
s.config->m_falco_libs_thread_table_auto_purging_interval_s);
inspector->set_thread_timeout_s(
s.config->m_falco_libs_thread_table_auto_purging_thread_timeout_s);
if(source != falco_common::syscall_source) /* Plugin engine */
{
for(const auto& p : inspector->get_plugin_manager()->plugins()) {

View File

@@ -21,6 +21,7 @@ limitations under the License.
#include <unordered_set>
#include <libsinsp/plugin_manager.h>
#include <libsinsp/sinsp_filtercheck_static.h>
using namespace falco::app;
using namespace falco::app::actions;
@@ -53,7 +54,14 @@ static bool populate_filterchecks(const std::shared_ptr<sinsp>& inspector,
const std::string& source,
filter_check_list& filterchecks,
std::unordered_set<std::string>& used_plugins,
std::map<std::string, std::string> static_fields,
std::string& err) {
// Add static filterchecks loaded from config
if(!static_fields.empty()) {
filterchecks.add_filter_check(std::make_unique<sinsp_filter_check_static>(static_fields));
}
// Add plugin-defined filterchecks, checking that they do not overlap any internal filtercheck
std::vector<const filter_check_info*> infos;
for(const auto& plugin : inspector->get_plugin_manager()->plugins()) {
if(!(plugin->caps() & CAP_EXTRACTION)) {
@@ -82,6 +90,7 @@ static bool populate_filterchecks(const std::shared_ptr<sinsp>& inspector,
filterchecks.add_filter_check(sinsp_plugin::new_filtercheck(plugin));
used_plugins.insert(plugin->name());
}
return true;
}
@@ -162,6 +171,7 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
src,
*src_info->filterchecks,
used_plugins,
s.config->m_static_fields,
err)) {
return run_result::fatal(err);
}

View File

@@ -38,6 +38,6 @@ falco::app::run_result falco::app::actions::list_plugins(const falco::app::state
os << std::endl;
}
printf("%lu Plugins Loaded:\n\n%s\n", configs.size(), os.str().c_str());
printf("%zu Plugins Loaded:\n\n%s\n", configs.size(), os.str().c_str());
return run_result::exit();
}

View File

@@ -47,10 +47,12 @@ falco::app::run_result falco::app::actions::load_plugins(falco::app::state& s) {
// Load all the configured plugins
for(auto& p : s.config->m_plugins) {
falco_logger::log(falco_logger::level::INFO,
"Loading plugin '" + p.m_name + "' from file " + p.m_library_path + "\n");
auto plugin = s.offline_inspector->register_plugin(p.m_library_path);
s.plugin_configs.insert(p, plugin->name());
falco_logger::log(falco_logger::level::INFO,
"Loaded plugin '" + p.m_name + "@" +
plugin->plugin_version().as_string() + "' from file " +
p.m_library_path + "\n");
if((plugin->caps() & CAP_SOURCING) == 0 || plugin->id() == 0) {
continue;
}

View File

@@ -27,8 +27,6 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::load_rules_files(falco::app::state& s) {
std::string all_rules;
if(!s.options.rules_filenames.empty()) {
s.config->m_rules_filenames = s.options.rules_filenames;
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -23,6 +23,7 @@ limitations under the License.
#include <fcntl.h>
#include <atomic>
#include <unordered_map>
#include <memory>
#include "falco_utils.h"
@@ -36,6 +37,7 @@ limitations under the License.
#include "../../event_drops.h"
#include <libsinsp/plugin_manager.h>
#include <libsinsp/dumper.h>
using namespace falco::app;
using namespace falco::app::actions;
@@ -143,6 +145,11 @@ static falco::app::run_result do_inspect(
s.config->m_syscall_evt_simulate_drops);
}
// init dumper for captures
auto dumper = std::make_unique<sinsp_dumper>();
uint64_t dump_started_ts = 0;
uint64_t dump_deadline_ts = 0;
//
// Start capture
//
@@ -168,11 +175,21 @@ static falco::app::run_result do_inspect(
if(falco::app::g_terminate_signal.triggered()) {
falco::app::g_terminate_signal.handle([&]() {
falco_logger::log(falco_logger::level::INFO, "SIGINT received, exiting...\n");
if(dump_started_ts != 0) {
dump_started_ts = 0;
dump_deadline_ts = 0;
dumper->close();
}
});
break;
} else if(falco::app::g_restart_signal.triggered()) {
falco::app::g_restart_signal.handle([&s]() {
falco::app::g_restart_signal.handle([&]() {
falco_logger::log(falco_logger::level::INFO, "SIGHUP received, restarting...\n");
if(dump_started_ts != 0) {
dump_started_ts = 0;
dump_deadline_ts = 0;
dumper->close();
}
s.restart.store(true);
});
break;
@@ -226,7 +243,7 @@ static falco::app::run_result do_inspect(
if(source_engine_idx == sinsp_no_event_source_idx) {
std::string msg = "Unknown event source for inspector's event";
if(ev->get_type() == PPME_PLUGINEVENT_E || ev->get_type() == PPME_ASYNCEVENT_E) {
auto pluginID = *(uint32_t*)ev->get_param(0)->m_val;
auto pluginID = ev->get_param(0)->as<uint32_t>();
if(pluginID != 0) {
msg += " (plugin ID: " + std::to_string(pluginID) + ")";
}
@@ -235,12 +252,6 @@ static falco::app::run_result do_inspect(
}
// for capture mode, the source name can change at every event
// TODO: This may currently cause issues for multiple event sources. We are deferring
// the fix to Falco 0.42.0.
// For multiple event sources, it generates `n` metrics logs per source at a time, as
// expected, with the engine_name correctly reflected. However, the order may interfere,
// as the correct inspector for the syscalls event source seems to never get passed,
// resulting in most metrics being missing.
stats_collector.collect(inspector,
inspector->event_sources()[source_engine_idx],
num_evts);
@@ -293,7 +304,10 @@ static falco::app::run_result do_inspect(
// the outputs.
auto res = s.engine->process_event(source_engine_idx, ev, s.config->m_rule_matching);
if(res != nullptr) {
auto capture = s.config->m_capture_enabled &&
capture_mode_t::ALL_RULES == s.config->m_capture_mode;
for(auto& rule_res : *res) {
// Process output
s.outputs->handle_event(rule_res.evt,
rule_res.rule,
rule_res.source,
@@ -301,6 +315,46 @@ static falco::app::run_result do_inspect(
rule_res.format,
rule_res.tags,
rule_res.extra_output_fields);
// Compute capture params, if enabled
if(s.config->m_capture_enabled) {
if(capture_mode_t::RULES == s.config->m_capture_mode && rule_res.capture) {
capture = true;
}
// Compute the capture deadline for this event,
// based on the rules duration or the default one if unspecified
auto evt_deadline_ts =
ev->get_ts() + (rule_res.capture_duration_ns > 0
? rule_res.capture_duration_ns
: s.config->m_capture_default_duration_ns);
// Update the capture deadline if this event needs to extend it beyond the
// current deadline or if no deadline is currently set
if(evt_deadline_ts > dump_deadline_ts) {
dump_deadline_ts = evt_deadline_ts;
}
}
}
// When a rule matches or we are in all_rules mode, we start a dump (if not in progress
// yet)
if(capture && dump_started_ts == 0) {
dumper->open(inspector.get(),
generate_scap_file_path(s.config->m_capture_path_prefix,
ev->get_ts(),
ev->get_num()),
true); // Enable compression
dump_started_ts = ev->get_ts();
}
}
// Save events when a dump is in progress.
// If the deadline is reached, close the dump.
if(dump_started_ts != 0) {
dumper->dump(ev);
if(ev->get_ts() > dump_deadline_ts) {
dumper->flush();
dumper->close();
dump_started_ts = 0;
dump_deadline_ts = 0;
}
}
@@ -440,6 +494,24 @@ falco::app::run_result falco::app::actions::process_events(falco::app::state& s)
return res;
}
// Print capture mode info, if enabled
if(s.config->m_capture_enabled) {
std::string capture_mode;
switch(s.config->m_capture_mode) {
case capture_mode_t::RULES:
capture_mode = "'rules'";
break;
case capture_mode_t::ALL_RULES:
capture_mode = "'all_rules'";
break;
default:
ASSERT(false);
}
falco_logger::log(falco_logger::level::INFO,
"Capture is enabled in mode " + capture_mode + ". Capturing events to " +
s.config->m_capture_path_prefix + "\n");
}
// Start processing events
bool termination_forced = false;
if(s.is_capture_mode()) {
@@ -491,6 +563,10 @@ falco::app::run_result falco::app::actions::process_events(falco::app::state& s)
}
if(s.enabled_sources.size() == 1) {
if(s.on_inspectors_opened != nullptr) {
s.on_inspectors_opened();
}
// optimization: with only one source we don't spawn additional threads
process_inspector_events(s,
src_info->inspector,
@@ -520,6 +596,9 @@ falco::app::run_result falco::app::actions::process_events(falco::app::state& s)
break;
}
}
if(s.enabled_sources.size() > 1 && s.on_inspectors_opened != nullptr) {
s.on_inspectors_opened();
}
// wait for event processing to terminate for all sources
// if a thread terminates with an error, we trigger the app termination

View File

@@ -44,6 +44,7 @@ falco::app::run_result falco::app::actions::start_webserver(falco::app::state& s
std::to_string(webserver_config.m_listen_port) + ssl_option + "\n");
state.webserver.start(state, webserver_config);
state.on_inspectors_opened = [&state]() { state.webserver.enable_prometheus_metrics(state); };
#endif
return run_result::ok();
}

View File

@@ -51,7 +51,7 @@ public:
std::string gvisor_generate_config_with_socket;
bool describe_all_rules = false;
std::string describe_rule;
bool print_ignored_events;
bool print_ignored_events = false;
bool list_fields = false;
std::string list_source_fields;
bool list_plugins = false;

View File

@@ -38,7 +38,9 @@ limitations under the License.
falco::app::restart_handler::~restart_handler() {
stop();
close(m_inotify_fd);
if(m_inotify_fd != -1) {
close(m_inotify_fd);
}
m_inotify_fd = -1;
}
@@ -48,6 +50,12 @@ void falco::app::restart_handler::trigger() {
bool falco::app::restart_handler::start(std::string& err) {
#ifdef __linux__
if(m_watched_files.empty() && m_watched_dirs.empty()) {
falco_logger::log(falco_logger::level::DEBUG,
"Refusing to start restart handler due to nothing to watch\n");
return true;
}
m_inotify_fd = inotify_init();
if(m_inotify_fd < 0) {
err = "could not initialize inotify handler";
@@ -100,7 +108,6 @@ void falco::app::restart_handler::watcher_loop() noexcept {
}
fd_set set;
bool forced = false;
bool should_check = false;
bool should_restart = false;
struct timeval timeout;
@@ -124,7 +131,7 @@ void falco::app::restart_handler::watcher_loop() noexcept {
}
// check if there's been a forced restart request
forced = m_forced.load(std::memory_order_acquire);
bool forced = m_forced.load(std::memory_order_acquire);
m_forced.store(false, std::memory_order_release);
// no new watch event is received during the timeout

View File

@@ -61,7 +61,7 @@ public:
private:
void watcher_loop() noexcept;
int m_inotify_fd;
int m_inotify_fd = -1;
std::thread m_watcher;
std::atomic<bool> m_stop;
std::atomic<bool> m_forced;

View File

@@ -116,6 +116,9 @@ struct state {
falco_webserver webserver;
#endif
// Set by start_webserver to start prometheus metrics
// once all inspectors are opened.
std::function<void()> on_inspectors_opened = nullptr;
inline bool is_capture_mode() const { return config->m_engine_mode == engine_kind_t::REPLAY; }

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2024 The Falco Authors.
Copyright (C) 2025 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.
@@ -35,6 +35,9 @@ const char config_schema_string[] = LONG_STRING_CONST(
"$ref": "#/definitions/AppendOutput"
}
},
"static_fields": {
"type": "object"
},
"config_files": {
"type": "array",
"items": {
@@ -91,6 +94,9 @@ const char config_schema_string[] = LONG_STRING_CONST(
"engine": {
"$ref": "#/definitions/Engine"
},
"capture": {
"$ref": "#/definitions/Capture"
},
"load_plugins": {
"type": "array",
"items": {
@@ -308,6 +314,29 @@ const char config_schema_string[] = LONG_STRING_CONST(
}
}
},
"Capture": {
"type": "object",
"additionalProperties": false,
"properties": {
"enabled": {
"type": "boolean"
},
"path_prefix": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"rules",
"all_rules"
]
},
"default_duration": {
"type": "integer"
}
},
"title": "Capture"
},
"BaseSyscalls": {
"type": "object",
"additionalProperties": false,
@@ -442,6 +471,12 @@ const char config_schema_string[] = LONG_STRING_CONST(
"thread_table_size": {
"type": "integer"
},
"thread_table_auto_purging_interval_s": {
"type": "integer"
},
"thread_table_auto_purging_thread_timeout_s": {
"type": "integer"
},
"snaplen": {
"type": "integer"
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -86,6 +86,10 @@ falco_configuration::falco_configuration():
m_syscall_evt_simulate_drops(false),
m_syscall_evt_timeout_max_consecutives(1000),
m_falco_libs_thread_table_size(DEFAULT_FALCO_LIBS_THREAD_TABLE_SIZE),
m_falco_libs_thread_table_auto_purging_interval_s(
DEFAULT_FALCO_LIBS_THREAD_TABLE_AUTO_PURGING_INTERVAL_S),
m_falco_libs_thread_table_auto_purging_thread_timeout_s(
DEFAULT_FALCO_LIBS_THREAD_TABLE_AUTO_PURGING_THREAD_TIMEOUT_S),
m_falco_libs_snaplen(0),
m_base_syscalls_all(false),
m_base_syscalls_repair(false),
@@ -97,7 +101,11 @@ falco_configuration::falco_configuration():
m_metrics_flags(0),
m_metrics_convert_memory_to_mb(true),
m_metrics_include_empty_values(false),
m_plugins_hostinfo(true) {
m_plugins_hostinfo(true),
m_capture_enabled(false),
m_capture_path_prefix("/tmp/falco"),
m_capture_mode(capture_mode_t::RULES),
m_capture_default_duration_ns(5000 * 1000000LL) {
m_config_schema = nlohmann::json::parse(config_schema_string);
}
@@ -331,7 +339,7 @@ void falco_configuration::load_yaml(const std::string &config_name) {
m_loaded_rules_filenames.clear();
m_loaded_rules_filenames_sha256sum.clear();
m_loaded_rules_folders.clear();
for(auto &file : rules_files) {
for(const auto &file : rules_files) {
// Here, we only include files that exist
struct stat buffer;
if(stat(file.c_str(), &buffer) == 0) {
@@ -590,6 +598,12 @@ void falco_configuration::load_yaml(const std::string &config_name) {
m_falco_libs_thread_table_size =
m_config.get_scalar<std::uint32_t>("falco_libs.thread_table_size",
DEFAULT_FALCO_LIBS_THREAD_TABLE_SIZE);
m_falco_libs_thread_table_auto_purging_interval_s = m_config.get_scalar<std::uint32_t>(
"falco_libs.thread_table_auto_purging_interval_s",
DEFAULT_FALCO_LIBS_THREAD_TABLE_AUTO_PURGING_INTERVAL_S);
m_falco_libs_thread_table_auto_purging_thread_timeout_s = m_config.get_scalar<std::uint32_t>(
"falco_libs.thread_table_auto_purging_thread_timeout_s",
DEFAULT_FALCO_LIBS_THREAD_TABLE_AUTO_PURGING_THREAD_TIMEOUT_S);
// if falco_libs.snaplen is not set we'll let libs configure it
m_falco_libs_snaplen = m_config.get_scalar<std::uint64_t>("falco_libs.snaplen", 0);
@@ -637,6 +651,26 @@ void falco_configuration::load_yaml(const std::string &config_name) {
m_metrics_include_empty_values =
m_config.get_scalar<bool>("metrics.include_empty_values", false);
m_capture_enabled = m_config.get_scalar<bool>("capture.enabled", false);
m_capture_path_prefix = m_config.get_scalar<std::string>("capture.path_prefix", "/tmp/falco");
// Set capture mode if not already set.
const std::unordered_map<std::string, capture_mode_t> capture_mode_lut = {
{"rules", capture_mode_t::RULES},
{"all_rules", capture_mode_t::ALL_RULES},
};
auto capture_mode_str = m_config.get_scalar<std::string>("capture.mode", "rules");
if(capture_mode_lut.find(capture_mode_str) != capture_mode_lut.end()) {
m_capture_mode = capture_mode_lut.at(capture_mode_str);
} else {
throw std::logic_error("Error reading config file (" + config_name + "): capture.mode '" +
capture_mode_str + "' is not a valid mode.");
}
// Convert to nanoseconds
m_capture_default_duration_ns =
m_config.get_scalar<uint32_t>("capture.default_duration", 5000) * 1000000LL;
m_plugins_hostinfo = m_config.get_scalar<bool>("plugins_hostinfo", true);
m_config.get_sequence<std::vector<rule_selection_config>>(m_rules_selection, "rules");
@@ -663,6 +697,8 @@ void falco_configuration::load_yaml(const std::string &config_name) {
}
}
m_static_fields = m_config.get_scalar<std::map<std::string, std::string>>("static_fields", {});
std::vector<std::string> load_plugins;
bool load_plugins_node_defined = m_config.is_defined("load_plugins");
@@ -733,7 +769,7 @@ void falco_configuration::read_rules_file_directory(const std::string &path,
std::sort(dir_filenames.begin(), dir_filenames.end());
for(std::string &ent : dir_filenames) {
for(const std::string &ent : dir_filenames) {
// only consider yaml files
if(falco::utils::matches_wildcard("*.yaml", ent) ||
falco::utils::matches_wildcard("*.yml", ent)) {

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2025 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.
@@ -42,6 +42,8 @@ limitations under the License.
enum class engine_kind_t : uint8_t { KMOD, EBPF, MODERN_EBPF, REPLAY, GVISOR, NODRIVER };
enum class capture_mode_t : uint8_t { RULES, ALL_RULES };
// Map that holds { config filename | validation status } for each loaded config file.
typedef std::map<std::string, std::string> config_loaded_res;
@@ -147,6 +149,8 @@ public:
std::vector<rule_selection_config> m_rules_selection;
// Append output configuration passed by the user
std::vector<append_output_config> m_append_output;
// Static fields configuration passed by the user
std::map<std::string, std::string> m_static_fields;
bool m_json_output;
bool m_json_include_output_property;
@@ -186,6 +190,8 @@ public:
uint32_t m_syscall_evt_timeout_max_consecutives;
uint32_t m_falco_libs_thread_table_size;
uint32_t m_falco_libs_thread_table_auto_purging_interval_s;
uint32_t m_falco_libs_thread_table_auto_purging_thread_timeout_s;
uint64_t m_falco_libs_snaplen;
// User supplied base_syscalls, overrides any Falco state engine enforcement.
@@ -205,6 +211,12 @@ public:
std::vector<plugin_config> m_plugins;
bool m_plugins_hostinfo;
// capture configs
bool m_capture_enabled;
std::string m_capture_path_prefix;
capture_mode_t m_capture_mode = capture_mode_t::RULES;
uint64_t m_capture_default_duration_ns;
// Falco engine
engine_kind_t m_engine_mode = engine_kind_t::KMOD;
kmod_config m_kmod = {};

View File

@@ -65,29 +65,16 @@ bool syscall_evt_drop_mgr::process_event(std::shared_ptr<sinsp> inspector, sinsp
delta.n_evts = stats.n_evts - m_last_stats.n_evts;
delta.n_drops = stats.n_drops - m_last_stats.n_drops;
delta.n_drops_buffer = stats.n_drops_buffer - m_last_stats.n_drops_buffer;
delta.n_drops_buffer_clone_fork_enter = stats.n_drops_buffer_clone_fork_enter -
m_last_stats.n_drops_buffer_clone_fork_enter;
delta.n_drops_buffer_clone_fork_exit =
stats.n_drops_buffer_clone_fork_exit - m_last_stats.n_drops_buffer_clone_fork_exit;
delta.n_drops_buffer_execve_enter =
stats.n_drops_buffer_execve_enter - m_last_stats.n_drops_buffer_execve_enter;
delta.n_drops_buffer_execve_exit =
stats.n_drops_buffer_execve_exit - m_last_stats.n_drops_buffer_execve_exit;
delta.n_drops_buffer_connect_enter =
stats.n_drops_buffer_connect_enter - m_last_stats.n_drops_buffer_connect_enter;
delta.n_drops_buffer_connect_exit =
stats.n_drops_buffer_connect_exit - m_last_stats.n_drops_buffer_connect_exit;
delta.n_drops_buffer_open_enter =
stats.n_drops_buffer_open_enter - m_last_stats.n_drops_buffer_open_enter;
delta.n_drops_buffer_open_exit =
stats.n_drops_buffer_open_exit - m_last_stats.n_drops_buffer_open_exit;
delta.n_drops_buffer_dir_file_enter =
stats.n_drops_buffer_dir_file_enter - m_last_stats.n_drops_buffer_dir_file_enter;
delta.n_drops_buffer_dir_file_exit =
stats.n_drops_buffer_dir_file_exit - m_last_stats.n_drops_buffer_dir_file_exit;
delta.n_drops_buffer_other_interest_enter =
stats.n_drops_buffer_other_interest_enter -
m_last_stats.n_drops_buffer_other_interest_enter;
delta.n_drops_buffer_other_interest_exit = stats.n_drops_buffer_other_interest_exit -
m_last_stats.n_drops_buffer_other_interest_exit;
delta.n_drops_buffer_close_exit =
@@ -151,15 +138,16 @@ bool syscall_evt_drop_mgr::perform_actions(uint64_t now,
std::string rule = "Falco internal: syscall event drop";
std::string msg =
rule + ". " + std::to_string(delta.n_drops) + " system calls dropped in last second.";
bool ret = true;
for(auto &act : m_actions) {
switch(act) {
case syscall_evt_drop_action::DISREGARD:
return true;
continue;
case syscall_evt_drop_action::LOG:
falco_logger::log(falco_logger::level::DEBUG, std::move(msg));
return true;
continue;
case syscall_evt_drop_action::ALERT: {
nlohmann::json output_fields;
@@ -181,24 +169,14 @@ bool syscall_evt_drop_mgr::perform_actions(uint64_t now,
* syscall category (typically `open` system call category is highest by orders of
* magnitude).
*/
output_fields["n_drops_buffer_clone_fork_enter"] =
std::to_string(delta.n_drops_buffer_clone_fork_enter);
output_fields["n_drops_buffer_clone_fork_exit"] =
std::to_string(delta.n_drops_buffer_clone_fork_exit);
output_fields["n_drops_buffer_execve_enter"] =
std::to_string(delta.n_drops_buffer_execve_enter);
output_fields["n_drops_buffer_execve_exit"] =
std::to_string(delta.n_drops_buffer_execve_exit);
output_fields["n_drops_buffer_connect_enter"] =
std::to_string(delta.n_drops_buffer_connect_enter);
output_fields["n_drops_buffer_connect_exit"] =
std::to_string(delta.n_drops_buffer_connect_exit);
output_fields["n_drops_buffer_open_enter"] =
std::to_string(delta.n_drops_buffer_open_enter);
output_fields["n_drops_buffer_open_exit"] =
std::to_string(delta.n_drops_buffer_open_exit);
output_fields["n_drops_buffer_dir_file_enter"] =
std::to_string(delta.n_drops_buffer_dir_file_enter);
output_fields["n_drops_buffer_dir_file_exit"] =
std::to_string(delta.n_drops_buffer_dir_file_exit);
/* `n_drops_buffer_other_interest_*` Category consisting of other system calls of
@@ -206,8 +184,6 @@ bool syscall_evt_drop_mgr::perform_actions(uint64_t now,
* for a custom category if needed - simply patch switch statement in kernel driver code
* (`falcosecurity/libs` repo).
*/
output_fields["n_drops_buffer_other_interest_enter"] =
std::to_string(delta.n_drops_buffer_other_interest_enter);
output_fields["n_drops_buffer_other_interest_exit"] =
std::to_string(delta.n_drops_buffer_other_interest_exit);
output_fields["n_drops_buffer_close_exit"] =
@@ -224,19 +200,20 @@ bool syscall_evt_drop_mgr::perform_actions(uint64_t now,
kernel instrumentation). */
output_fields["ebpf_enabled"] = std::to_string(bpf_enabled);
m_outputs->handle_msg(now, falco_common::PRIORITY_DEBUG, msg, rule, output_fields);
return true;
continue;
}
case syscall_evt_drop_action::EXIT:
falco_logger::log(falco_logger::level::CRIT, std::move(msg));
falco_logger::log(falco_logger::level::CRIT, "Exiting.");
return false;
ret = false;
continue;
default:
falco_logger::log(falco_logger::level::ERR,
"Ignoring unknown action " + std::to_string(int(act)));
return true;
continue;
}
}
return true;
return ret;
}

View File

@@ -72,6 +72,34 @@ namespace fs = std::filesystem;
*/
const std::string falco_metrics::content_type_prometheus = "text/plain; version=0.0.4";
// Helper function to convert metric to prometheus text with custom help text
static std::string convert_metric_to_text_prometheus_with_deprecation_notice(
libs::metrics::prometheus_metrics_converter& converter,
const metrics_v2& metric,
const std::string& prefix,
const std::string& subsystem,
const std::map<std::string, std::string>& labels) {
// First get the standard prometheus text
std::string prometheus_text =
converter.convert_metric_to_text_prometheus(metric, prefix, subsystem, labels);
// Find the first occurrence of "# HELP" and append the deprecation notice
size_t help_pos = prometheus_text.find("# HELP");
if(help_pos != std::string::npos) {
// Find the end of the help line
size_t help_end = prometheus_text.find('\n', help_pos);
if(help_end != std::string::npos) {
// Append (DEPRECATED: enter events are no longer tracked in falcosecurity/libs) to the
// help text
prometheus_text.insert(
help_end,
" (DEPRECATED: enter events are no longer tracked in falcosecurity/libs)");
}
}
return prometheus_text;
}
std::string falco_metrics::falco_to_text_prometheus(
const falco::app::state& state,
libs::metrics::prometheus_metrics_converter& prometheus_metrics_converter,
@@ -122,13 +150,15 @@ std::string falco_metrics::falco_to_text_prometheus(
// # HELP falcosecurity_falco_outputs_queue_num_drops_total https://falco.org/docs/metrics/
// # TYPE falcosecurity_falco_outputs_queue_num_drops_total counter
// falcosecurity_falco_outputs_queue_num_drops_total 0
additional_wrapper_metrics.emplace_back(libs::metrics::libsinsp_metrics::new_metric(
"outputs_queue_num_drops",
METRICS_V2_MISC,
METRIC_VALUE_TYPE_U64,
METRIC_VALUE_UNIT_COUNT,
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
state.outputs->get_outputs_queue_num_drops()));
if(state.outputs != nullptr) {
additional_wrapper_metrics.emplace_back(libs::metrics::libsinsp_metrics::new_metric(
"outputs_queue_num_drops",
METRICS_V2_MISC,
METRIC_VALUE_TYPE_U64,
METRIC_VALUE_UNIT_COUNT,
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
state.outputs->get_outputs_queue_num_drops()));
}
// # HELP falcosecurity_falco_reload_timestamp_nanoseconds https://falco.org/docs/metrics/
// # TYPE falcosecurity_falco_reload_timestamp_nanoseconds gauge
@@ -234,7 +264,7 @@ std::string falco_metrics::sources_to_text_prometheus(
SOURCE_PLUGIN_ENGINE,
NODRIVER_ENGINE,
GVISOR_ENGINE};
static re2::RE2 drops_buffer_pattern("n_drops_buffer_([^_]+(?:_[^_]+)*)_(enter|exit)$");
static re2::RE2 drops_buffer_pattern("n_drops_buffer_([^_]+(?:_[^_]+)*)_exit$");
static re2::RE2 cpu_pattern("(\\d+)");
std::string prometheus_text;
@@ -355,9 +385,8 @@ std::string falco_metrics::sources_to_text_prometheus(
} else if(strncmp(metric.name, "n_drops_buffer", 14) == 0) // prefix match
{
std::string drop;
std::string dir;
std::string name_str(metric.name);
if(re2::RE2::FullMatch(name_str, drops_buffer_pattern, &drop, &dir)) {
if(re2::RE2::FullMatch(name_str, drops_buffer_pattern, &drop)) {
auto metric_new = libs::metrics::libsinsp_metrics::new_metric(
"n_drops_buffer",
METRICS_V2_KERNEL_COUNTERS,
@@ -366,16 +395,12 @@ std::string falco_metrics::sources_to_text_prometheus(
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
metric.value.u64);
const std::map<std::string, std::string>& const_labels = {{"drop", drop},
{"dir", dir}};
{"dir", "exit"}};
/* Examples ...
# HELP falcosecurity_scap_n_drops_buffer_total
https://falco.org/docs/metrics/ # TYPE
falcosecurity_scap_n_drops_buffer_total counter
falcosecurity_scap_n_drops_buffer_total{dir="enter",drop="clone_fork"} 0
# HELP falcosecurity_scap_n_drops_buffer_total
https://falco.org/docs/metrics/ # TYPE
falcosecurity_scap_n_drops_buffer_total counter
falcosecurity_scap_n_drops_buffer_total{dir="exit",drop="clone_fork"} 0
falcosecurity_scap_n_drops_buffer_total{dir="exit",drop="clone_fork"} 0
*/
prometheus_text +=
prometheus_metrics_converter.convert_metric_to_text_prometheus(
@@ -392,6 +417,30 @@ std::string falco_metrics::sources_to_text_prometheus(
prometheus_subsystem);
}
}
// Add deprecated enter event metrics with 0 values for backward compatibility
static const std::vector<std::string> deprecated_enter_drops =
{"clone_fork", "execve", "connect", "open", "dir_file", "other_interest"};
for(const auto& drop_type : deprecated_enter_drops) {
auto metric_new = libs::metrics::libsinsp_metrics::new_metric(
"n_drops_buffer",
METRICS_V2_KERNEL_COUNTERS,
METRIC_VALUE_TYPE_U64,
METRIC_VALUE_UNIT_COUNT,
METRIC_VALUE_METRIC_TYPE_MONOTONIC,
0); // Always 0 for deprecated enter events
const std::map<std::string, std::string>& const_labels = {{"drop", drop_type},
{"dir", "enter"}};
// Add deprecation notice to the help text
prometheus_text += convert_metric_to_text_prometheus_with_deprecation_notice(
prometheus_metrics_converter,
metric_new,
"falcosecurity",
"scap", // Use "scap" subsystem for kernel counters
const_labels);
}
}
// Source wrapper metrics Part B: Agnostic, performed only once.

View File

@@ -46,7 +46,7 @@ private:
class stream_context : public context {
public:
explicit stream_context(::grpc::ServerContext* ctx): context(ctx) {};
virtual ~stream_context() = default;
virtual ~stream_context() override = default;
enum : char { STREAMING = 1, SUCCESS, ERROR } m_status = STREAMING;
@@ -58,7 +58,7 @@ public:
class bidi_context : public stream_context {
public:
explicit bidi_context(::grpc::ServerContext* ctx): stream_context(ctx) {};
virtual ~bidi_context() = default;
virtual ~bidi_context() override = default;
};
} // namespace grpc

View File

@@ -44,7 +44,7 @@ template<class Service, class Request, class Response>
class request_stream_context : public request_context_base {
public:
request_stream_context(): m_process_func(nullptr), m_request_func(nullptr) {};
~request_stream_context() = default;
~request_stream_context() override = default;
// Pointer to function that does actual processing
void (server::*m_process_func)(const stream_context&, const Request&, Response&);
@@ -73,7 +73,7 @@ template<class Service, class Request, class Response>
class request_context : public request_context_base {
public:
request_context(): m_process_func(nullptr), m_request_func(nullptr) {};
~request_context() = default;
~request_context() override = default;
// Pointer to function that does actual processing
void (server::*m_process_func)(const context&, const Request&, Response&);
@@ -99,7 +99,7 @@ template<class Service, class Request, class Response>
class request_bidi_context : public request_context_base {
public:
request_bidi_context(): m_process_func(nullptr), m_request_func(nullptr) {};
~request_bidi_context() = default;
~request_bidi_context() override = default;
// Pointer to function that does actual processing
void (server::*m_process_func)(const bidi_context&, const Request&, Response&);

View File

@@ -74,7 +74,7 @@ public:
}
// Return the output's name as per its configuration.
const std::string get_name() const { return m_oc.name; }
const std::string& get_name() const { return m_oc.name; }
// Output a message.
virtual void output(const message* msg) = 0;

View File

@@ -20,7 +20,10 @@ limitations under the License.
#define CHECK_RES(fn) res = res == CURLE_OK ? fn : res
static size_t noop_write_callback(void *contents, size_t size, size_t nmemb, void *userp) {
static size_t noop_write_callback(void * /*contents*/,
size_t size,
size_t nmemb,
void * /*userp*/) {
// We don't want to echo anything. Just return size of bytes ignored
return size * nmemb;
}

View File

@@ -414,7 +414,8 @@ void stats_writer::collector::get_metrics_output_fields_wrapper(
void stats_writer::collector::get_metrics_output_fields_additional(
nlohmann::json& output_fields,
double stats_snapshot_time_delta_sec) {
double stats_snapshot_time_delta_sec,
const std::string& src) {
// Falco metrics categories
//
// rules_counters_enabled
@@ -441,7 +442,7 @@ void stats_writer::collector::get_metrics_output_fields_additional(
nlohmann::json j;
malloc_stats_print(
[](void* to, const char* from) {
nlohmann::json* j = (nlohmann::json*)to;
nlohmann::json* j = static_cast<nlohmann::json*>(to);
*j = nlohmann::json::parse(from);
},
&j,
@@ -478,7 +479,8 @@ void stats_writer::collector::get_metrics_output_fields_additional(
#endif
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
if(m_writer->m_libs_metrics_collector && m_writer->m_output_rule_metrics_converter) {
if(m_writer->m_libs_metrics_collectors.find(src) != m_writer->m_libs_metrics_collectors.end() &&
m_writer->m_output_rule_metrics_converter) {
// Libs metrics categories
//
// resource_utilization_enabled
@@ -487,8 +489,9 @@ void stats_writer::collector::get_metrics_output_fields_additional(
// libbpf_stats_enabled
// Refresh / New snapshot
m_writer->m_libs_metrics_collector->snapshot();
auto metrics_snapshot = m_writer->m_libs_metrics_collector->get_metrics();
auto& libs_metrics_collector = m_writer->m_libs_metrics_collectors[src];
libs_metrics_collector->snapshot();
auto metrics_snapshot = libs_metrics_collector->get_metrics();
// Cache n_evts and n_drops to derive n_drops_perc.
uint64_t n_evts = 0;
uint64_t n_drops = 0;
@@ -611,7 +614,8 @@ void stats_writer::collector::collect(const std::shared_ptr<sinsp>& inspector,
uint64_t num_evts) {
if(m_writer->has_output()) {
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
if(!m_writer->m_libs_metrics_collector) {
if(m_writer->m_libs_metrics_collectors.find(src) ==
m_writer->m_libs_metrics_collectors.end()) {
uint32_t flags = m_writer->m_config->m_metrics_flags;
// Note: ENGINE_FLAG_BPF_STATS_ENABLED check has been moved to libs, that is, when
// libbpf stats is not enabled in the kernel settings we won't collect them even if the
@@ -625,7 +629,7 @@ void stats_writer::collector::collect(const std::shared_ptr<sinsp>& inspector,
flags &= ~(METRICS_V2_KERNEL_COUNTERS | METRICS_V2_KERNEL_COUNTERS_PER_CPU |
METRICS_V2_STATE_COUNTERS | METRICS_V2_LIBBPF_STATS);
}
m_writer->m_libs_metrics_collector =
m_writer->m_libs_metrics_collectors[src] =
std::make_unique<libs::metrics::libs_metrics_collector>(inspector.get(), flags);
}
@@ -658,7 +662,7 @@ void stats_writer::collector::collect(const std::shared_ptr<sinsp>& inspector,
now,
stats_snapshot_time_delta_sec);
get_metrics_output_fields_additional(output_fields, stats_snapshot_time_delta_sec);
get_metrics_output_fields_additional(output_fields, stats_snapshot_time_delta_sec, src);
/* Send message in the queue */
stats_writer::msg msg;

View File

@@ -79,7 +79,8 @@ public:
fields.
*/
void get_metrics_output_fields_additional(nlohmann::json& output_fields,
double stats_snapshot_time_delta_sec);
double stats_snapshot_time_delta_sec,
const std::string& src);
std::shared_ptr<stats_writer> m_writer;
// Init m_last_tick w/ invalid value to enable metrics logging immediately after
@@ -153,7 +154,9 @@ private:
tbb::concurrent_bounded_queue<stats_writer::msg> m_queue;
#endif
#if defined(__linux__) and !defined(MINIMAL_BUILD) and !defined(__EMSCRIPTEN__)
std::unique_ptr<libs::metrics::libs_metrics_collector> m_libs_metrics_collector;
// Per source map of libs metrics collectors
std::unordered_map<std::string, std::unique_ptr<libs::metrics::libs_metrics_collector>>
m_libs_metrics_collectors;
std::unique_ptr<libs::metrics::output_rule_metrics_converter> m_output_rule_metrics_converter;
#endif
std::shared_ptr<falco_outputs> m_outputs;

View File

@@ -58,12 +58,6 @@ void falco_webserver::start(const falco::app::state &state,
res.set_content(versions_json_str, "application/json");
});
if(state.config->m_metrics_enabled && webserver_config.m_prometheus_metrics_enabled) {
m_server->Get("/metrics", [&state](const httplib::Request &, httplib::Response &res) {
res.set_content(falco_metrics::to_text_prometheus(state),
falco_metrics::content_type_prometheus);
});
}
// run server in a separate thread
if(!m_server->is_valid()) {
m_server = nullptr;
@@ -106,3 +100,13 @@ void falco_webserver::stop() {
m_running = false;
}
}
void falco_webserver::enable_prometheus_metrics(const falco::app::state &state) {
if(state.config->m_metrics_enabled &&
state.config->m_webserver_config.m_prometheus_metrics_enabled) {
m_server->Get("/metrics", [&state](const httplib::Request &, httplib::Response &res) {
res.set_content(falco_metrics::to_text_prometheus(state),
falco_metrics::content_type_prometheus);
});
}
}

View File

@@ -40,6 +40,7 @@ public:
virtual void start(const falco::app::state& state,
const falco_configuration::webserver_config& webserver_config);
virtual void stop();
virtual void enable_prometheus_metrics(const falco::app::state& state);
private:
bool m_running = false;