Compare commits

..

4 Commits

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

Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-22 10:00:02 +01:00
Federico Di Pierro
36797b0cda update(cmake): bump libs to 0.20.0 and driver to 8.0.0+driver.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2025-01-21 09:53:53 +01:00
124 changed files with 1837 additions and 4268 deletions

View File

@@ -1,3 +0,0 @@
*
!config/
!docker/

View File

@@ -6,7 +6,6 @@
| rpm-x86_64 | [![rpm](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpmFALCOBUCKET/falco-FALCOVER-x86_64.rpm) |
| deb-x86_64 | [![deb](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/debFALCOBUCKET/stable/falco-FALCOVER-x86_64.deb) |
| tgz-x86_64 | [![tgz](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/binFALCOBUCKET/x86_64/falco-FALCOVER-x86_64.tar.gz) |
| tgz-static-x86_64 | [![tgz-static](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/binFALCOBUCKET/x86_64/falco-FALCOVER-static-x86_64.tar.gz) |
| rpm-aarch64 | [![rpm](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpmFALCOBUCKET/falco-FALCOVER-aarch64.rpm) |
| deb-aarch64 | [![deb](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/debFALCOBUCKET/stable/falco-FALCOVER-aarch64.deb) |
| tgz-aarch64 | [![tgz](https://img.shields.io/badge/Falco-FALCOVER-%2300aec7?style=flat-square)](https://download.falco.org/packages/binFALCOBUCKET/aarch64/falco-FALCOVER-aarch64.tar.gz) |

View File

@@ -27,7 +27,6 @@ jobs:
version: ${{ needs.fetch-version.outputs.version }}
enable_debug: true
enable_sanitizers: true
use_mimalloc: true
build-dev-packages-arm64:
needs: [fetch-version]
@@ -36,31 +35,28 @@ 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]
uses: ./.github/workflows/reusable_test_packages.yaml
# See https://github.com/falcosecurity/falco/pull/3482
# Since musl build does not support dynamically loaded plugins,
# many tests would fail (the ones using `container.foo` fields).
# Disable tests on static builds for now.
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
# sanitizers: ${{ matrix.static == '' && true || false }}
sanitizers: true
# static: ${{ matrix.static != '' && true || false }}
sanitizers: ${{ matrix.static == '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
test-dev-packages-arm64:
needs: [fetch-version, build-dev-packages-arm64]
uses: ./.github/workflows/reusable_test_packages.yaml
strategy:
fail-fast: false
with:
arch: aarch64
static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
build-dev-minimal:

View File

@@ -31,17 +31,13 @@ jobs:
test-dev-packages:
needs: [fetch-version, build-dev-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
# See https://github.com/falcosecurity/falco/pull/3482
# Since musl build does not support dynamically loaded plugins,
# many tests would fail (the ones using `container.foo` fields).
# Disable tests on static builds for now.
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
# static: ${{ matrix.static != '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
test-dev-packages-arm64:

View File

@@ -56,7 +56,6 @@ jobs:
with:
arch: x86_64
version: ${{ github.event.release.tag_name }}
use_jemalloc: true
secrets: inherit
build-packages-arm64:
@@ -65,23 +64,18 @@ jobs:
with:
arch: aarch64
version: ${{ github.event.release.tag_name }}
use_jemalloc: true
secrets: inherit
test-packages:
needs: [release-settings, build-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
# See https://github.com/falcosecurity/falco/pull/3482
# Since musl build does not support dynamically loaded plugins,
# many tests would fail (the ones using `container.foo` fields).
# Disable tests on static builds for now.
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
# static: ${{ matrix.static != '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ github.event.release.tag_name }}
test-packages-arm64:

View File

@@ -43,40 +43,39 @@ jobs:
- name: Build falco image
run: |
docker build -f docker/falco/Dockerfile -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }} \
cd ${{ github.workspace }}/docker/falco/
docker build -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
- name: Build falco-debian image
run: |
docker build -f docker/falco-debian/Dockerfile -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}-debian \
cd ${{ github.workspace }}/docker/falco-debian/
docker build -t docker.io/falcosecurity/falco:${{ inputs.arch }}-${{ inputs.tag }}-debian \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg 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
- name: Build falco-driver-loader image
run: |
docker build -f docker/driver-loader/Dockerfile -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} \
cd ${{ github.workspace }}/docker/driver-loader/
docker build -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg FALCO_IMAGE_TAG=${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg 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
- name: Build falco-driver-loader-buster image
run: |
docker build -f docker/driver-loader-buster/Dockerfile -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}-buster \
cd ${{ github.workspace }}/docker/driver-loader-buster/
docker build -t docker.io/falcosecurity/falco-driver-loader:${{ inputs.arch }}-${{ inputs.tag }}-buster \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg 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,25 +20,15 @@ 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:
build-modern-bpf-skeleton:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'ubuntu-22.04-arm') || 'ubuntu-latest' }}
container: fedora:41
container: fedora:latest
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build dependencies
@@ -69,12 +59,7 @@ jobs:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build deps
run: |
sudo apt update && sudo apt install -y --no-install-recommends ca-certificates cmake curl wget build-essential git pkg-config autoconf automake libtool m4 rpm alien
- 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-59.el9.noarch.rpm
sudo alien -d -i systemd-rpm-macros-252-59.el9.noarch.rpm
sudo apt update && sudo apt install -y --no-install-recommends ca-certificates cmake curl wget build-essential git pkg-config autoconf automake libtool m4 rpm
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
@@ -98,8 +83,7 @@ jobs:
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=${{ inputs.use_jemalloc }} \
-DUSE_MIMALLOC=${{ inputs.use_mimalloc }} \
-DUSE_JEMALLOC=ON \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
@@ -171,8 +155,7 @@ jobs:
-DMODERN_BPF_SKEL_DIR=/tmp \
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=${{ inputs.use_jemalloc }} \
-DUSE_MIMALLOC=${{ inputs.use_mimalloc }} \
-DUSE_JEMALLOC=On \
-DFALCO_VERSION=${{ inputs.version }}
- name: Build project
@@ -221,7 +204,6 @@ jobs:
-DBUILD_DRIVER=Off \
-DBUILD_BPF=Off \
-DUSE_JEMALLOC=Off \
-DUSE_MIMALLOC=Off \
-DUSE_ASAN=On \
-DFALCO_VERSION=${{ inputs.version }}
@@ -266,8 +248,7 @@ jobs:
-DCMAKE_BUILD_TYPE=Release \
-DCPACK_GENERATOR=TGZ \
-DBUILD_BPF=Off -DBUILD_DRIVER=Off \
-DUSE_JEMALLOC=${{ inputs.use_jemalloc }} \
-DUSE_MIMALLOC=${{ inputs.use_mimalloc }} \
-DUSE_JEMALLOC=On \
-DUSE_BUNDLED_DEPS=On \
-DMUSL_OPTIMIZED_BUILD=On \
-DFALCO_ETC_DIR=/etc/falco \
@@ -353,9 +334,6 @@ 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

@@ -40,7 +40,8 @@ jobs:
tar -xvf $(ls falco-*.tar.gz)
cd falco-${{ inputs.version }}-${{ inputs.arch }}
sudo cp -r * /
# We only run driver loader tests on x86_64
- name: Install kernel headers for falco-driver-loader tests
run: |
sudo apt update -y
@@ -48,7 +49,6 @@ jobs:
# Some builds use sanitizers, we always install support for them so they can run
- name: Install sanitizer support
if: inputs.sanitizers
run: |
sudo apt update -y
sudo apt install -y libasan5 libubsan1
@@ -56,7 +56,7 @@ jobs:
- name: Run tests
env:
LSAN_OPTIONS: "intercept_tls_get_addr=0"
uses: falcosecurity/testing@main
uses: falcosecurity/testing@main
with:
test-falco: 'true'
test-falcoctl: 'true'

View File

@@ -43,8 +43,6 @@ This is a list of production adopters of Falco (in alphabetical order):
* [MathWorks](https://mathworks.com) - MathWorks develops mathematical computing software for engineers and scientists. MathWorks uses Falco for Kubernetes threat detection, unexpected application behavior, and maps Falco rules to their cloud infrastructure's security kill chain model. MathWorks presented their Falco use case at [KubeCon + CloudNativeCon North America 2020](https://www.youtube.com/watch?v=L-5RYBTV010).
* [NETWAYS Web Services](https://nws.netways.de/en/) - NETWAYS Web Services provides cloud and managed services tailored to their customers needs. From VPCs to managed databases and Kubernetes clusters, NETWAYS Web Services enables their customers to run infrastructure and applications without worries. Falco plays its part for NETWAYS Managed Services to ensure their platform conforms to ISO 27001 at all times and that their clients' workloads behave as expected by detecting anomalies in real-time.
* [Pocteo](https://pocteo.co) - Pocteo helps with Kubernetes adoption in enterprises by providing a variety of services such as training, consulting, auditing and mentoring. We build CI/CD pipelines the GitOps way, as well as design and run k8s clusters. Pocteo uses Falco as a runtime monitoring system to secure clients' workloads against suspicious behavior and ensure k8s pods immutability. We also use Falco to collect, process and act on security events through a response engine and serverless functions.
* [Preferral](https://www.preferral.com) - Preferral is a HIPAA-compliant platform for Referral Management and Online Referral Forms. Preferral streamlines the referral process for patients, specialists and their referral partners. By automating the referral process, referring practices spend less time on the phone, manual efforts are eliminated, and patients get the right care from the right specialist. Preferral leverages Falco to provide a Host Intrusion Detection System to meet their HIPAA compliance requirements.
@@ -60,8 +58,6 @@ This is a list of production adopters of Falco (in alphabetical order):
* [Shopify](https://www.shopify.com) - Shopify is the leading multi-channel commerce platform. Merchants use Shopify to design, set up, and manage their stores across multiple sales channels, including mobile, web, social media, marketplaces, brick-and-mortar locations, and pop-up shops. The platform also provides merchants with a powerful back-office and a single view of their business, from payments to shipping. The Shopify platform was engineered for reliability and scale, making enterprise-level technology available to businesses of all sizes. Shopify uses Falco to complement its Host and Network Intrusion Detection Systems.
* [SafeDep](https://safedep.io/) - SafeDep is a open source software supply chain security platform that helps organizations identify and mitigate risks in their dependencies. At its core, SafeDep offers [`vet`](https://github.com/safedep/vet) a free and open source tool for detecting vulnerabilities, malicious code, and quality issues in open source components, while the enterprise offering, SafeDep Cloud, provides centralized control, data aggregation, and advanced features like malware analysis for large-scale deployments across thousands of repositories.
* [Sight Machine](https://www.sightmachine.com) - Sight Machine is the category leader for manufacturing analytics and used by Global 500 companies to make better, faster decisions about their operations. Sight Machine uses Falco to help enforce SOC2 compliance as well as a tool for real time security monitoring and alerting in Kubernetes.
* [Skyscanner](https://www.skyscanner.net) - Skyscanner is the world's travel search engine for flights, hotels and car rentals. Most of our infrastructure is based on Kubernetes, and our Security team is using Falco to monitor anomalies at runtime, integrating Falco's findings with our internal ChatOps tooling to provide insight on the behavior of our machines in production. We also postprocess and store Falco's results to generate dashboards for auditing purposes.

View File

@@ -1,310 +1,5 @@
# 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
### Breaking Changes :warning:
* cleanup(engine)!: only consider .yaml/.yml rule files [[#3551](https://github.com/falcosecurity/falco/pull/3551)] - [@LucaGuerra](https://github.com/LucaGuerra)
* cleanup(userspace)!: deprecate print of `container.info` [[#3543](https://github.com/falcosecurity/falco/pull/3543)] - [@FedeDP](https://github.com/FedeDP)
* cleanup(userspace/falco)!: drop deprecated in 0.40.0 CLI flags. [[#3496](https://github.com/falcosecurity/falco/pull/3496)] - [@FedeDP](https://github.com/FedeDP)
### Major Changes
* new(falco): add json_include_output_fields option [[#3527](https://github.com/falcosecurity/falco/pull/3527)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(build,userspace): switch to use container plugin [[#3482](https://github.com/falcosecurity/falco/pull/3482)] - [@FedeDP](https://github.com/FedeDP)
* new(docker,scripts,ci): use an override config file to enable ISO 8601 output timeformat on docker images [[#3488](https://github.com/falcosecurity/falco/pull/3488)] - [@FedeDP](https://github.com/FedeDP)
### Minor Changes
* chore(build): update falcoctl to v0.11.2, rules for artifact follow to v4 [[#3580](https://github.com/falcosecurity/falco/pull/3580)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(cmake): bumped falcoctl to 0.11.1 and rules to 4.0.0. [[#3577](https://github.com/falcosecurity/falco/pull/3577)] - [@FedeDP](https://github.com/FedeDP)
* update(containers): update opencontainers labels [[#3575](https://github.com/falcosecurity/falco/pull/3575)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(metrics): improve restart/hot_reload conditions inspection [[#3562](https://github.com/falcosecurity/falco/pull/3562)] - [@incertum](https://github.com/incertum)
* update: empty `values` in `exceptions` won't emit a warning anymore [[#3529](https://github.com/falcosecurity/falco/pull/3529)] - [@leogr](https://github.com/leogr)
* chore(falco.yaml): enable libs_logger by default with info level [[#3507](https://github.com/falcosecurity/falco/pull/3507)] - [@FedeDP](https://github.com/FedeDP)
### Bug Fixes
* fix(metrics/prometheus): gracefully handle multiple event sources, avoid erroneous duplicate metrics [[#3563](https://github.com/falcosecurity/falco/pull/3563)] - [@incertum](https://github.com/incertum)
* fix(ci): properly install rpm systemd-rpm-macro package on building packages pipeline [[#3521](https://github.com/falcosecurity/falco/pull/3521)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/falco): init cmdline options after loading all config files [[#3493](https://github.com/falcosecurity/falco/pull/3493)] - [@FedeDP](https://github.com/FedeDP)
* fix(cmake): add support for 16K kernel page to jemalloc [[#3490](https://github.com/falcosecurity/falco/pull/3490)] - [@Darkness4](https://github.com/Darkness4)
* fix(userspace/falco): fix jemalloc enabled in minimal build. [[#3478](https://github.com/falcosecurity/falco/pull/3478)] - [@FedeDP](https://github.com/FedeDP)
### Non user-facing changes
* chore(deps): Bump submodules/falcosecurity-rules from `4ccf111` to `cb17833` [[#3572](https://github.com/falcosecurity/falco/pull/3572)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake/rules): bump to falco-rules-4.0.0-rc1 [[#3567](https://github.com/falcosecurity/falco/pull/3567)] - [@leogr](https://github.com/leogr)
* cleanup(userspace/falco): drop unused `libs_metrics_collector` variable. [[#3566](https://github.com/falcosecurity/falco/pull/3566)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3564](https://github.com/falcosecurity/falco/pull/3564)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* fix(build): fixed container custom_target `sed` command. [[#3556](https://github.com/falcosecurity/falco/pull/3556)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `ae6ed41` to `4ccf111` [[#3555](https://github.com/falcosecurity/falco/pull/3555)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix(cmake): fix bundled c-ares cmake issue with e.g. SLES [[#3559](https://github.com/falcosecurity/falco/pull/3559)] - [@terror96](https://github.com/terror96)
* chore(deps): Bump submodules/falcosecurity-rules from `1d2c6b1` to `ae6ed41` [[#3553](https://github.com/falcosecurity/falco/pull/3553)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore: revert "chore(deps): Bump submodules/falcosecurity-rules from `1d2c6b1` to `371e431`" [[#3552](https://github.com/falcosecurity/falco/pull/3552)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3550](https://github.com/falcosecurity/falco/pull/3550)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3549](https://github.com/falcosecurity/falco/pull/3549)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(adopters): added SafeDep as adopter [[#3548](https://github.com/falcosecurity/falco/pull/3548)] - [@KunalSin9h](https://github.com/KunalSin9h)
* update(cmake): update libs and driver to latest master [[#3547](https://github.com/falcosecurity/falco/pull/3547)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3541](https://github.com/falcosecurity/falco/pull/3541)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* fix(userspace): fixed engine `openssl` dep. [[#3535](https://github.com/falcosecurity/falco/pull/3535)] - [@FedeDP](https://github.com/FedeDP)
* fix(userspace/falco): fix outputs_http timeout [[#3523](https://github.com/falcosecurity/falco/pull/3523)] - [@benierc](https://github.com/benierc)
* fix(ci): use clang-19 to build modern_ebpf skeleton. [[#3537](https://github.com/falcosecurity/falco/pull/3537)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3531](https://github.com/falcosecurity/falco/pull/3531)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3530](https://github.com/falcosecurity/falco/pull/3530)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3525](https://github.com/falcosecurity/falco/pull/3525)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3520](https://github.com/falcosecurity/falco/pull/3520)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3516](https://github.com/falcosecurity/falco/pull/3516)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* docs(README.md): cleanups and enhancements [[#3514](https://github.com/falcosecurity/falco/pull/3514)] - [@leogr](https://github.com/leogr)
* update(cmake): update libs and driver to latest master [[#3511](https://github.com/falcosecurity/falco/pull/3511)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* chore(deps): Bump submodules/falcosecurity-rules from `1d2c6b1` to `371e431` [[#3510](https://github.com/falcosecurity/falco/pull/3510)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake): update libs and driver to latest master [[#3508](https://github.com/falcosecurity/falco/pull/3508)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* update(cmake): update libs and driver to latest master [[#3506](https://github.com/falcosecurity/falco/pull/3506)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* fix(userspace/falco): when counting `-M` timeout, do not account for async events [[#3505](https://github.com/falcosecurity/falco/pull/3505)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `d8415c1` to `1d2c6b1` [[#3504](https://github.com/falcosecurity/falco/pull/3504)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* docs(proposals): correct typo in example [[#3499](https://github.com/falcosecurity/falco/pull/3499)] - [@leogr](https://github.com/leogr)
* fix(docker): fixed entrypoints paths with new docker context. [[#3492](https://github.com/falcosecurity/falco/pull/3492)] - [@FedeDP](https://github.com/FedeDP)
* feat(falco/app): move actions not using config before `load_config` [[#3483](https://github.com/falcosecurity/falco/pull/3483)] - [@ekoops](https://github.com/ekoops)
* refactor(falco/app): apply early return pattern in actions code [[#3484](https://github.com/falcosecurity/falco/pull/3484)] - [@ekoops](https://github.com/ekoops)
* chore(deps): Bump submodules/falcosecurity-rules from `abf6637` to `d8415c1` [[#3489](https://github.com/falcosecurity/falco/pull/3489)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* Add NETWAYS Web Services to ADOPTERS.md [[#3487](https://github.com/falcosecurity/falco/pull/3487)] - [@mocdaniel](https://github.com/mocdaniel)
* chore: add back Falco static package to the release template. [[#3472](https://github.com/falcosecurity/falco/pull/3472)] - [@FedeDP](https://github.com/FedeDP)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 36 |
| Release note | 17 |
| Total | 53 |
## v0.40.0
Released on 2025-01-28
### Breaking Changes :warning:
* cleanup(userspac/falco)!: drop deprecated options. [[#3361](https://github.com/falcosecurity/falco/pull/3361)] - [@FedeDP](https://github.com/FedeDP)
### Major Changes
* new(docker): streamline docker images [[#3273](https://github.com/falcosecurity/falco/pull/3273)] - [@FedeDP](https://github.com/FedeDP)
* new(build): reintroduce static build [[#3428](https://github.com/falcosecurity/falco/pull/3428)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(cmake,ci): added support for using jemalloc allocator instead of glibc one and use it by default for release artifacts [[#3406](https://github.com/falcosecurity/falco/pull/3406)] - [@FedeDP](https://github.com/FedeDP)
* new(userspace,cmake): honor new plugins exposed suggested output formats [[#3388](https://github.com/falcosecurity/falco/pull/3388)] - [@FedeDP](https://github.com/FedeDP)
* new(userspace/falco): allow entirely disabling plugin hostinfo support. [[#3412](https://github.com/falcosecurity/falco/pull/3412)] - [@FedeDP](https://github.com/FedeDP)
* new(ci): use `zig` compiler instead of relying on centos7. [[#3307](https://github.com/falcosecurity/falco/pull/3307)] - [@FedeDP](https://github.com/FedeDP)
* new(falco): add buffer_format_base64 option, deprecate -b [[#3358](https://github.com/falcosecurity/falco/pull/3358)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(falco): add base_syscalls.all option to falco.yaml, deprecate -A [[#3352](https://github.com/falcosecurity/falco/pull/3352)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(falco): add falco_libs.snaplen option, deprecate -S / --snaplen [[#3362](https://github.com/falcosecurity/falco/pull/3362)] - [@LucaGuerra](https://github.com/LucaGuerra)
### Minor Changes
* update(cmake): bump falcoctl to v0.11.0 [[#3467](https://github.com/falcosecurity/falco/pull/3467)] - [@alacuku](https://github.com/alacuku)
* chore(ci): add attestation for falco [[#3216](https://github.com/falcosecurity/falco/pull/3216)] - [@cpanato](https://github.com/cpanato)
* chore(ci): build Falco in RelWithDebInfo, and upload Falco debug symbols as github artifacts [[#3452](https://github.com/falcosecurity/falco/pull/3452)] - [@FedeDP](https://github.com/FedeDP)
* update(build): DEB and RPM package requirements for dkms and kernel-devel are now suggestions [[#3450](https://github.com/falcosecurity/falco/pull/3450)] - [@jthiltges](https://github.com/jthiltges)
### Bug Fixes
* fix(userspace/falco): fix container_engines.cri.sockets not loading from config file [[#3453](https://github.com/falcosecurity/falco/pull/3453)] - [@zayaanmoez](https://github.com/zayaanmoez)
* fix(docker): /usr/src/'*' no longer created if $HOST_PATH/usr/src didn't exist at startup [[#3434](https://github.com/falcosecurity/falco/pull/3434)] - [@shane-lawrence](https://github.com/shane-lawrence)
* fix(docker): add brotli to the Falco image [[#3399](https://github.com/falcosecurity/falco/pull/3399)] - [@LucaGuerra](https://github.com/LucaGuerra)
* fix(userspace/engine): explicitly disallow appending/modifying a rule with different sources [[#3383](https://github.com/falcosecurity/falco/pull/3383)] - [@mstemm](https://github.com/mstemm)
### Non user-facing changes
* chore(falco.yaml): remove comments about cri cli arguments [[#3458](https://github.com/falcosecurity/falco/pull/3458)] - [@alacuku](https://github.com/alacuku)
* fix(ci): fixed reusable_build/publish_docker workflows. [[#3459](https://github.com/falcosecurity/falco/pull/3459)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3455](https://github.com/falcosecurity/falco/pull/3455)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* chore(ci): bumped actions/upload-download-artifact. [[#3454](https://github.com/falcosecurity/falco/pull/3454)] - [@FedeDP](https://github.com/FedeDP)
* chore(docker): drop unused libelf dep from container images [[#3451](https://github.com/falcosecurity/falco/pull/3451)] - [@leogr](https://github.com/leogr)
* chore(docs): update `plugins_hostinfo` config file comment. [[#3449](https://github.com/falcosecurity/falco/pull/3449)] - [@FedeDP](https://github.com/FedeDP)
* new(build): add RelWithDebInfo target [[#3440](https://github.com/falcosecurity/falco/pull/3440)] - [@shane-lawrence](https://github.com/shane-lawrence)
* chore(deps): Bump submodules/falcosecurity-rules from `283a62f` to `abf6637` [[#3448](https://github.com/falcosecurity/falco/pull/3448)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(ci): use 4cpu-16gb arm runners [[#3447](https://github.com/falcosecurity/falco/pull/3447)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(cmake): update libs and driver to latest master [[#3439](https://github.com/falcosecurity/falco/pull/3439)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* chore: avoid deprecated funcs to calculate sha256 [[#3442](https://github.com/falcosecurity/falco/pull/3442)] - [@federico-sysdig](https://github.com/federico-sysdig)
* chore(ci): enable jemalloc in musl build. [[#3436](https://github.com/falcosecurity/falco/pull/3436)] - [@FedeDP](https://github.com/FedeDP)
* docs(falco.yaml): correct `buffered_outputs` description [[#3427](https://github.com/falcosecurity/falco/pull/3427)] - [@leogr](https://github.com/leogr)
* fix(userspace/falco): use correct filtercheck_field_info. [[#3426](https://github.com/falcosecurity/falco/pull/3426)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3421](https://github.com/falcosecurity/falco/pull/3421)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* fix: update the url for the docs about the concurrent queue classes [[#3415](https://github.com/falcosecurity/falco/pull/3415)] - [@Issif](https://github.com/Issif)
* update(changelog): updated changelog for 0.39.2. [[#3410](https://github.com/falcosecurity/falco/pull/3410)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3392](https://github.com/falcosecurity/falco/pull/3392)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* fix(cmake,docker): avoid cpp-httplib requiring brotli. [[#3400](https://github.com/falcosecurity/falco/pull/3400)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `407e997` to `283a62f` [[#3391](https://github.com/falcosecurity/falco/pull/3391)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake): bump libs to latest master. [[#3389](https://github.com/falcosecurity/falco/pull/3389)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): update libs and driver to latest master [[#3385](https://github.com/falcosecurity/falco/pull/3385)] - [@github-actions[bot]](https://github.com/apps/github-actions)
* Make enable()/disable() virtual so they can be overridden [[#3375](https://github.com/falcosecurity/falco/pull/3375)] - [@mstemm](https://github.com/mstemm)
* fix(ci): fixed shasum computation for bump-libs CI. [[#3379](https://github.com/falcosecurity/falco/pull/3379)] - [@FedeDP](https://github.com/FedeDP)
* chore(ci): use redhat advised method to check rpmsign success. [[#3376](https://github.com/falcosecurity/falco/pull/3376)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `e38fb3f` to `407e997` [[#3374](https://github.com/falcosecurity/falco/pull/3374)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* Compile output clone [[#3364](https://github.com/falcosecurity/falco/pull/3364)] - [@mstemm](https://github.com/mstemm)
* fix(ci): fixed bump-libs workflow syntax. [[#3369](https://github.com/falcosecurity/falco/pull/3369)] - [@FedeDP](https://github.com/FedeDP)
* new(ci): add a workflow to automatically bump libs on each monday. [[#3360](https://github.com/falcosecurity/falco/pull/3360)] - [@FedeDP](https://github.com/FedeDP)
* chore(deps): Bump submodules/falcosecurity-rules from `b6ad373` to `e38fb3f` [[#3365](https://github.com/falcosecurity/falco/pull/3365)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* cleanup(falco): reformat options::define [[#3356](https://github.com/falcosecurity/falco/pull/3356)] - [@LucaGuerra](https://github.com/LucaGuerra)
### Statistics
| MERGED PRS | NUMBER |
|-----------------|--------|
| Not user-facing | 31 |
| Release note | 18 |
| Total | 49 |
## v0.39.2
Released on 2024-11-21

View File

@@ -29,18 +29,7 @@ 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)
# 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()
option(USE_JEMALLOC "Use jemalloc allocator" OFF)
if(WIN32)
if(POLICY CMP0091)
@@ -153,29 +142,19 @@ 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)
@@ -288,35 +267,6 @@ if(NOT WIN32
AND NOT MUSL_OPTIMIZED_BUILD
)
include(falcoctl)
include(container_plugin)
# Generate a binary_dir/falco.yaml that automatically enables the plugin to be used for local
# testing.
configure_file(${CMAKE_SOURCE_DIR}/falco.yaml ${CMAKE_BINARY_DIR} COPYONLY)
# The custom target configures the plugin and set its path
add_custom_target(
container
COMMAND sed -i 's,^load_plugins: .*,load_plugins: [container],g'
${CMAKE_BINARY_DIR}/falco.yaml
COMMAND sed -i 's,library_path: libcontainer.so,library_path: ${CONTAINER_LIBRARY},g'
${CMAKE_BINARY_DIR}/falco.yaml
DEPENDS container_plugin
)
# Let `make falco` also download container plugin
add_dependencies(falco container)
# Install the plugin
install(
FILES "${CONTAINER_LIBRARY}"
DESTINATION "${FALCO_ABSOLUTE_SHARE_DIR}/plugins"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
# Install additional config override file to enable the container plugin
install(
FILES "${PROJECT_SOURCE_DIR}/config/falco.container_plugin.yaml"
DESTINATION "${FALCO_ETC_DIR}/config.d"
COMPONENT "${FALCO_COMPONENT_NAME}"
)
endif()
# Packages configuration

3
OWNERS
View File

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

View File

@@ -2,7 +2,7 @@
[![Latest release](https://img.shields.io/github/v/release/falcosecurity/falco?style=for-the-badge)](https://github.com/falcosecurity/falco/releases/latest) [![Supported Architectures](https://img.shields.io/badge/ARCHS-x86__64%7Caarch64-blueviolet?style=for-the-badge)](https://github.com/falcosecurity/falco/releases/latest) [![License](https://img.shields.io/github/license/falcosecurity/falco?style=for-the-badge)](COPYING) [![Docs](https://img.shields.io/badge/docs-latest-green.svg?style=for-the-badge)](https://falco.org/docs)
[![Falco Core Repository](https://github.com/falcosecurity/evolution/blob/main/repos/badges/falco-core-blue.svg)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#core-scope) [![Stable](https://img.shields.io/badge/status-stable-brightgreen?style=for-the-badge)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#stable) [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/falcosecurity/falco?label=openssf%20scorecard&style=for-the-badge)](https://scorecard.dev/viewer/?uri=github.com/falcosecurity/falco) [![OpenSSF Best Practices](https://img.shields.io/cii/summary/2317?label=OpenSSF%20Best%20Practices&style=for-the-badge)](https://bestpractices.coreinfrastructure.org/projects/2317)
[![Falco Core Repository](https://github.com/falcosecurity/evolution/blob/main/repos/badges/falco-core-blue.svg)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#core-scope) [![Stable](https://img.shields.io/badge/status-stable-brightgreen?style=for-the-badge)](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md#stable) [![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/falcosecurity/falco?label=openssf%20scorecard&style=for-the-badge)](https://scorecard.dev/viewer/?uri=github.com/falcosecurity/falco) [![OpenSSF Best Practices](https://img.shields.io/cii/summary/2317?label=OpenSSF%20Best%20Practices&style=for-the-badge)](https://bestpractices.coreinfrastructure.org/projects/2317) <a href="https://actuated.dev/"><img alt="Arm CI sponsored by Actuated" src="https://docs.actuated.dev/images/actuated-badge.png" width="120px"></img></a>
[![Falco](https://falco.org/img/brand/falco-horizontal-color.svg)](https://falco.org)
@@ -14,30 +14,43 @@ Falco, originally created by [Sysdig](https://sysdig.com), is a **graduated proj
For detailed technical information and insights into the cyber threats that Falco can detect, visit the official [Falco](https://falco.org/) website.
For comprehensive information on the latest updates and changes to the project, please refer to the [Change Log](CHANGELOG.md).
For comprehensive information on the latest updates and changes to the project, please refer to the [Change Log](CHANGELOG.md). Additionally, we have documented the [Release Process](RELEASE.md) for delivering new versions of Falco.
## The Falco Project
## Falco Repo: Powering the Core of The Falco Project
The Falco Project codebase is maintained under the [falcosecurity GitHub organization](https://github.com/falcosecurity). The primary repository, [falcosecurity/falco](https://github.com/falcosecurity/falco), holds the source code for the Falco binary, while other sub-projects are hosted in dedicated repositories. This approach of isolating components into specialized repositories enhances modularity and focused development. Notable [core repositories](https://github.com/falcosecurity/evolution?tab=readme-ov-file#core) include:
This is the main Falco repository which contains the source code for building the Falco binary. By utilizing its [libs](https://github.com/falcosecurity/libs) and the [falco.yaml](falco.yaml) configuration file, this repository forms the foundation of Falco's functionality. The Falco repository is closely interconnected with the following *core* repositories:
- [falcosecurity/libs](https://github.com/falcosecurity/libs): This repository hosts Falco's core libraries, which constitute the majority of the binarys source code and provide essential features, such as kernel drivers.
- [falcosecurity/rules](https://github.com/falcosecurity/rules): It contains the official ruleset for Falco, offering pre-defined detection rules for various security threats and abnormal behaviors.
- [falcosecurity/plugins](https://github.com/falcosecurity/plugins): This repository supports integration with external services through plugins that extend Falco's capabilities beyond syscalls and container events, with plans for evolving specialized functionalities in future releases.
- [falcosecurity/falcoctl](https://github.com/falcosecurity/falcoctl): A command-line utility designed for managing and interacting with Falco.
- [falcosecurity/charts](https://github.com/falcosecurity/charts): This repository provides Helm charts for deploying Falco and its ecosystem, simplifying the installation and management process.
- [falcosecurity/libs](https://github.com/falcosecurity/libs): Falco's libraries are key to its fundamental operations, making up the greater portion of the source code of the Falco binary and providing essential features such as kernel drivers.
- [falcosecurity/rules](https://github.com/falcosecurity/rules): Contains the official ruleset for Falco, providing pre-defined detection rules for various security threats and abnormal behaviors.
- [falcosecurity/plugins](https://github.com/falcosecurity/plugins/): Falco plugins facilitate integration with external services, expand Falco's capabilities beyond syscalls and container events, and are designed to evolve with specialized functionality in future releases.
- [falcosecurity/falcoctl](https://github.com/falcosecurity/falcoctl): Command-line utility for managing and interacting with Falco.
For further insights into our repositories and additional details about our governance model, please visit the official hub of The Falco Project: [falcosecurity/evolution](https://github.com/falcosecurity/evolution).
For more information, visit the official hub of The Falco Project: [falcosecurity/evolution](https://github.com/falcosecurity/evolution). It provides valuable insights and information about the project's repositories.
## Getting Started with Falco
If you're new to Falco, begin your journey with our [Getting Started](https://falco.org/docs/getting-started/) guide. For production deployments, please refer to our comprehensive [Setup](https://falco.org/docs/setup/) documentation.
Carefully review and follow the [Official Documentation](https://falco.org/docs/install-operate/).
As final recommendations before deploying Falco, verify environment compatibility, define your detection goals, optimize performance, choose the appropriate build, and plan for SIEM or data lake integration to ensure effective incident response.
Considerations and guidance for Falco adopters:
1. Understand dependencies: Assess the environment where you'll run Falco and consider kernel versions and architectures.
2. Define threat detection objectives: Clearly identify the threats you want to detect and evaluate Falco's strengths and limitations.
3. Consider performance and cost: Assess compute performance overhead and align with system administrators or SREs. Budget accordingly.
4. Choose build and customization approach: Decide between the open source Falco build or creating a custom build pipeline. Customize the build and deployment process as necessary, including incorporating unique tests or approaches, to ensure a resilient deployment with fast deployment cycles.
5. Integrate with output destinations: Integrate Falco with SIEM, data lake systems, or other preferred output destinations to establish a robust foundation for comprehensive data analysis and enable effective incident response workflows.
### Demo Environment
A demo environment is provided via a docker-compose file that can be started on a docker host which includes falco, falcosidekick, falcosidekick-ui and its required redis database. For more information see the [docker-compose section](docker/docker-compose/)
## How to Contribute
Please refer to the [Contributing](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) guide and the [Code of Conduct](https://github.com/falcosecurity/evolution/blob/main/CODE_OF_CONDUCT.md) for more information on how to contribute.
## Join the Community
To get involved with the Falco Project please visit the [Community](https://github.com/falcosecurity/community) repository to find more information and ways to get involved.
@@ -58,16 +71,20 @@ In addition, you can refer to the [falco](https://github.com/falcosecurity/falco
To report security vulnerabilities, please follow the community process outlined in the documentation found [here](https://github.com/falcosecurity/.github/blob/main/SECURITY.md).
## Building
## What's next for Falco?
For comprehensive, step-by-step instructions on building Falco from source, please refer to the [official documentation](https://falco.org/docs/developer-guide/source/).
Stay updated with Falco's evolving capabilities by exploring the [Falco Roadmap](https://github.com/orgs/falcosecurity/projects/5), which provides insights into the features currently under development and planned for future releases.
## License
Falco is licensed to you under the [Apache 2.0](./COPYING) open source license.
## Testing
<details>
<summary>Expand Testing Instructions</summary>
Falco's [Build Falco from source](https://falco.org/docs/developer-guide/source/) is the go-to resource to understand how to build Falco from source. In addition, the [falcosecurity/libs](https://github.com/falcosecurity/libs) repository offers additional valuable information about tests and debugging of Falco's underlying libraries and kernel drivers.
Falco's [Build Falco from source](https://falco.org/docs/install-operate/source/) is the go-to resource to understand how to build Falco from source. In addition, the [falcosecurity/libs](https://github.com/falcosecurity/libs) repository offers additional valuable information about tests and debugging of Falco's underlying libraries and kernel drivers.
Here's an example of a `cmake` command that will enable everything you need for all unit tests of this repository:
@@ -100,13 +117,7 @@ Lastly, The Falco Project has moved its Falco regression tests to [falcosecurity
</br>
## How to Contribute
Please refer to the [Contributing](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) guide and the [Code of Conduct](https://github.com/falcosecurity/evolution/blob/main/CODE_OF_CONDUCT.md) for more information on how to contribute.
## FAQs
### Why is Falco in C++ rather than Go or {language}?
## Why is Falco in C++ rather than Go or {language}?
<details>
<summary>Expand Information</summary>
@@ -125,14 +136,6 @@ Please refer to the [Contributing](https://github.com/falcosecurity/.github/blob
</details>
</br>
### What's next for Falco?
Stay updated with Falco's evolving capabilities by exploring the [Falco Roadmap](https://github.com/orgs/falcosecurity/projects/5), which provides insights into the features currently under development and planned for future releases.
## License
Falco is licensed to you under the [Apache 2.0](./COPYING) open source license.
## Resources
- [Governance](https://github.com/falcosecurity/evolution/blob/main/GOVERNANCE.md)
@@ -142,6 +145,5 @@ Falco is licensed to you under the [Apache 2.0](./COPYING) open source license.
- [Repositories Guidelines](https://github.com/falcosecurity/evolution/blob/main/REPOSITORIES.md)
- [Repositories List](https://github.com/falcosecurity/evolution/blob/main/README.md#repositories)
- [Adopters List](https://github.com/falcosecurity/falco/blob/master/ADOPTERS.md)
- [Release Process](RELEASE.md)
- [Setup documentation](https://falco.org/docs/setup/)
- [Install and Operate](https://falco.org/docs/install-operate/)
- [Troubleshooting](https://falco.org/docs/troubleshooting/)

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 [community call](https://github.com/falcosecurity/community).
Moreover, we assign owners for each release (typically pairing a new person with an experienced one). Assignees and due dates for releases are proposed during the [weekly community call](https://github.com/falcosecurity/community).
At a high level each Falco release needs to follow a pre-determined sequencing of releases and build order:
@@ -84,15 +84,11 @@ 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)
- 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)
- Check the release note block of every PR matching the `is:pr is:merged closed:>YYYY-MM-DD` [filter](https://github.com/falcosecurity/falco/pulls?q=is%3Apr+is%3Amerged+closed%3A%3EYYYY-MM-DD)
- Ensure the release note block follows the [commit convention](https://github.com/falcosecurity/.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
@@ -106,7 +102,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
@@ -116,7 +112,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 -r falcosecurity/falco -m M.m.p`
- Execute `rn2md -o falcosecurity -m <version> -r falco`
- 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
@@ -129,18 +125,16 @@ 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 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`).
The prerelease tag must be formatted as `M.m.p-r`where `r` is the prerelease version information (e.g. `0.35.0-rc1`.)
To create both pre-release tag and pre-release, do the following:
To do so:
- [Draft a new release](https://github.com/falcosecurity/falco/releases/new)
- Use `M.m.p-r` both as tag version and release title
- Associate `release/M.m.x` as "target branch" for the new tag
- Use `M.m.p-r` both as tag version and release title.
- Check the "Set as a pre-release" checkbox and make sure "Set as the latest release" is unchecked
- It is recommended to add a brief description so that other contributors will understand the reason why the prerelease is published
- Publish the prerelease!
- The release pipeline will start automatically. Packages will be uploaded to the `-dev` bucket and container images will be tagged with the specified tag
- 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.
@@ -152,7 +146,6 @@ 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.
@@ -165,7 +158,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/main/meeting-notes](https://github.com/falcosecurity/community/tree/main/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/master/meeting-notes](https://github.com/falcosecurity/community/tree/master/meeting-notes) as a new file labeled `release-M.m.p.md`
- Open up a pull request with the new change.
@@ -173,10 +166,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
@@ -188,7 +181,9 @@ 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

@@ -73,7 +73,7 @@ if(NOT MSVC)
if(BUILD_WARNINGS_AS_ERRORS)
set(CMAKE_SUPPRESSED_WARNINGS
"-Wno-unused-parameter -Wno-unused-variable -Wno-unused-but-set-variable -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-implicit-fallthrough -Wno-format-truncation -Wno-stringop-truncation -Wno-stringop-overflow -Wno-restrict -Wno-deprecated-declarations"
"-Wno-unused-parameter -Wno-unused-variable -Wno-unused-but-set-variable -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-implicit-fallthrough -Wno-format-truncation -Wno-stringop-truncation -Wno-stringop-overflow -Wno-restrict"
)
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
set(CMAKE_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wextra ${CMAKE_SUPPRESSED_WARNINGS}")

View File

@@ -1,78 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
option(USE_BUNDLED_CARES "Enable building of the bundled c-ares" ${USE_BUNDLED_DEPS})
if(CARES_INCLUDE)
# we already have c-ares
elseif(NOT USE_BUNDLED_CARES)
find_path(CARES_INCLUDE NAMES cares/ares.h ares.h)
find_library(CARES_LIB NAMES cares)
if(CARES_INCLUDE AND CARES_LIB)
message(STATUS "Found c-ares: include: ${CARES_INCLUDE}, lib: ${CARES_LIB}")
else()
message(FATAL_ERROR "Couldn't find system c-ares")
endif()
else()
if(BUILD_SHARED_LIBS)
set(CARES_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
set(CARES_STATIC_OPTION "Off")
else()
set(CARES_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(CARES_STATIC_OPTION "On")
endif()
set(CARES_SRC "${PROJECT_BINARY_DIR}/c-ares-prefix/src/c-ares")
set(CARES_INCLUDE "${CARES_SRC}/include/")
set(CARES_LIB "${CARES_SRC}/lib/libcares${CARES_LIB_SUFFIX}")
if(NOT TARGET c-ares)
message(STATUS "Using bundled c-ares in '${CARES_SRC}'")
ExternalProject_Add(
c-ares
PREFIX "${PROJECT_BINARY_DIR}/c-ares-prefix"
URL "https://github.com/c-ares/c-ares/releases/download/v1.33.1/c-ares-1.33.1.tar.gz"
URL_HASH "SHA256=06869824094745872fa26efd4c48e622b9bd82a89ef0ce693dc682a23604f415"
BUILD_IN_SOURCE 1
CMAKE_ARGS -DCMAKE_POLICY_DEFAULT_CMP0091:STRING=NEW
-DCMAKE_MSVC_RUNTIME_LIBRARY=${CMAKE_MSVC_RUNTIME_LIBRARY}
-DCMAKE_INSTALL_LIBDIR=lib
-DCARES_SHARED=${BUILD_SHARED_LIBS}
-DCARES_STATIC=${CARES_STATIC_OPTION}
-DCARES_STATIC_PIC=${ENABLE_PIC}
-DCARES_BUILD_TOOLS=Off
-DCARES_INSTALL=Off
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
BUILD_BYPRODUCTS ${CARES_INCLUDE} ${CARES_LIB}
INSTALL_COMMAND ""
)
install(
FILES "${CARES_LIB}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
install(
DIRECTORY "${CARES_INCLUDE}"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
endif()
endif()
if(NOT TARGET c-ares)
add_custom_target(c-ares)
endif()
include_directories("${CARES_INCLUDE}")

View File

@@ -20,14 +20,11 @@ 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.23.1.tar.gz
URL_HASH SHA256=410a1347ed6bcbcc4a19af8ed8ad3873fe9fa97731d52db845c4c78f3f9c31e6
URL https://github.com/yhirose/cpp-httplib/archive/refs/tags/v0.15.3.tar.gz
URL_HASH SHA256=2121bbf38871bb2aafb5f7f2b9b94705366170909f434428352187cb0216124e
)
FetchContent_MakeAvailable(cpp-httplib)
else()

View File

@@ -1,100 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
option(USE_BUNDLED_CURL "Enable building of the bundled curl" ${USE_BUNDLED_DEPS})
include(openssl)
include(zlib)
if(CURL_INCLUDE_DIRS)
# we already have curl
elseif(NOT USE_BUNDLED_CURL)
find_package(CURL REQUIRED)
message(STATUS "Found CURL: include: ${CURL_INCLUDE_DIRS}, lib: ${CURL_LIBRARIES}")
else()
if(BUILD_SHARED_LIBS)
set(CURL_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
set(CURL_STATIC_OPTION)
else()
set(CURL_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(CURL_STATIC_OPTION --disable-shared)
endif()
set(CURL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/curl-prefix/src/curl")
set(CURL_INCLUDE_DIRS "${CURL_BUNDLE_DIR}/include/")
set(CURL_LIBRARIES "${CURL_BUNDLE_DIR}/lib/.libs/libcurl${CURL_LIB_SUFFIX}")
if(NOT USE_BUNDLED_OPENSSL)
set(CURL_SSL_OPTION "--with-ssl")
else()
set(CURL_SSL_OPTION "--with-ssl=${OPENSSL_INSTALL_DIR}")
message(STATUS "Using SSL for curl in '${OPENSSL_INSTALL_DIR}'")
endif()
if(NOT USE_BUNDLED_ZLIB)
set(CURL_ZLIB_OPTION "--with-zlib")
else()
set(CURL_ZLIB_OPTION "--with-zlib=${ZLIB_SRC}")
message(STATUS "Using zlib for curl in '${ZLIB_SRC}'")
endif()
message(STATUS "Using bundled curl in '${CURL_BUNDLE_DIR}'")
if(NOT ENABLE_PIC)
set(CURL_PIC_OPTION)
else()
set(CURL_PIC_OPTION "--with-pic")
endif()
if(NOT TARGET curl)
ExternalProject_Add(
curl
PREFIX "${PROJECT_BINARY_DIR}/curl-prefix"
DEPENDS openssl zlib
URL "https://github.com/curl/curl/releases/download/curl-8_7_1/curl-8.7.1.tar.bz2"
URL_HASH "SHA256=05bbd2b698e9cfbab477c33aa5e99b4975501835a41b7ca6ca71de03d8849e76"
CONFIGURE_COMMAND
./configure ${CURL_SSL_OPTION} ${CURL_ZLIB_OPTION} ${CURL_STATIC_OPTION}
${CURL_PIC_OPTION} --enable-optimize --disable-curldebug --disable-rt --enable-http
--disable-ftp --disable-file --disable-ldap --disable-ldaps --disable-rtsp
--disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb
--disable-smtp --disable-gopher --disable-sspi --disable-ntlm-wb --disable-tls-srp
--without-winssl --without-polarssl --without-cyassl --without-nss --without-axtls
--without-librtmp --without-winidn --without-libidn2 --without-libpsl
--without-nghttp2 --without-libssh2 --with-ca-path=/etc/ssl/certs/
--disable-threaded-resolver --without-brotli --without-zstd
BUILD_COMMAND make
BUILD_IN_SOURCE 1
BUILD_BYPRODUCTS ${CURL_LIBRARIES}
INSTALL_COMMAND ""
)
install(
FILES "${CURL_LIBRARIES}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
install(
DIRECTORY "${CURL_INCLUDE_DIRS}curl"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
FILES_MATCHING
PATTERN "*.h"
)
endif()
endif()
if(NOT TARGET curl)
add_custom_target(curl)
endif()
include_directories("${CURL_INCLUDE_DIRS}")

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco Authors.
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. 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 "9e6a8ccd4e4f5796f45ad486decd00b4996129b7")
set(DRIVER_VERSION "8.0.0+driver")
set(DRIVER_CHECKSUM
"SHA256=87902814e29718529094b89ff2a3ddbd4ee7aa77da824d4acbaad0d863e04ce9"
"SHA256=f35990d6a1087a908fe94e1390027b9580d4636032c0f2b80bf945219474fd6b"
)
endif()

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco Authors.
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. 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.4")
set(FALCOCTL_VERSION "0.11.0")
message(STATUS "Building with falcoctl: ${FALCOCTL_VERSION}")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "8015cadcb4328abcbf140c3ca88031cd46426f7f3279d2802f0937ab1e41d66c")
set(FALCOCTL_HASH "b9d0e0f50813e7172a945f36f70c5c3c16a677ab4c85b35b6f7a155bc92768fc")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "246874f1168abb7a8463509c6191ede460e5a2b8a39058ef5c4a17b67cb86c85")
set(FALCOCTL_HASH "689c625d1d414cbf53d39ef94083a53dda3ea4ac4908799fb85f4519e21442e0")
endif()
ExternalProject_Add(

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco Authors.
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. 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 "9e6a8ccd4e4f5796f45ad486decd00b4996129b7")
set(FALCOSECURITY_LIBS_VERSION "0.20.0")
set(FALCOSECURITY_LIBS_CHECKSUM
"SHA256=87902814e29718529094b89ff2a3ddbd4ee7aa77da824d4acbaad0d863e04ce9"
"SHA256=4ae6ddb42a1012bacd88c63abdaa7bd27ca0143c4721338a22c45597e63bc99d"
)
endif()

View File

@@ -1,278 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
option(USE_BUNDLED_GRPC "Enable building of the bundled grpc" ${USE_BUNDLED_DEPS})
if(GRPC_INCLUDE)
# we already have grpc
elseif(NOT USE_BUNDLED_GRPC)
# gRPC
find_package(gRPC CONFIG)
if(gRPC_FOUND)
message(STATUS "Using gRPC ${gRPC_VERSION}")
set(GPR_LIB gRPC::gpr)
set(GRPC_LIB gRPC::grpc)
set(GRPCPP_LIB gRPC::grpc++)
# gRPC C++ plugin
get_target_property(GRPC_CPP_PLUGIN gRPC::grpc_cpp_plugin LOCATION)
if(NOT GRPC_CPP_PLUGIN)
message(FATAL_ERROR "System grpc_cpp_plugin not found")
endif()
# gRPC include dir + properly handle grpc{++,pp}
get_target_property(GRPC_INCLUDE gRPC::grpc++ INTERFACE_INCLUDE_DIRECTORIES)
find_path(
GRPCXX_INCLUDE
NAMES grpc++/grpc++.h
PATHS ${GRPC_INCLUDE}
)
if(NOT GRPCXX_INCLUDE)
find_path(
GRPCPP_INCLUDE
NAMES grpcpp/grpcpp.h
PATHS ${GRPC_INCLUDE}
)
add_definitions(-DGRPC_INCLUDE_IS_GRPCPP=1)
endif()
else()
# Fallback to manually find libraries; Some distro, namely Ubuntu focal, do not install gRPC
# config cmake module
find_library(GPR_LIB NAMES gpr)
if(GPR_LIB)
message(STATUS "Found gpr lib: ${GPR_LIB}")
else()
message(FATAL_ERROR "Couldn't find system gpr")
endif()
find_path(GRPCXX_INCLUDE NAMES grpc++/grpc++.h)
if(GRPCXX_INCLUDE)
set(GRPC_INCLUDE ${GRPCXX_INCLUDE})
else()
find_path(GRPCPP_INCLUDE NAMES grpcpp/grpcpp.h)
set(GRPC_INCLUDE ${GRPCPP_INCLUDE})
add_definitions(-DGRPC_INCLUDE_IS_GRPCPP=1)
endif()
find_library(GRPC_LIB NAMES grpc)
find_library(GRPCPP_LIB NAMES grpc++)
if(GRPC_INCLUDE
AND GRPC_LIB
AND GRPCPP_LIB
)
message(
STATUS
"Found grpc: include: ${GRPC_INCLUDE}, C lib: ${GRPC_LIB}, C++ lib: ${GRPCPP_LIB}"
)
else()
message(FATAL_ERROR "Couldn't find system grpc")
endif()
find_program(GRPC_CPP_PLUGIN grpc_cpp_plugin)
if(NOT GRPC_CPP_PLUGIN)
message(FATAL_ERROR "System grpc_cpp_plugin not found")
endif()
endif()
else()
include(cares)
include(protobuf)
include(zlib)
include(openssl)
if(BUILD_SHARED_LIBS)
set(GRPC_OPENSSL_STATIC_LIBS_OPTION FALSE)
else()
set(GRPC_OPENSSL_STATIC_LIBS_OPTION TRUE)
endif()
include(re2)
set(GRPC_SRC "${PROJECT_BINARY_DIR}/grpc-prefix/src/grpc")
set(GRPC_INSTALL_DIR "${GRPC_SRC}/target")
set(GRPC_INCLUDE "${GRPC_INSTALL_DIR}/include" "${GRPC_SRC}/third_party/abseil-cpp")
set(GPR_LIB "${GRPC_SRC}/libgpr.a")
set(GRPC_LIB "${GRPC_SRC}/libgrpc.a")
set(GRPCPP_LIB "${GRPC_SRC}/libgrpc++.a")
set(GRPC_CPP_PLUGIN "${GRPC_SRC}/grpc_cpp_plugin")
set(GRPC_MAIN_LIBS "")
list(
APPEND
GRPC_MAIN_LIBS
"${GPR_LIB}"
"${GRPC_LIB}"
"${GRPCPP_LIB}"
"${GRPC_SRC}/libgrpc++_alts.a"
"${GRPC_SRC}/libgrpc++_error_details.a"
"${GRPC_SRC}/libgrpc++_reflection.a"
"${GRPC_SRC}/libgrpc++_unsecure.a"
"${GRPC_SRC}/libgrpc_plugin_support.a"
"${GRPC_SRC}/libgrpc_unsecure.a"
"${GRPC_SRC}/libgrpcpp_channelz.a"
)
get_filename_component(PROTOC_DIR ${PROTOC} PATH)
if(NOT TARGET grpc)
message(STATUS "Using bundled grpc in '${GRPC_SRC}'")
# fixme(leogr): this workaround is required to inject the missing deps (built by gRCP
# cmakefiles) into target_link_libraries later note: the list below is manually generated
# starting from the output of pkg-config --libs grpc++
set(GRPC_LIBRARIES "")
list(
APPEND
GRPC_LIBRARIES
"${GRPC_SRC}/libaddress_sorting.a"
"${GRPC_SRC}/libupb.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_hash.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_city.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/hash/libabsl_low_level_hash.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/container/libabsl_raw_hash_set.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/container/libabsl_hashtablez_sampler.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/status/libabsl_statusor.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/status/libabsl_status.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cord.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cordz_functions.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/profiling/libabsl_exponential_biased.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/types/libabsl_bad_optional_access.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/types/libabsl_bad_variant_access.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_str_format_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/synchronization/libabsl_synchronization.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/synchronization/libabsl_graphcycles_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/debugging/libabsl_stacktrace.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/debugging/libabsl_symbolize.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/debugging/libabsl_debugging_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/debugging/libabsl_demangle_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_malloc_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/time/libabsl_time.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/time/libabsl_civil_time.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_strings.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_strings_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_base.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_spinlock_wait.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/numeric/libabsl_int128.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_throw_delegate.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_raw_logging_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/base/libabsl_log_severity.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/time/libabsl_time_zone.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cord_internal.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cordz_info.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/strings/libabsl_cordz_handle.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_pool_urbg.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen_hwaes.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen_hwaes_impl.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_randen_slow.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_seed_material.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_internal_platform.a"
"${GRPC_SRC}/third_party/abseil-cpp/absl/random/libabsl_random_seed_gen_exception.a"
)
# Make abseil-cpp build compatible with gcc-13 See
# https://patchwork.yoctoproject.org/project/oe/patch/20230518093301.2938164-1-Martin.Jansa@gmail.com/
# TO BE DROPPED once we finally upgrade grpc...
set(GRPC_PATCH_CMD
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
# cmake module, making it use a name understood by zig for arm64. See
# https://github.com/abseil/abseil-cpp/blob/master/absl/copts/GENERATED_AbseilCopts.cmake#L226.
if(CMAKE_C_COMPILER MATCHES "zig")
message(STATUS "Enabling zig workaround for abseil-cpp")
set(GRPC_PATCH_CMD
${GRPC_PATCH_CMD}
&&
sh
-c
"sed -i 's/armv8-a/cortex_a57/g' ${GRPC_SRC}/third_party/abseil-cpp/absl/copts/GENERATED_AbseilCopts.cmake"
)
endif()
ExternalProject_Add(
grpc
PREFIX "${PROJECT_BINARY_DIR}/grpc-prefix"
DEPENDS openssl protobuf c-ares zlib re2
GIT_REPOSITORY https://github.com/grpc/grpc.git
GIT_TAG v1.44.0
GIT_SUBMODULES "third_party/abseil-cpp"
CMAKE_CACHE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=${GRPC_INSTALL_DIR}
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=${ENABLE_PIC}
-DgRPC_INSTALL:BOOL=OFF
# disable unused stuff
-DgRPC_BUILD_TESTS:BOOL=OFF
-DgRPC_BUILD_CSHARP_EXT:BOOL=OFF
-DgRPC_BUILD_GRPC_CSHARP_PLUGIN:BOOL=OFF
-DgRPC_BUILD_GRPC_NODE_PLUGIN:BOOL=OFF
-DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN:BOOL=OFF
-DgRPC_BUILD_GRPC_PHP_PLUGIN:BOOL=OFF
-DgRPC_BUILD_GRPC_PYTHON_PLUGIN:BOOL=OFF
-DgRPC_BUILD_GRPC_RUBY_PLUGIN:BOOL=OFF
# deps provided by us
# https://github.com/grpc/grpc/blob/v1.32.0/cmake/modules/Findc-ares.cmake
-DgRPC_CARES_PROVIDER:STRING=package
-Dc-ares_DIR:PATH=${CARES_SRC}
-Dc-ares_INCLUDE_DIR:PATH=${CARES_INCLUDE}
-Dc-ares_LIBRARY:PATH=${CARES_LIB}
# https://cmake.org/cmake/help/v3.6/module/FindProtobuf.html
-DgRPC_PROTOBUF_PROVIDER:STRING=package
-DCMAKE_CXX_FLAGS:STRING=-I${PROTOBUF_INCLUDE}
-DProtobuf_INCLUDE_DIR:PATH=${PROTOBUF_INCLUDE}
-DProtobuf_LIBRARY:PATH=${PROTOBUF_LIB}
-DProtobuf_PROTOC_LIBRARY:PATH=${PROTOC_LIB}
-DProtobuf_PROTOC_EXECUTABLE:PATH=${PROTOC}
# https://cmake.org/cmake/help/v3.6/module/FindOpenSSL.html
-DgRPC_SSL_PROVIDER:STRING=package
-DOPENSSL_ROOT_DIR:PATH=${OPENSSL_INSTALL_DIR}
-DOPENSSL_USE_STATIC_LIBS:BOOL=${GRPC_OPENSSL_STATIC_LIBS_OPTION}
# https://cmake.org/cmake/help/v3.6/module/FindZLIB.html
-DgRPC_ZLIB_PROVIDER:STRING=package
-DZLIB_ROOT:STRING=${ZLIB_SRC}
# RE2
-DgRPC_RE2_PROVIDER:STRING=package
-Dre2_DIR:PATH=${RE2_DIR}
BUILD_IN_SOURCE 1
BUILD_BYPRODUCTS ${GRPC_LIB} ${GRPCPP_LIB} ${GPR_LIB} ${GRPC_LIBRARIES}
# Keep installation files into the local ${GRPC_INSTALL_DIR} since here is the case when
# we are embedding gRPC
UPDATE_COMMAND ""
PATCH_COMMAND ${GRPC_PATCH_CMD}
INSTALL_COMMAND DESTDIR= ${CMAKE_MAKE_PROGRAM} install
)
install(
FILES ${GRPC_MAIN_LIBS}
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
install(
FILES ${GRPC_LIBRARIES}
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
install(
DIRECTORY "${GRPC_SRC}/target/include/"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
endif()
endif()
if(NOT TARGET grpc)
add_custom_target(grpc)
endif()
include_directories("${GRPC_INCLUDE}")

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco Authors.
# Copyright (C) 2024 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
@@ -25,9 +25,9 @@ elseif(NOT USE_BUNDLED_JEMALLOC)
else()
set(JEMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
find_library(MALLOC_LIB NAMES libjemalloc${JEMALLOC_LIB_SUFFIX})
if(MALLOC_LIB)
message(STATUS "Found system jemalloc: include: ${JEMALLOC_INCLUDE}, lib: ${MALLOC_LIB}")
find_library(JEMALLOC_LIB NAMES libjemalloc${JEMALLOC_LIB_SUFFIX})
if(JEMALLOC_LIB)
message(STATUS "Found JEMALLOC: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}")
else()
message(FATAL_ERROR "Couldn't find system jemalloc")
endif()
@@ -38,28 +38,23 @@ else()
set(JEMALLOC_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
set(JEMALLOC_SRC "${PROJECT_BINARY_DIR}/jemalloc-prefix/src")
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()
set(JEMALLOC_LIB "${JEMALLOC_SRC}/jemalloc/lib/libjemalloc${JEMALLOC_LIB_SUFFIX}")
set(JEMALLOC_INCLUDE "${JEMALLOC_SRC}/jemalloc/include/jemalloc")
ExternalProject_Add(
malloc
jemalloc
PREFIX "${PROJECT_BINARY_DIR}/jemalloc-prefix"
URL "https://github.com/jemalloc/jemalloc/archive/refs/tags/5.3.0.tar.gz"
URL_HASH "SHA256=ef6f74fd45e95ee4ef7f9e19ebe5b075ca6b7fbe0140612b2a161abafb7ee179"
CONFIGURE_COMMAND ./autogen.sh --enable-prof --disable-libdl
${JEMALLOC_ARCH_SPECIFIC_CONFIGURE_ARGS}
BUILD_IN_SOURCE 1
BUILD_COMMAND make build_lib_static
INSTALL_COMMAND ""
UPDATE_COMMAND ""
BUILD_BYPRODUCTS ${MALLOC_LIB}
BUILD_BYPRODUCTS ${JEMALLOC_LIB}
)
message(STATUS "Using bundled jemalloc: include: ${JEMALLOC_INCLUDE}, lib: ${JEMALLOC_LIB}")
install(
FILES "${MALLOC_LIB}"
FILES "${JEMALLOC_LIB}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
@@ -67,8 +62,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 malloc)
add_custom_target(malloc)
if(NOT TARGET jemalloc)
add_custom_target(jemalloc)
endif()
include_directories(${JEMALLOC_INCLUDE})

View File

@@ -1,92 +0,0 @@
# 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

@@ -1,81 +0,0 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
# or implied. See the License for the specific language governing permissions and limitations under
# the License.
#
option(USE_BUNDLED_OPENSSL "Enable building of the bundled OpenSSL" ${USE_BUNDLED_DEPS})
if(OPENSSL_INCLUDE_DIR)
# we already have openssl
elseif(NOT USE_BUNDLED_OPENSSL)
find_package(OpenSSL REQUIRED)
message(STATUS "Found OpenSSL: include: ${OPENSSL_INCLUDE_DIR}, lib: ${OPENSSL_LIBRARIES}")
else()
if(BUILD_SHARED_LIBS)
set(OPENSSL_LIB_SUFFIX ${CMAKE_SHARED_LIBRARY_SUFFIX})
set(OPENSSL_SHARED_OPTION shared)
else()
set(OPENSSL_LIB_SUFFIX ${CMAKE_STATIC_LIBRARY_SUFFIX})
set(OPENSSL_SHARED_OPTION no-shared)
endif()
set(OPENSSL_BUNDLE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl")
set(OPENSSL_INSTALL_DIR "${OPENSSL_BUNDLE_DIR}/target")
set(OPENSSL_INCLUDE_DIR "${PROJECT_BINARY_DIR}/openssl-prefix/src/openssl/include/")
set(OPENSSL_LIBRARY_SSL "${OPENSSL_INSTALL_DIR}/lib/libssl${OPENSSL_LIB_SUFFIX}")
set(OPENSSL_LIBRARY_CRYPTO "${OPENSSL_INSTALL_DIR}/lib/libcrypto${OPENSSL_LIB_SUFFIX}")
set(OPENSSL_LIBRARIES ${OPENSSL_LIBRARY_SSL} ${OPENSSL_LIBRARY_CRYPTO})
if(NOT TARGET openssl)
if(NOT ENABLE_PIC)
set(OPENSSL_PIC_OPTION)
else()
set(OPENSSL_PIC_OPTION "-fPIC")
endif()
message(STATUS "Using bundled openssl in '${OPENSSL_BUNDLE_DIR}'")
ExternalProject_Add(
openssl
PREFIX "${PROJECT_BINARY_DIR}/openssl-prefix"
URL "https://github.com/openssl/openssl/releases/download/openssl-3.1.4/openssl-3.1.4.tar.gz"
URL_HASH "SHA256=840af5366ab9b522bde525826be3ef0fb0af81c6a9ebd84caa600fea1731eee3"
CONFIGURE_COMMAND ./config ${OPENSSL_SHARED_OPTION} ${OPENSSL_PIC_OPTION}
--prefix=${OPENSSL_INSTALL_DIR} --libdir=lib
BUILD_COMMAND make
BUILD_IN_SOURCE 1
BUILD_BYPRODUCTS ${OPENSSL_LIBRARY_SSL} ${OPENSSL_LIBRARY_CRYPTO}
INSTALL_COMMAND make install_sw
)
install(
FILES "${OPENSSL_LIBRARY_SSL}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
install(
FILES "${OPENSSL_LIBRARY_CRYPTO}"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
install(
DIRECTORY "${OPENSSL_INCLUDE_DIR}"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBS_PACKAGE_NAME}"
COMPONENT "libs-deps"
)
endif()
endif()
if(NOT TARGET openssl)
add_custom_target(openssl)
endif()
include_directories("${OPENSSL_INCLUDE_DIR}")

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2025 The Falco Authors.
# Copyright (C) 2024 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
# in compliance with the License. You may obtain a copy of the License at
@@ -18,9 +18,9 @@ include(ExternalProject)
if(NOT DEFINED FALCOSECURITY_RULES_FALCO_PATH)
# falco_rules.yaml
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-5.0.0")
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-3.2.0")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM
"SHA256=ca87d972e102a9f960fed41f90d2736a73079fcc7e787187028f455ad58b1637"
"SHA256=b3990bf0209cfbf6a903b361e458a1f5851a9a5aeee808ad26a5ddbe1377157d"
)
set(FALCOSECURITY_RULES_FALCO_PATH
"${PROJECT_BINARY_DIR}/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml"

View File

@@ -1,2 +0,0 @@
# Enable container plugin for linux non musl installation.
load_plugins: [container]

View File

@@ -1,2 +0,0 @@
# Enable iso 8601 time format on docker
time_format_iso_8601: true

View File

@@ -1,37 +1,22 @@
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 maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro 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 \
@@ -111,8 +96,10 @@ RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Change the falco config within the container to enable ISO 8601 output.
ADD ./config/falco.iso8601_timeformat.yaml /etc/falco/config.d/
# Change the falco config within the container to enable ISO 8601
# output.
RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /etc/falco/falco.yaml > /etc/falco/falco.yaml.new \
&& mv /etc/falco/falco.yaml.new /etc/falco/falco.yaml
# Some base images have an empty /lib/modules by default
# If it's not empty, docker build will fail instead of
@@ -136,6 +123,6 @@ RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dep
&& dpkg -i *binutils*.deb \
&& rm -f *binutils*.deb
COPY ./docker/driver-loader-buster/docker-entrypoint.sh /
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -1,22 +1,13 @@
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 maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro 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
@@ -50,6 +41,6 @@ RUN apt-get update \
RUN rm -df /lib/modules \
&& ln -s $HOST_ROOT/lib/modules /lib/modules
COPY ./docker/driver-loader/docker-entrypoint.sh /
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -1,26 +1,18 @@
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 maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco/docker/falco-debian"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /proc:/host/proc:ro -v /etc:/host/etc:ro falcosecurity/falco:latest-debian"
ARG FALCO_VERSION
ARG VERSION_BUCKET=deb
ENV FALCO_VERSION=${FALCO_VERSION}
ENV VERSION_BUCKET=${VERSION_BUCKET}
ENV HOST_ROOT=/host
ENV HOME=/root
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/*
@@ -34,7 +26,6 @@ RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Change the falco config within the container to enable ISO 8601 output.
ADD ./config/falco.iso8601_timeformat.yaml /etc/falco/config.d/
RUN sed -i -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' /etc/falco/falco.yaml
CMD ["/usr/bin/falco"]

View File

@@ -1,26 +1,18 @@
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 maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /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++
@@ -34,11 +26,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 /usr/bin/falcoctl /etc/falcoctl/
rm -rf /falco
RUN sed -i -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' /etc/falco/falco.yaml
# 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

@@ -175,7 +175,7 @@ _The units represent the number of releases._
### Examples
**Example 1** Let's consider a feature _foo_ in the Output/Alerts Area introduced in Falco 1.0.0 and labeled as *Incubating*. The feature is promoted to *Stable* in Falco 1.1.0 (because the feature did not get any user-facing change).
Subsequently, maintainers decide that backward-incompatible changes must be introduced in _foo_ to improve its functionality. The part of the feature to be changed is labeled as *Deprecated* in Falco 1.2.0, and the deprecation period starts. The non-backward compatible change is then introduced in Falco 1.4.0.
Subsequently, maintainers decide that backward-compatible changes must be introduced in _foo_ to improve its functionality. The part of the feature to be changed is labeled as *Deprecated* in Falco 1.2.0, and the deprecation period starts. The non-backward compatible change is then introduced in Falco 1.4.0.
**Example 2** The `--bar` flag in the CLI/Config Area has been introduced since Falco 1.1.0 and is labeled as *Stable*. Before releasing Falco 1.5.0, maintainers realize `--bar` is redundant and should be removed. The flag is labeled as *Deprecated* in Falco 1.5.0, and the deprecation period starts. The flag is removed in Falco 1.6.0.

View File

@@ -1,127 +0,0 @@
# 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: 168h0m0s
every: 6h0m0s
falcoVersions: http://localhost:8765/versions
refs:
- falco-rules:5
- falco-rules:3
indexes:
- name: falcosecurity
url: https://falcosecurity.github.io/falcoctl/index.yaml

26
scripts/ignored-calls.sh Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
parentdir="$(dirname "$scriptdir")"
libsdir="${parentdir}/build/falcosecurity-libs-repo/falcosecurity-libs-prefix/src/falcosecurity-libs"
cat "${libsdir}/userspace/libscap/syscall_info_table.c" | grep EF_DROP_SIMPLE_CONS | sed -e 's/.*\"\(.*\)\".*/\1/' | sort > /tmp/ignored_syscall_info_table.txt
cat "${libsdir}/driver/event_table.c" | grep EF_DROP_SIMPLE_CONS | sed -e 's/[^\"]*\"\([^\"]*\)\".*/\1/' | sort | uniq > /tmp/ignored_driver_event_table.txt
cat /tmp/ignored_driver_event_table.txt /tmp/ignored_syscall_info_table.txt | sort | uniq | tr '\n' ', '

View File

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

@@ -28,7 +28,7 @@ TEST_F(test_falco_engine, extra_format_all) {
priority: INFO
)END";
m_engine->add_extra_output_format("evt.type=%evt.type", "", {}, "");
m_engine->add_extra_output_format("evt.type=%evt.type", "", {}, "", false);
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
EXPECT_EQ(get_compiled_rule_output("legit_rule"),
@@ -50,7 +50,7 @@ TEST_F(test_falco_engine, extra_format_by_rule) {
priority: INFO
)END";
m_engine->add_extra_output_format("evt.type=%evt.type", "", {}, "legit_rule");
m_engine->add_extra_output_format("evt.type=%evt.type", "", {}, "legit_rule", false);
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
EXPECT_EQ(get_compiled_rule_output("legit_rule"), "out 1 evt.type=%evt.type");
@@ -81,9 +81,9 @@ TEST_F(test_falco_engine, extra_format_by_tag_rule) {
tags: [tag1, tag2]
)END";
m_engine->add_extra_output_format("extra 1", "", {"tag1"}, "");
m_engine->add_extra_output_format("extra 2", "", {}, "another_rule");
m_engine->add_extra_output_format("extra 3", "", {"tag1", "tag2"}, "");
m_engine->add_extra_output_format("extra 1", "", {"tag1"}, "", false);
m_engine->add_extra_output_format("extra 2", "", {}, "another_rule", false);
m_engine->add_extra_output_format("extra 3", "", {"tag1", "tag2"}, "", false);
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
@@ -92,7 +92,32 @@ TEST_F(test_falco_engine, extra_format_by_tag_rule) {
EXPECT_EQ(get_compiled_rule_output("a_third_rule"), "out 3 extra 1 extra 3");
}
TEST_F(test_falco_engine, extra_format_empty_container_info) {
TEST_F(test_falco_engine, extra_format_replace_container_info) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
condition: evt.type=open
output: out 1 (%container.info)
priority: INFO
tags: [tag1]
- rule: another_rule
desc: legit rule description
condition: evt.type=open
output: out 2
priority: INFO
tags: [tag1]
)END";
m_engine->add_extra_output_format("extra 1", "", {}, "", true);
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
EXPECT_EQ(get_compiled_rule_output("legit_rule"), "out 1 (extra 1)");
EXPECT_EQ(get_compiled_rule_output("another_rule"), "out 2 extra 1");
}
TEST_F(test_falco_engine, extra_format_do_not_replace_container_info) {
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description

View File

@@ -15,16 +15,14 @@ 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();
rule_loader::context ctx("test");
rule_loader::result res("test");
filter_warning_resolver().run(ctx, res, *ast.get());
return res.has_warnings();
filter_warning_resolver().run(ast.get(), w);
return !w.empty();
}
TEST(WarningResolver, warnings_in_filtering_conditions) {
@@ -40,8 +38,4 @@ 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,36 +1327,3 @@ 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

@@ -116,6 +116,7 @@ TEST_F(test_falco_engine, preconditions_postconditions) {
s1.engine = nullptr;
s1.config = std::make_shared<falco_configuration>();
s1.options.all_events = false;
auto result = falco::app::actions::configure_interesting_sets(s1);
ASSERT_FALSE(result.success);
ASSERT_NE(result.errstr, "");
@@ -198,8 +199,9 @@ TEST_F(test_falco_engine, selection_not_allevents) {
falco::app::state s2;
// run app action with fake engine and without the `-A` option
s2.engine = m_engine;
s2.config->m_base_syscalls_all = false;
s2.options.all_events = false;
ASSERT_EQ(s2.options.all_events, false);
auto result = falco::app::actions::configure_interesting_sets(s2);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
@@ -254,8 +256,7 @@ TEST_F(test_falco_engine, selection_allevents) {
falco::app::state s3;
// run app action with fake engine and with the `-A` option
s3.engine = m_engine;
s3.config->m_base_syscalls_all = true;
s3.options.all_events = true;
auto result = falco::app::actions::configure_interesting_sets(s3);
ASSERT_TRUE(result.success);
ASSERT_EQ(result.errstr, "");
@@ -298,8 +299,8 @@ TEST_F(test_falco_engine, selection_allevents) {
TEST_F(test_falco_engine, selection_generic_evts) {
falco::app::state s4;
// run app action with fake engine and without the `m_base_syscalls_all` option
// run app action with fake engine and without the `-A` option
s4.options.all_events = false;
auto filters = s_sample_filters;
filters.insert(s_sample_generic_filters.begin(), s_sample_generic_filters.end());
load_rules(ruleset_from_filters(filters), "dummy_ruleset.yaml");
@@ -346,7 +347,8 @@ TEST_F(test_falco_engine, selection_custom_base_set) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s5;
s5.config->m_base_syscalls_all = true;
// run app action with fake engine and without the `-A` option
s5.options.all_events = true;
s5.engine = m_engine;
auto default_base_set = libsinsp::events::sinsp_state_sc_set();
@@ -423,8 +425,8 @@ TEST_F(test_falco_engine, selection_custom_base_set) {
expected_sc_names.erase("accept4");
ASSERT_NAMES_EQ(selected_sc_names, expected_sc_names);
// non-empty custom base set (positive, disable all syscalls)
s5.config->m_base_syscalls_all = false;
// non-empty custom base set (positive, without -A)
s5.options.all_events = false;
s5.config->m_base_syscalls_custom_set = {"read"};
result = falco::app::actions::configure_interesting_sets(s5);
ASSERT_TRUE(result.success);
@@ -451,8 +453,8 @@ TEST_F(test_falco_engine, selection_custom_base_set_repair) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s6;
// run app action with fake engine and without the `all syscalls` option
s6.config->m_base_syscalls_all = false;
// run app action with fake engine and without the `-A` option
s6.options.all_events = false;
s6.engine = m_engine;
// note: here we use file syscalls (e.g. open, openat) and have a custom
@@ -492,8 +494,8 @@ TEST_F(test_falco_engine, selection_empty_custom_base_set_repair) {
load_rules(ruleset_from_filters(s_sample_filters), "dummy_ruleset.yaml");
falco::app::state s7;
// run app action with fake engine and with the `all syscalls` option
s7.config->m_base_syscalls_all = true;
// run app action with fake engine and with the `-A` option
s7.options.all_events = true;
s7.engine = m_engine;
// simulate empty custom set but repair option set.

View File

@@ -24,7 +24,6 @@ limitations under the License.
#include <future>
#include <memory>
#include <vector>
#include <thread>
TEST(AtomicSignalHandler, lock_free_implementation) {
ASSERT_TRUE(falco::atomic_signal_handler().is_lock_free());

View File

@@ -1,134 +0,0 @@
// 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,6 +92,7 @@ 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));
@@ -244,316 +245,6 @@ TEST(Configuration, configuration_config_files_override) {
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_sequence_strategy_default) {
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - conf_2.yaml\n" // default merge-strategy: append
" - conf_3.yaml\n"
"foo: [ bar ]\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo: [ bar2 ]\n" // append to foo sequence
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"base_value:\n" // override base_value
" id: 3\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
outfile.close();
outfile.open("conf_2.yaml");
outfile << conf_yaml_2;
outfile.close();
outfile.open("conf_3.yaml");
outfile << conf_yaml_3;
outfile.close();
std::vector<std::string> cmdline_config_options;
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));
// main + conf_2 + conf_3
ASSERT_EQ(res.size(), 3);
ASSERT_TRUE(falco_config.m_config.is_defined("foo"));
std::vector<std::string> foos;
auto expected_foos = std::vector<std::string>{"bar", "bar2"};
ASSERT_NO_THROW(falco_config.m_config.get_sequence<std::vector<std::string>>(foos, "foo"));
ASSERT_EQ(foos.size(), 2); // 2 elements in `foo` sequence because we appended to it
for(size_t i = 0; i < foos.size(); ++i) {
EXPECT_EQ(foos[i], expected_foos[i])
<< "Vectors foo's and expected_foo's differ at index " << i;
}
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined(
"base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_sequence_strategy_append) {
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - path: conf_2.yaml\n"
" strategy: append\n"
" - conf_3.yaml\n"
"foo: [ bar ]\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo: [ bar2 ]\n" // append to foo sequence
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"base_value:\n" // override base_value
" id: 3\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
outfile.close();
outfile.open("conf_2.yaml");
outfile << conf_yaml_2;
outfile.close();
outfile.open("conf_3.yaml");
outfile << conf_yaml_3;
outfile.close();
std::vector<std::string> cmdline_config_options;
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));
// main + conf_2 + conf_3
ASSERT_EQ(res.size(), 3);
ASSERT_TRUE(falco_config.m_config.is_defined("foo"));
std::vector<std::string> foos;
auto expected_foos = std::vector<std::string>{"bar", "bar2"};
ASSERT_NO_THROW(falco_config.m_config.get_sequence<std::vector<std::string>>(foos, "foo"));
ASSERT_EQ(foos.size(), 2); // 2 elements in `foo` sequence because we appended to it
for(size_t i = 0; i < foos.size(); ++i) {
EXPECT_EQ(foos[i], expected_foos[i])
<< "Vectors foo's and expected_foo's differ at index " << i;
}
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined(
"base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_sequence_strategy_override) {
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - path: conf_2.yaml\n"
" strategy: override\n"
" - conf_3.yaml\n"
"foo: [ bar ]\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo: [ bar2 ]\n" // override foo sequence
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"base_value:\n" // override base_value
" id: 3\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
outfile.close();
outfile.open("conf_2.yaml");
outfile << conf_yaml_2;
outfile.close();
outfile.open("conf_3.yaml");
outfile << conf_yaml_3;
outfile.close();
std::vector<std::string> cmdline_config_options;
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));
// main + conf_2 + conf_3
ASSERT_EQ(res.size(), 3);
ASSERT_TRUE(falco_config.m_config.is_defined("foo"));
std::vector<std::string> foos;
auto expected_foos = std::vector<std::string>{"bar2"};
ASSERT_NO_THROW(falco_config.m_config.get_sequence<std::vector<std::string>>(foos, "foo"));
ASSERT_EQ(foos.size(), 1); // one element in `foo` sequence because we overrode it
for(size_t i = 0; i < foos.size(); ++i) {
EXPECT_EQ(foos[i], expected_foos[i])
<< "Vectors foo's and expected_foo's differ at index " << i;
}
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined(
"base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_sequence_strategy_addonly) {
/* Test that included config files are able to override configs from main file */
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - path: conf_2.yaml\n"
" strategy: add-only\n"
" - conf_3.yaml\n"
"foo: [ bar ]\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo: [ bar2 ]\n" // ignored: add-only strategy
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"base_value:\n" // override base_value
" id: 3\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
outfile.close();
outfile.open("conf_2.yaml");
outfile << conf_yaml_2;
outfile.close();
outfile.open("conf_3.yaml");
outfile << conf_yaml_3;
outfile.close();
std::vector<std::string> cmdline_config_options;
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));
// main + conf_2 + conf_3
ASSERT_EQ(res.size(), 3);
ASSERT_TRUE(falco_config.m_config.is_defined("foo"));
std::vector<std::string> foos;
auto expected_foos =
std::vector<std::string>{"bar"}; // bar2 is ignored because of merge-strategy: add-only
ASSERT_NO_THROW(falco_config.m_config.get_sequence<std::vector<std::string>>(foos, "foo"));
ASSERT_EQ(foos.size(), 1); // one element in `foo` sequence because we overrode it
for(size_t i = 0; i < foos.size(); ++i) {
EXPECT_EQ(foos[i], expected_foos[i])
<< "Vectors foo's and expected_foo's differ at index " << i;
}
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined(
"base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_sequence_wrong_strategy) {
const std::string main_conf_yaml = yaml_helper::configs_key +
":\n"
" - path: conf_2.yaml\n"
" strategy: wrong\n"
" - conf_3.yaml\n"
"foo: [ bar ]\n"
"base_value:\n"
" id: 1\n"
" name: foo\n";
const std::string conf_yaml_2 =
"foo: [ bar2 ]\n" // append to foo sequence
"base_value_2:\n"
" id: 2\n";
const std::string conf_yaml_3 =
"base_value:\n" // override base_value
" id: 3\n";
std::ofstream outfile("main.yaml");
outfile << main_conf_yaml;
outfile.close();
outfile.open("conf_2.yaml");
outfile << conf_yaml_2;
outfile.close();
outfile.open("conf_3.yaml");
outfile << conf_yaml_3;
outfile.close();
std::vector<std::string> cmdline_config_options;
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));
// main
ASSERT_EQ(res.size(), 3);
auto validation = res["main.yaml"];
// Since we are using a wrong strategy, the validation should fail
// but the enforced strategy should be "append"
ASSERT_NE(validation, yaml_helper::validation_ok);
ASSERT_TRUE(falco_config.m_config.is_defined("foo"));
std::vector<std::string> foos;
auto expected_foos = std::vector<std::string>{"bar", "bar2"};
ASSERT_NO_THROW(falco_config.m_config.get_sequence<std::vector<std::string>>(foos, "foo"));
ASSERT_EQ(foos.size(), 2); // 2 elements in `foo` sequence because we appended to it
for(size_t i = 0; i < foos.size(); ++i) {
EXPECT_EQ(foos[i], expected_foos[i])
<< "Vectors foo's and expected_foo's differ at index " << i;
}
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value.id", 0), 3); // overridden!
ASSERT_FALSE(falco_config.m_config.is_defined(
"base_value.name")); // no more present since entire `base_value` block was overridden
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);
ASSERT_FALSE(falco_config.m_config.is_defined("base_value_3.id")); // not defined
std::filesystem::remove("main.yaml");
std::filesystem::remove("conf_2.yaml");
std::filesystem::remove("conf_3.yaml");
}
TEST(Configuration, configuration_config_files_unexistent) {
/* Test that including an unexistent file just skips it */
const std::string main_conf_yaml = yaml_helper::configs_key +
@@ -775,9 +466,6 @@ TEST(Configuration, configuration_config_files_cmdline) {
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back((yaml_helper::configs_key + "=conf_2.yaml"));
// Override foo2 value from cli
cmdline_config_options.push_back(("foo2=bar22"));
falco_configuration falco_config;
config_loaded_res res;
ASSERT_NO_THROW(res = falco_config.init_from_file("main.yaml", cmdline_config_options));
@@ -792,7 +480,7 @@ TEST(Configuration, configuration_config_files_cmdline) {
ASSERT_TRUE(falco_config.m_config.is_defined("base_value.name"));
ASSERT_EQ(falco_config.m_config.get_scalar<std::string>("base_value.name", ""), "foo");
ASSERT_TRUE(falco_config.m_config.is_defined("foo2"));
ASSERT_EQ(falco_config.m_config.get_scalar<std::string>("foo2", ""), "bar22");
ASSERT_EQ(falco_config.m_config.get_scalar<std::string>("foo2", ""), "bar2");
ASSERT_TRUE(falco_config.m_config.is_defined("base_value_2.id"));
ASSERT_EQ(falco_config.m_config.get_scalar<int>("base_value_2.id", 0), 2);

View File

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

View File

@@ -36,14 +36,6 @@ if(EMSCRIPTEN)
target_compile_options(falco_engine PRIVATE "-sDISABLE_EXCEPTION_CATCHING=0")
endif()
set(ENGINE_LIBRARIES sinsp nlohmann_json::nlohmann_json yaml-cpp)
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
# Used by falco_utils.cpp
add_dependencies(falco_engine openssl)
list(APPEND ENGINE_LIBRARIES "${OPENSSL_LIBRARIES}")
endif()
target_include_directories(falco_engine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${TBB_INCLUDE_DIR})
target_link_libraries(falco_engine PUBLIC ${ENGINE_LIBRARIES})
target_link_libraries(falco_engine PUBLIC sinsp nlohmann_json::nlohmann_json yaml-cpp)

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(const auto &wrap : wrappers) {
for(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(const auto &wrap : wrappers) {
for(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() override;
virtual ~evttype_index_ruleset();
// From filter_ruleset
void add(const falco_rule &rule,

View File

@@ -29,8 +29,6 @@ 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) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -413,8 +413,6 @@ 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;
@@ -570,8 +568,6 @@ 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);
@@ -895,6 +891,17 @@ std::shared_ptr<filter_ruleset> falco_engine::ruleset_for_source(std::size_t sou
return source->ruleset;
}
void falco_engine::read_file(const std::string &filename, std::string &contents) {
std::ifstream is;
is.open(filename);
if(!is.is_open()) {
throw falco_exception("Could not open " + filename + " for reading");
}
contents.assign(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>());
}
static bool check_plugin_requirement_alternatives(
const std::vector<falco_engine::plugin_version_requirement> &plugins,
const rule_loader::plugin_version_info::requirement_alternatives &alternatives,
@@ -979,8 +986,9 @@ void falco_engine::set_sampling_multiplier(double sampling_multiplier) {
void falco_engine::add_extra_output_format(const std::string &format,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule) {
m_extra_output_format.push_back({format, source, tags, rule});
const std::string &rule,
bool replace_container_info) {
m_extra_output_format.push_back({format, source, tags, rule, replace_container_info});
}
void falco_engine::add_extra_output_formatted_field(const std::string &key,

View File

@@ -199,7 +199,8 @@ public:
void add_extra_output_format(const std::string &format,
const std::string &source,
const std::set<std::string> &tags,
const std::string &rule);
const std::string &rule,
bool replace_container_info);
// You can optionally add fields that will only show up in the object
// output (e.g. json, gRPC) alongside other output_fields
@@ -228,8 +229,6 @@ 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;
};
//
@@ -380,6 +379,9 @@ private:
filter_ruleset::engine_state_funcs m_engine_state;
// Throws falco_exception if the file can not be read
void read_file(const std::string &filename, std::string &contents);
indexed_vector<falco_source> m_sources;
inline const falco_source *find_source(std::size_t index) {

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -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 58
#define FALCO_ENGINE_VERSION_MINOR 46
#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 "952fa3356bfd266419810be51ae659eab48093a66da26fff3897022a9de2c08c"
#define FALCO_ENGINE_CHECKSUM "24861acb14c5b9f7d293dd37d1623949135e1a865f2d813cbd660212b71ada33"

View File

@@ -75,14 +75,8 @@ 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[static_cast<int>(wc)];
return warning_codes[wc];
}
static const std::string warning_strings[] = {"Unknown event source",
@@ -100,14 +94,8 @@ 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[static_cast<int>(wc)];
return warning_strings[wc];
}
static const std::string warning_descs[] = {
@@ -133,60 +121,6 @@ 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[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));
return warning_descs[wc];
}

View File

@@ -46,9 +46,7 @@ public:
// impact.
static const std::string& error_desc(error_code ec);
virtual ~load_result() = default;
enum class warning_code {
enum warning_code {
LOAD_UNKNOWN_SOURCE = 0,
LOAD_UNSAFE_NA_CHECK,
LOAD_NO_EVTTYPE,
@@ -65,6 +63,8 @@ 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,27 +75,6 @@ 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) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -77,11 +77,7 @@ 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),
capture(false),
capture_duration(0) {}
falco_rule(): id(0), priority(falco_common::PRIORITY_DEBUG) {}
falco_rule(falco_rule&&) = default;
falco_rule& operator=(falco_rule&&) = default;
falco_rule(const falco_rule&) = default;
@@ -95,9 +91,7 @@ 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->capture == rhs.capture &&
this->capture_duration == rhs.capture_duration &&
this->condition.get() == rhs.condition.get() &&
this->priority == rhs.priority && this->condition.get() == rhs.condition.get() &&
this->filter.get() == rhs.filter.get());
}
@@ -110,8 +104,6 @@ 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,10 +120,11 @@ 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()) {
uint64_t cur_interval = 0;
std::string cur_interval_str = args[group_it->second - 1];
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,7 +15,6 @@ 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"
@@ -33,30 +32,14 @@ static inline bool is_equality_operator(const std::string& op) {
op == "pmatch";
}
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);
bool filter_warning_resolver::run(libsinsp::filter::ast::expr* filter,
std::set<load_result::warning_code>& warnings) const {
visitor v;
auto size = warnings.size();
v.m_is_equality_check = false;
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();
v.m_warnings = &warnings;
filter->accept(&v);
return warnings.size() > size;
}
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::binary_check_expr* e) {
@@ -71,24 +54,17 @@ 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(falco::load_result::warning_code::LOAD_UNSAFE_NA_CHECK);
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
}
}
void filter_warning_resolver::visitor::visit(libsinsp::filter::ast::list_expr* e) {
if(m_is_equality_check &&
std::find(e->values.begin(), e->values.end(), no_value) != e->values.end()) {
m_warnings->insert(falco::load_result::warning_code::LOAD_UNSAFE_NA_CHECK);
m_warnings->insert(load_result::LOAD_UNSAFE_NA_CHECK);
}
}

View File

@@ -23,7 +23,6 @@ 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
@@ -32,23 +31,25 @@ limitations under the License.
class filter_warning_resolver {
public:
/*!
\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
\brief Visits a filter AST and substitutes macro references
according with all the definitions added through set_macro(),
by replacing the reference with a clone of the macro AST.
\param filter The filter AST to be 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(const rule_loader::context& ctx,
rule_loader::result& res,
libsinsp::filter::ast::expr& filter) const;
bool run(libsinsp::filter::ast::expr* filter,
std::set<falco::load_result::warning_code>& warnings) const;
private:
struct visitor : public libsinsp::filter::ast::base_expr_visitor {
visitor(std::set<falco::load_result::warning_code>& warnings,
std::set<falco::load_result::deprecated_field>& deprecated_fields):
visitor():
m_is_equality_check(false),
m_last_node_is_unsafe_field(false),
m_warnings(&warnings),
m_deprecated_fields(&deprecated_fields) {}
m_warnings(nullptr) {}
visitor(visitor&&) = default;
visitor& operator=(visitor&&) = default;
visitor(const visitor&) = delete;
@@ -57,7 +58,6 @@ 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

@@ -24,13 +24,11 @@ falco_formats::falco_formats(std::shared_ptr<const falco_engine> engine,
bool json_include_output_property,
bool json_include_tags_property,
bool json_include_message_property,
bool json_include_output_fields_property,
bool time_format_iso_8601):
m_falco_engine(engine),
m_json_include_output_property(json_include_output_property),
m_json_include_tags_property(json_include_tags_property),
m_json_include_message_property(json_include_message_property),
m_json_include_output_fields_property(json_include_output_fields_property),
m_time_format_iso_8601(time_format_iso_8601) {}
falco_formats::~falco_formats() {}
@@ -57,6 +55,8 @@ 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);
@@ -79,9 +79,7 @@ std::string falco_formats::format_event(sinsp_evt *evt,
std::string json_fields_prefix;
// Resolve message fields
if(m_json_include_output_fields_property) {
message_formatter->tostring(evt, json_fields_message);
}
message_formatter->tostring(evt, json_fields_message);
// Resolve prefix (e.g. time) fields
prefix_formatter->tostring(evt, json_fields_prefix);
@@ -120,38 +118,36 @@ std::string falco_formats::format_event(sinsp_evt *evt,
event["message"] = message;
}
if(m_json_include_output_fields_property) {
event["output_fields"] = nlohmann::json::parse(json_fields_message);
event["output_fields"] = nlohmann::json::parse(json_fields_message);
auto prefix_fields = nlohmann::json::parse(json_fields_prefix);
if(prefix_fields.is_object()) {
for(auto const &el : prefix_fields.items()) {
event["output_fields"][el.key()] = el.value();
}
auto prefix_fields = nlohmann::json::parse(json_fields_prefix);
if(prefix_fields.is_object()) {
for(auto const &el : prefix_fields.items()) {
event["output_fields"][el.key()] = el.value();
}
}
for(auto const &ef : extra_fields) {
std::string fformat = ef.second.first;
if(fformat.size() == 0) {
continue;
}
for(auto const &ef : extra_fields) {
std::string fformat = ef.second.first;
if(fformat.size() == 0) {
continue;
}
if(!(fformat[0] == '*')) {
fformat = "*" + fformat;
}
if(!(fformat[0] == '*')) {
fformat = "*" + fformat;
}
if(ef.second.second) // raw field
{
std::string json_field_map;
auto field_formatter = m_falco_engine->create_formatter(source, fformat);
field_formatter->tostring_withformat(evt,
json_field_map,
sinsp_evt_formatter::OF_JSON);
auto json_obj = nlohmann::json::parse(json_field_map);
event["output_fields"][ef.first] = json_obj[ef.first];
} else {
event["output_fields"][ef.first] = format_string(evt, fformat, source);
}
if(ef.second.second) // raw field
{
std::string json_field_map;
auto field_formatter = m_falco_engine->create_formatter(source, fformat);
field_formatter->tostring_withformat(evt,
json_field_map,
sinsp_evt_formatter::OF_JSON);
auto json_obj = nlohmann::json::parse(json_field_map);
event["output_fields"][ef.first] = json_obj[ef.first];
} else {
event["output_fields"][ef.first] = format_string(evt, fformat, source);
}
}

View File

@@ -27,7 +27,6 @@ public:
bool json_include_output_property,
bool json_include_tags_property,
bool json_include_message_property,
bool json_include_output_fields_property,
bool time_format_iso_8601);
virtual ~falco_formats();
@@ -53,6 +52,5 @@ protected:
bool m_json_include_output_property;
bool m_json_include_tags_property;
bool m_json_include_message_property;
bool m_json_include_output_fields_property;
bool m_time_format_iso_8601;
};

View File

@@ -46,7 +46,7 @@ template<class filter_wrapper>
class indexable_ruleset : public filter_ruleset {
public:
indexable_ruleset() = default;
virtual ~indexable_ruleset() override = default;
virtual ~indexable_ruleset() = 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:
explicit ruleset_filters(uint16_t ruleset_id): m_ruleset_id(ruleset_id) {}
ruleset_filters(uint16_t ruleset_id): m_ruleset_id(ruleset_id) {}
virtual ~ruleset_filters() {};

View File

@@ -128,9 +128,15 @@ void falco_logger::log(falco_logger::level priority, const std::string&& msg) {
}
} else {
const struct tm* ltm = std::localtime(&result);
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());
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());
}
}
}

View File

@@ -74,12 +74,6 @@ const char rule_schema_string[] = LONG_STRING_CONST(
"priority": {
"$ref": "#/definitions/Priority"
},
"capture": {
"type": "boolean"
},
"capture_duration": {
"type": "integer"
},
"source": {
"type": "string"
},
@@ -125,7 +119,8 @@ const char rule_schema_string[] = LONG_STRING_CONST(
"values": {}
},
"required": [
"name"
"name",
"values"
],
"title": "Exception"
},

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -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() const {
std::string rule_loader::context::as_string() {
std::ostringstream os;
// All valid contexts should have at least one location.
@@ -142,7 +142,7 @@ std::string rule_loader::context::as_string() const {
return os.str();
}
nlohmann::json rule_loader::context::as_json() const {
nlohmann::json rule_loader::context::as_json() {
nlohmann::json ret;
ret["locations"] = nlohmann::json::array();
@@ -282,13 +282,9 @@ 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) {
warnings.emplace_back(std::make_unique<warning>(wc, msg, ctx));
}
warning warn = {wc, msg, ctx};
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));
warnings.push_back(warn);
}
void rule_loader::result::set_schema_validation_status(const std::vector<std::string>& status) {
@@ -333,7 +329,7 @@ const std::string& rule_loader::result::as_summary_string() {
os << " " << schema_validation_status.size() << " schema warnings: [";
bool first = true;
for(const auto& status : schema_validation_status) {
for(auto& status : schema_validation_status) {
if(!first) {
os << " ";
}
@@ -373,7 +369,8 @@ const std::string& rule_loader::result::as_summary_string() {
}
first = false;
os << warn->code_string() << " (" << warn->as_string() << ")";
os << load_result::warning_code_str(warn.wc) << " ("
<< load_result::warning_str(warn.wc) << ")";
}
os << "]";
}
@@ -412,7 +409,7 @@ const std::string& rule_loader::result::as_verbose_string(const rules_contents_t
os << schema_validation_status.size() << " Schema warnings:" << std::endl;
for(const auto& status : schema_validation_status) {
for(auto& status : schema_validation_status) {
os << "------" << std::endl;
os << status << std::endl;
}
@@ -441,13 +438,14 @@ 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 << warn->code_string() << " (" << warn->as_string() << "): " << warn->msg;
os << load_result::warning_code_str(warn.wc) << " ("
<< load_result::warning_str(warn.wc) << "): " << warn.msg;
os << std::endl;
}
}
@@ -494,7 +492,16 @@ const nlohmann::json& rule_loader::result::as_json(const rules_contents_t& conte
j["warnings"] = nlohmann::json::array();
for(auto& warn : warnings) {
j["warnings"].push_back(warn->as_json(contents));
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);
}
res_json = j;
@@ -525,8 +532,6 @@ 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() const;
nlohmann::json as_json() const;
std::string as_string();
nlohmann::json as_json();
private:
void init(const std::string& name,
@@ -183,52 +183,15 @@ struct warning {
msg(m),
ctx(c) {}
warning(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;
};
warning& operator=(warning&&) = default;
warning(const warning&) = default;
warning& operator=(const warning&) = default;
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):
@@ -265,7 +228,7 @@ public:
class result : public falco::load_result {
public:
explicit result(const std::string& name);
virtual ~result() override = default;
virtual ~result() = default;
result(result&&) = default;
result& operator=(result&&) = default;
result(const result&) = default;
@@ -285,9 +248,6 @@ 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;
@@ -300,7 +260,7 @@ protected:
std::vector<std::string> schema_validation_status;
std::vector<error> errors;
std::vector<std::unique_ptr<warning>> warnings;
std::vector<warning> warnings;
std::string res_summary_string;
std::string res_verbose_string;
@@ -312,6 +272,7 @@ struct extra_output_format_conf {
std::string m_source;
std::set<std::string> m_tags;
std::string m_rule;
bool m_replace_container_info;
};
struct extra_output_field_conf {
@@ -500,8 +461,6 @@ 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;
@@ -522,8 +481,7 @@ 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() ||
capture.has_value() || capture_duration.has_value() || warn_evttypes.has_value() ||
skip_if_unknown_filter.has_value();
warn_evttypes.has_value() || skip_if_unknown_filter.has_value();
}
context ctx;
@@ -536,8 +494,6 @@ 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) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -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::warning_code::LOAD_UNKNOWN_SOURCE,
cfg.res->add_warning(falco::load_result::LOAD_UNKNOWN_SOURCE,
"Unknown source " + info.source + ", skipping",
info.ctx);
}
@@ -313,14 +313,6 @@ 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) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ limitations under the License.
#include <memory>
#include <set>
#include <vector>
#include <functional>
#include "rule_loader_compiler.h"
#include "filter_warning_resolver.h"
@@ -35,12 +36,9 @@ limitations under the License.
}
static std::string s_container_info_fmt = "%container.info";
// We were previously expanding %container.info to "container_id=%container.id
// container_name=%container.name". Since the container plugin is now in use, and it exposes
// container.id and container.name as suggested output fields, we don't need to expand
// container.info anymore. We kept container.info in the ruleset to avoid a major breaking change.
// TODO: drop `container.info` magic once we make a major breaking change in the ruleset.
static std::string s_default_extra_fmt = "";
static std::string s_default_extra_fmt =
"container_id=%container.id container_name=%container.name";
using namespace libsinsp::filter;
// todo(jasondellaluce): this breaks string escaping in lists and exceptions
@@ -72,24 +70,6 @@ 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,
@@ -177,13 +157,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;
size_t start, end;
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
size_t end = start + list.name.length();
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
@@ -288,7 +268,7 @@ static std::shared_ptr<ast::expr> parse_condition(std::string condition,
}
}
void rule_loader::compiler::compile_list_infos(const configuration& cfg,
void rule_loader::compiler::compile_list_infos(configuration& cfg,
const collector& col,
indexed_vector<falco_list>& out) const {
std::list<std::string> used_names;
@@ -317,7 +297,7 @@ void rule_loader::compiler::compile_list_infos(const configuration& cfg,
}
// note: there is a visibility ordering between macros
void rule_loader::compiler::compile_macros_infos(const configuration& cfg,
void rule_loader::compiler::compile_macros_infos(configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& out) const {
@@ -349,7 +329,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(const configuration& cfg,
bool rule_loader::compiler::compile_condition(configuration& cfg,
filter_macro_resolver& macro_resolver,
indexed_vector<falco_list>& lists,
const indexed_vector<rule_loader::macro_info>& macros,
@@ -373,7 +353,11 @@ bool rule_loader::compiler::compile_condition(const configuration& cfg,
parent_ctx);
// check for warnings in the filtering condition
warn_resolver.run(cond_ctx, *cfg.res, *ast_out.get());
if(warn_resolver.run(ast_out.get(), warn_codes)) {
for(const auto& w : warn_codes) {
cfg.res->add_warning(w, "", parent_ctx);
}
}
// validate the rule's condition: we compile it into a sinsp filter
// on-the-fly and we throw an exception with details on failure
@@ -386,23 +370,23 @@ bool rule_loader::compiler::compile_condition(const 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::warning_code::LOAD_UNKNOWN_FILTER, err, ctx);
cfg.res->add_warning(falco::load_result::load_result::LOAD_UNKNOWN_FILTER, err, ctx);
return false;
}
throw rule_loader::rule_load_exception(
falco::load_result::error_code::LOAD_ERR_COMPILE_CONDITION,
falco::load_result::load_result::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::warning_code::LOAD_COMPILE_CONDITION, w.msg, ctx);
cfg.res->add_warning(falco::load_result::load_result::LOAD_COMPILE_CONDITION, w.msg, ctx);
}
return true;
}
void rule_loader::compiler::compile_rule_infos(const configuration& cfg,
void rule_loader::compiler::compile_rule_infos(configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& macros,
@@ -447,16 +431,18 @@ void rule_loader::compiler::compile_rule_infos(const configuration& cfg,
continue;
}
rule.output = rule.output + " " + extra.m_format;
if(extra.m_replace_container_info) {
if(rule.output.find(s_container_info_fmt) != std::string::npos) {
rule.output = replace(rule.output, s_container_info_fmt, extra.m_format);
} else {
rule.output = rule.output + " " + extra.m_format;
}
} else {
rule.output = rule.output + " " + extra.m_format;
}
}
if(rule.output.find(s_container_info_fmt) != std::string::npos) {
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 "
"the output message.",
r.ctx);
rule.output = replace(rule.output, s_container_info_fmt, s_default_extra_fmt);
}
@@ -486,28 +472,23 @@ void rule_loader::compiler::compile_rule_infos(const 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::warning_code::LOAD_UNKNOWN_FILTER,
cfg.res->add_warning(falco::load_result::load_result::LOAD_UNKNOWN_FILTER,
err,
r.output_ctx);
continue;
}
throw rule_load_exception(falco::load_result::error_code::LOAD_ERR_COMPILE_OUTPUT,
throw rule_load_exception(falco::load_result::load_result::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::error_code::LOAD_ERR_COMPILE_OUTPUT,
throw rule_load_exception(falco::load_result::load_result::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,
@@ -529,7 +510,7 @@ void rule_loader::compiler::compile_rule_infos(const 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::warning_code::LOAD_NO_EVTTYPE,
cfg.res->add_warning(falco::load_result::load_result::LOAD_NO_EVTTYPE,
"Rule matches too many evt.type values. This has a "
"significant performance penalty.",
r.ctx);
@@ -541,8 +522,6 @@ void rule_loader::compiler::compile_rule_infos(const 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;
@@ -569,14 +548,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::warning_code::LOAD_UNUSED_MACRO,
cfg.res->add_warning(falco::load_result::load_result::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::warning_code::LOAD_UNUSED_LIST,
cfg.res->add_warning(falco::load_result::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(const configuration& cfg,
bool compile_condition(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(const configuration& cfg,
void compile_list_infos(configuration& cfg,
const collector& col,
indexed_vector<falco_list>& out) const;
void compile_macros_infos(const configuration& cfg,
void compile_macros_infos(configuration& cfg,
const collector& col,
indexed_vector<falco_list>& lists,
indexed_vector<falco_macro>& out) const;
void compile_rule_infos(const configuration& cfg,
void compile_rule_infos(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) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -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(const auto& exception : exceptions) {
for(auto& exception : exceptions) {
if(v_ex.name == exception.name) {
cfg.res->add_warning(
falco::load_result::warning_code::LOAD_EXCEPTION_NAME_NOT_UNIQUE,
falco::load_result::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::warning_code::LOAD_APPEND_NO_VALUES,
cfg.res->add_warning(falco::load_result::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::warning_code::LOAD_INVALID_LIST_NAME,
cfg.res->add_warning(falco::load_result::LOAD_INVALID_LIST_NAME,
"List has an invalid name. List names should match a regular "
"expression: " RGX_BARESTR,
ctx);
@@ -538,9 +538,7 @@ 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::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_APPEND,
ctx);
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM, WARNING_APPEND, ctx);
}
std::set<std::string> override_append, override_replace;
@@ -569,7 +567,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::warning_code::LOAD_INVALID_MACRO_NAME,
cfg.res->add_warning(falco::load_result::LOAD_INVALID_MACRO_NAME,
"Macro has an invalid name. Macro names should match a regular "
"expression: " RGX_IDENTIFIER,
ctx);
@@ -589,9 +587,7 @@ 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::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_APPEND,
ctx);
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM, WARNING_APPEND, ctx);
}
std::set<std::string> override_append, override_replace;
@@ -625,9 +621,7 @@ 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::warning_code::LOAD_DEPRECATED_ITEM,
WARNING_APPEND,
ctx);
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM, WARNING_APPEND, ctx);
}
std::set<std::string> override_append, override_replace;
@@ -640,8 +634,6 @@ void rule_loader::reader::read_item(rule_loader::configuration& cfg,
"output",
"desc",
"priority",
"capture",
"capture_duration",
"tags",
"exceptions",
"enabled",
@@ -764,22 +756,6 @@ 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",
@@ -842,8 +818,6 @@ 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;
@@ -855,7 +829,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::warning_code::LOAD_DEPRECATED_ITEM,
cfg.res->add_warning(falco::load_result::LOAD_DEPRECATED_ITEM,
WARNING_ENABLED,
ctx);
collector.enable(cfg, v);
@@ -889,8 +863,6 @@ 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);
@@ -900,9 +872,7 @@ 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::warning_code::LOAD_UNKNOWN_ITEM,
"Unknown top level item",
ctx);
cfg.res->add_warning(falco::load_result::LOAD_UNKNOWN_ITEM, "Unknown top level item", ctx);
}
}

View File

@@ -85,33 +85,6 @@ public:
inline static const std::string validation_failed = "failed";
inline static const std::string validation_none = "none";
enum config_files_strategy {
STRATEGY_APPEND, // append to existing sequence keys, override scalar keys and add new ones
STRATEGY_OVERRIDE, // override existing keys (sequences too) and add new ones
STRATEGY_ADDONLY // only add new keys and ignore existing ones
};
static enum config_files_strategy strategy_from_string(const std::string& strategy) {
if(strategy == "override") {
return yaml_helper::STRATEGY_OVERRIDE;
}
if(strategy == "add-only") {
return yaml_helper::STRATEGY_ADDONLY;
}
return yaml_helper::STRATEGY_APPEND;
}
static std::string strategy_to_string(const enum config_files_strategy strategy) {
switch(strategy) {
case yaml_helper::STRATEGY_OVERRIDE:
return "override";
case yaml_helper::STRATEGY_ADDONLY:
return "add-only";
default:
return "append";
}
}
/**
* Load all the YAML document represented by the input string.
* Since this is used by rule loader, does not process env vars.
@@ -164,7 +137,6 @@ public:
}
void include_config_file(const std::string& include_file_path,
enum config_files_strategy strategy = STRATEGY_APPEND,
const nlohmann::json& schema = {},
std::vector<std::string>* schema_warnings = nullptr) {
auto loaded_nodes = load_from_file_int(include_file_path, schema, schema_warnings);
@@ -180,24 +152,10 @@ public:
"' directive in included config file " +
include_file_path + ".");
}
switch(strategy) {
case STRATEGY_APPEND:
if(n.second.IsSequence()) {
for(const auto& item : n.second) {
m_root[key].push_back(item);
}
break;
}
// fallthrough
case STRATEGY_OVERRIDE:
m_root[key] = n.second;
break;
case STRATEGY_ADDONLY:
if(!m_root[key].IsDefined()) {
m_root[key] = n.second;
}
break;
}
// We allow to override keys.
// We don't need to use `get_node()` here,
// since key is a top-level one.
m_root[key] = n.second;
}
}
@@ -383,11 +341,13 @@ 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) {
char c = key[i];
bool should_shift = c == '.' || c == '[' || i == key.size() - 1;
c = key[i];
should_shift = c == '.' || c == '[' || i == key.size() - 1;
if(c != '.' && c != '[') {
if(i > 0 && nodeKey.empty() && key[i - 1] != '.') {
@@ -456,6 +416,11 @@ 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) {
@@ -471,11 +436,7 @@ struct convert<nlohmann::json> {
res.emplace_back(sub);
}
break;
case YAML::NodeType::Scalar: {
int int_val;
double double_val;
bool bool_val;
std::string str_val;
case YAML::NodeType::Scalar:
if(YAML::convert<int>::decode(node, int_val)) {
res = int_val;
} else if(YAML::convert<double>::decode(node, double_val)) {
@@ -485,7 +446,6 @@ struct convert<nlohmann::json> {
} else if(YAML::convert<std::string>::decode(node, str_val)) {
res = str_val;
}
}
default:
break;
}

View File

@@ -68,11 +68,11 @@ set(FALCO_INCLUDE_DIRECTORIES
)
set(FALCO_DEPENDENCIES cxxopts)
set(FALCO_LIBRARIES falco_engine)
set(FALCO_LIBRARIES falco_engine sinsp yaml-cpp)
if(USE_JEMALLOC OR USE_MIMALLOC)
list(APPEND FALCO_DEPENDENCIES malloc)
list(APPEND FALCO_LIBRARIES ${MALLOC_LIB})
if(USE_JEMALLOC)
list(APPEND FALCO_DEPENDENCIES jemalloc)
list(APPEND FALCO_LIBRARIES ${JEMALLOC_LIB})
endif()
if(NOT WIN32)
@@ -110,23 +110,19 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT MINIMAL_BUILD)
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND USE_BUNDLED_GRPC)
list(APPEND FALCO_DEPENDENCIES grpc)
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND USE_BUNDLED_CURL)
list(APPEND FALCO_DEPENDENCIES curl)
list(APPEND FALCO_LIBRARIES "${GRPC_LIBRARIES}")
endif()
list(
APPEND
FALCO_LIBRARIES
httplib::httplib
"${CURL_LIBRARIES}"
"${GRPCPP_LIB}"
"${GRPC_LIB}"
"${GPR_LIB}"
"${GRPC_LIBRARIES}"
"${PROTOBUF_LIB}"
"${CARES_LIB}"
"${OPENSSL_LIBRARIES}"
)
endif()

View File

@@ -200,12 +200,22 @@ static void select_event_set(falco::app::state& s,
concat_set_in_order(non_rules_sc_set_names) + "\n");
}
/* base_syscall.all behavior:
/* base_syscall.all / -A flag behavior:
* (1) default: all syscalls in rules included, sinsp state enforcement
without high volume syscalls
* (2) set: all syscalls in rules included, sinsp state enforcement
and allowing high volume syscalls */
if(!s.config->m_base_syscalls_all) {
bool all_events = false;
if(s.options.all_events) {
falco_logger::log(falco_logger::level::WARNING,
"The -A option is deprecated and will be removed. Use -o "
"base_syscalls.all=true instead.");
all_events = true;
}
if(s.config->m_base_syscalls_all) {
all_events = true;
}
if(!(s.options.all_events || s.config->m_base_syscalls_all)) {
auto ignored_sc_set = falco::app::ignored_sc_set();
auto erased_sc_set = s.selected_sc_set.intersect(ignored_sc_set);
s.selected_sc_set = s.selected_sc_set.diff(ignored_sc_set);

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ limitations under the License.
#include "../state.h"
#include "../run_result.h"
#include <string>
#include <nlohmann/json.hpp>
namespace falco {
@@ -35,44 +34,6 @@ 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) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ 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,12 +50,6 @@ 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

@@ -52,7 +52,8 @@ static void add_suggested_output(const falco::app::state& s,
s.engine->add_extra_output_format(format_suggested_field(fldinfo),
src,
eo.m_tags,
eo.m_rule);
eo.m_rule,
false);
}
}
}
@@ -61,7 +62,11 @@ static void add_suggested_output(const falco::app::state& s,
void configure_output_format(falco::app::state& s) {
for(auto& eo : s.config->m_append_output) {
if(eo.m_format != "") {
s.engine->add_extra_output_format(eo.m_format, eo.m_source, eo.m_tags, eo.m_rule);
s.engine->add_extra_output_format(eo.m_format,
eo.m_source,
eo.m_tags,
eo.m_rule,
false);
}
// Add suggested filtercheck formats to each source output
@@ -89,25 +94,40 @@ void configure_output_format(falco::app::state& s) {
}
// See https://falco.org/docs/rules/style-guide/
const std::string container_info =
"container_id=%container.id container_image=%container.image.repository "
"container_image_tag=%container.image.tag container_name=%container.name";
const std::string k8s_info = "k8s_ns=%k8s.ns.name k8s_pod_name=%k8s.pod.name";
const std::string gvisor_info = "vpid=%proc.vpid vtid=%thread.vtid";
if(!s.options.print_additional.empty()) {
falco_logger::log(falco_logger::level::WARNING,
"The -p/--print option is deprecated and will be removed. Use -o "
"append_output=... instead.\n");
if(s.options.print_additional == "c" || s.options.print_additional == "container" ||
s.options.print_additional == "k" || s.options.print_additional == "kubernetes") {
// Don't do anything, we don't need these anymore
// since container plugin takes care of suggesting the output format fields itself.
} else if(s.options.print_additional == "cg" ||
s.options.print_additional == "container-gvisor" ||
s.options.print_additional == "kg" ||
s.options.print_additional == "kubernetes-gvisor") {
s.engine->add_extra_output_format(gvisor_info, falco_common::syscall_source, {}, "");
} else {
s.engine->add_extra_output_format(s.options.print_additional, "", {}, "");
}
if(s.options.print_additional == "c" || s.options.print_additional == "container") {
s.engine->add_extra_output_format(container_info,
falco_common::syscall_source,
{},
"",
true);
} else if(s.options.print_additional == "cg" ||
s.options.print_additional == "container-gvisor") {
s.engine->add_extra_output_format(gvisor_info + " " + container_info,
falco_common::syscall_source,
{},
"",
true);
} else if(s.options.print_additional == "k" || s.options.print_additional == "kubernetes") {
s.engine->add_extra_output_format(container_info + " " + k8s_info,
falco_common::syscall_source,
{},
"",
true);
} else if(s.options.print_additional == "kg" ||
s.options.print_additional == "kubernetes-gvisor") {
s.engine->add_extra_output_format(gvisor_info + " " + container_info + " " + k8s_info,
falco_common::syscall_source,
{},
"",
true);
} else if(!s.options.print_additional.empty()) {
s.engine->add_extra_output_format(s.options.print_additional, "", {}, "", false);
}
}
@@ -150,15 +170,14 @@ falco::app::run_result falco::app::actions::init_falco_engine(falco::app::state&
if(s.is_capture_mode()) {
auto manager = s.offline_inspector->get_plugin_manager();
for(const auto& p : manager->plugins()) {
if((p->caps() & CAP_SOURCING) == 0 || p->id() == 0) {
continue;
}
bool added = false;
auto source_idx = manager->source_idx_by_plugin_id(p->id(), added);
auto engine_idx = s.source_infos.at(p->event_source())->engine_idx;
if(!added || source_idx != engine_idx) {
return run_result::fatal("Could not add event source in the engine: " +
p->event_source());
if(p->caps() & CAP_SOURCING && p->id() != 0) {
bool added = false;
auto source_idx = manager->source_idx_by_plugin_id(p->id(), added);
auto engine_idx = s.source_infos.at(p->event_source())->engine_idx;
if(!added || source_idx != engine_idx) {
return run_result::fatal("Could not add event source in the engine: " +
p->event_source());
}
}
}
}

View File

@@ -21,25 +21,82 @@ 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;
static void init_syscall_inspector(falco::app::state& s, std::shared_ptr<sinsp> inspector) {
sinsp_evt::param_fmt event_buffer_format = sinsp_evt::PF_NORMAL;
if(s.options.print_base64) {
falco_logger::log(falco_logger::level::WARNING,
"The -b/--print-base64 option is deprecated and will be removed. Use -o "
"buffer_format_base64=true instead.");
event_buffer_format = sinsp_evt::PF_BASE64;
}
if(s.config->m_buffer_format_base64) {
event_buffer_format = sinsp_evt::PF_BASE64;
}
inspector->set_buffer_format(event_buffer_format);
//
// Container engines
//
// Debug log messages
if(s.config->m_container_engines_mask & (1 << CT_DOCKER)) {
falco_logger::log(falco_logger::level::DEBUG, "Enabled container engine 'docker'");
}
if(s.config->m_container_engines_mask & (1 << CT_PODMAN)) {
falco_logger::log(falco_logger::level::DEBUG, "Enabled container engine 'podman'");
}
if(s.config->m_container_engines_mask &
((1 << CT_CRI) | (1 << CT_CRIO) | (1 << CT_CONTAINERD))) {
falco_logger::log(falco_logger::level::DEBUG, "Enabled container engine 'CRI'");
}
if(s.config->m_container_engines_mask & (1 << CT_LXC)) {
falco_logger::log(falco_logger::level::DEBUG, "Enabled container engine 'lxc'");
}
if(s.config->m_container_engines_mask & (1 << CT_LIBVIRT_LXC)) {
falco_logger::log(falco_logger::level::DEBUG, "Enabled container engine 'libvirt_lxc'");
}
if(s.config->m_container_engines_mask & (1 << CT_BPM)) {
falco_logger::log(falco_logger::level::DEBUG, "Enabled container engine 'bpm'");
}
// Container engines configs via falco.yaml
inspector->set_container_engine_mask(s.config->m_container_engines_mask);
for(auto& p : s.config->m_container_engines_cri_socket_paths) {
if(!p.empty()) {
inspector->add_cri_socket_path(p);
falco_logger::log(falco_logger::level::DEBUG,
"Enabled container runtime socket at '" + p + "' via config file");
}
}
inspector->set_cri_async(!s.config->m_container_engines_disable_cri_async);
if(s.config->m_container_engines_disable_cri_async) {
falco_logger::log(falco_logger::level::DEBUG, "Disabling async lookups for 'CRI'");
}
//
// If required, set the snaplen.
// In case both config and CLI options are specified, CLI takes precedence.
//
if(s.config->m_falco_libs_snaplen != 0) {
inspector->set_snaplen(s.config->m_falco_libs_snaplen);
}
if(s.options.snaplen != 0) {
inspector->set_snaplen(s.options.snaplen);
falco_logger::log(falco_logger::level::WARNING,
"The -S/--snaplen option is deprecated and will be removed. Use -o "
"falco_libs.snaplen=<len> instead.");
}
if(s.is_driver_drop_failed_exit_enabled()) {
falco_logger::log(falco_logger::level::INFO,
@@ -54,14 +111,7 @@ 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)) {
@@ -90,7 +140,6 @@ 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;
}
@@ -98,14 +147,13 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
std::string err;
std::unordered_set<std::string> used_plugins;
const auto& all_plugins = s.offline_inspector->get_plugin_manager()->plugins();
const bool is_capture_mode = s.is_capture_mode();
for(const auto& src : s.loaded_sources) {
auto src_info = s.source_infos.at(src);
// in capture mode, every event source uses the offline inspector.
// in live mode, we create a new inspector for each event source
if(is_capture_mode) {
if(s.is_capture_mode()) {
src_info->inspector = s.offline_inspector;
} else {
src_info->inspector =
@@ -126,16 +174,15 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
((p->id() != 0 && src == p->event_source()) ||
(p->id() == 0 && src == falco_common::syscall_source));
if(is_capture_mode) {
if(s.is_capture_mode()) {
// in capture mode, every plugin is already registered
// in the offline inspector by the load_plugins action
plugin = p;
} else {
// in live mode, for the inspector assigned to the given event source, we must
// register a plugin if one of the following condition applies to it:
// - it has event sourcing capability for the given event source
// - it has one among field extraction, event parsing and async events capabilities
// and is compatible (with respect to that capability) with the given event source
// in live mode, for the inspector assigned to the given
// event source, we must register the plugin supporting
// that event source and also plugins with field extraction
// capability that are compatible with that event source
if(is_input ||
(p->caps() & CAP_EXTRACTION &&
sinsp_plugin::is_source_compatible(p->extract_event_sources(), src)) ||
@@ -147,23 +194,22 @@ falco::app::run_result falco::app::actions::init_inspectors(falco::app::state& s
}
}
if(!plugin) {
continue;
}
// init the plugin only if we registered it into an inspector (in capture mode, this is
// true for every plugin). Avoid initializing the same plugin twice in the same
// inspector if we're in capture mode
if(!is_capture_mode || used_plugins.find(p->name()) == used_plugins.end()) {
if(!plugin->init(config->m_init_config, err)) {
return run_result::fatal(err);
// init the plugin, if we registered it into an inspector
// (in capture mode, this is true for every plugin)
if(plugin) {
// avoid initializing the same plugin twice in the same
// inspector if we're in capture mode
if(!s.is_capture_mode() || used_plugins.find(p->name()) == used_plugins.end()) {
if(!plugin->init(config->m_init_config, err)) {
return run_result::fatal(err);
}
}
if(is_input) {
auto gen_check = src_info->inspector->new_generic_filtercheck();
src_info->filterchecks->add_filter_check(std::move(gen_check));
}
used_plugins.insert(plugin->name());
}
if(is_input) {
auto gen_check = src_info->inspector->new_generic_filtercheck();
src_info->filterchecks->add_filter_check(std::move(gen_check));
}
used_plugins.insert(plugin->name());
}
// populate filtercheck list for this inspector
@@ -171,27 +217,24 @@ 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);
}
if(is_capture_mode) {
continue;
}
// in live mode, each inspector should have registered at most two event sources: the
// "syscall" on, loaded at default at index 0, and optionally another one defined by a
// plugin, at index 1
const auto& sources = src_info->inspector->event_sources();
if(sources.size() == 0 || sources.size() > 2 ||
sources[0] != falco_common::syscall_source) {
err.clear();
for(const auto& source : sources) {
err += (err.empty() ? "" : ", ") + source;
// in live mode, each inspector should have registered at most two event sources:
// the "syscall" on, loaded at default at index 0, and optionally another
// one defined by a plugin, at index 1
if(!s.is_capture_mode()) {
const auto& sources = src_info->inspector->event_sources();
if(sources.size() == 0 || sources.size() > 2 ||
sources[0] != falco_common::syscall_source) {
err.clear();
for(const auto& source : sources) {
err += (err.empty() ? "" : ", ") + source;
}
return run_result::fatal("Illegal sources setup in live inspector for source '" +
src + "': " + err);
}
return run_result::fatal("Illegal sources setup in live inspector for source '" + src +
"': " + err);
}
}

View File

@@ -64,7 +64,6 @@ falco::app::run_result falco::app::actions::init_outputs(falco::app::state& s) {
s.config->m_json_include_output_property,
s.config->m_json_include_tags_property,
s.config->m_json_include_message_property,
s.config->m_json_include_output_fields_property,
s.config->m_output_timeout,
s.config->m_buffered_outputs,
s.config->m_outputs_queue_capacity,

View File

@@ -21,18 +21,17 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::list_fields(falco::app::state& s) {
if(!s.options.list_fields) {
return run_result::ok();
if(s.options.list_fields) {
if(s.options.list_source_fields != "" &&
!s.engine->is_source_valid(s.options.list_source_fields)) {
return run_result::fatal("Value for --list must be a valid source type");
}
s.engine->list_fields(s.options.list_source_fields,
s.options.verbose,
s.options.names_only,
s.options.markdown);
return run_result::exit();
}
if(s.options.list_source_fields != "" &&
!s.engine->is_source_valid(s.options.list_source_fields)) {
return run_result::fatal("Value for --list must be a valid source type");
}
s.engine->list_fields(s.options.list_source_fields,
s.options.verbose,
s.options.names_only,
s.options.markdown);
return run_result::exit();
return run_result::ok();
}

View File

@@ -24,20 +24,20 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::list_plugins(const falco::app::state& s) {
if(!s.options.list_plugins) {
return run_result::ok();
if(s.options.list_plugins) {
std::ostringstream os;
sinsp inspector;
const auto& configs = s.config->m_plugins;
for(auto& c : configs) {
// load the plugin (no need to initialize it)
auto plugin = inspector.register_plugin(c.m_library_path);
format_plugin_info(plugin, os);
os << std::endl;
}
printf("%lu Plugins Loaded:\n\n%s\n", configs.size(), os.str().c_str());
return run_result::exit();
}
std::ostringstream os;
sinsp inspector;
const auto& configs = s.config->m_plugins;
for(auto& c : configs) {
// load the plugin (no need to initialize it)
auto plugin = inspector.register_plugin(c.m_library_path);
format_plugin_info(plugin, os);
os << std::endl;
}
printf("%zu Plugins Loaded:\n\n%s\n", configs.size(), os.str().c_str());
return run_result::exit();
return run_result::ok();
}

View File

@@ -66,10 +66,6 @@ falco::app::run_result falco::app::actions::load_config(const falco::app::state&
}
}
s.config->m_falco_reload_ts = (int64_t)std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
s.config->m_buffered_outputs = !s.options.unbuffered_outputs;
return apply_deprecated_options(s);

View File

@@ -47,24 +47,20 @@ 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;
}
// Account the plugin event source
state::source_info src_info;
src_info.filterchecks = std::make_shared<filter_check_list>();
auto src_name = plugin->event_source();
s.source_infos.insert(src_info, src_name);
// note: this avoids duplicate values
if(std::find(s.loaded_sources.begin(), s.loaded_sources.end(), src_name) ==
s.loaded_sources.end()) {
s.loaded_sources.push_back(src_name);
if(plugin->caps() & CAP_SOURCING && plugin->id() != 0) {
state::source_info src_info;
src_info.filterchecks = std::make_shared<filter_check_list>();
auto sname = plugin->event_source();
s.source_infos.insert(src_info, sname);
// note: this avoids duplicate values
if(std::find(s.loaded_sources.begin(), s.loaded_sources.end(), sname) ==
s.loaded_sources.end()) {
s.loaded_sources.push_back(sname);
}
}
}

View File

@@ -27,6 +27,8 @@ 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

@@ -30,23 +30,21 @@ falco::app::run_result falco::app::actions::pidfile(const falco::app::state& sta
return run_result::ok();
}
if(state.options.pidfilename.empty()) {
return run_result::ok();
if(!state.options.pidfilename.empty()) {
int64_t self_pid = getpid();
std::ofstream stream;
stream.open(state.options.pidfilename);
if(!stream.good()) {
falco_logger::log(
falco_logger::level::ERR,
"Could not write pid to pidfile " + state.options.pidfilename + ". Exiting.\n");
exit(-1);
}
stream << self_pid;
stream.close();
}
int64_t self_pid = getpid();
std::ofstream stream;
stream.open(state.options.pidfilename);
if(!stream.good()) {
falco_logger::log(
falco_logger::level::ERR,
"Could not write pid to pidfile " + state.options.pidfilename + ". Exiting.\n");
exit(-1);
}
stream << self_pid;
stream.close();
return run_result::ok();
}

View File

@@ -21,10 +21,9 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_config_schema(falco::app::state &s) {
if(!s.options.print_config_schema) {
return run_result::ok();
if(s.options.print_config_schema) {
printf("%s", s.config->m_config_schema.dump(2).c_str());
return run_result::exit();
}
printf("%s", s.config->m_config_schema.dump(2).c_str());
return run_result::exit();
return run_result::ok();
}

View File

@@ -22,13 +22,12 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_generated_gvisor_config(falco::app::state& s) {
if(s.options.gvisor_generate_config_with_socket.empty()) {
return run_result::ok();
if(!s.options.gvisor_generate_config_with_socket.empty()) {
sinsp i;
std::string gvisor_config =
i.generate_gvisor_config(s.options.gvisor_generate_config_with_socket);
printf("%s\n", gvisor_config.c_str());
return run_result::exit();
}
sinsp i;
std::string gvisor_config =
i.generate_gvisor_config(s.options.gvisor_generate_config_with_socket);
printf("%s\n", gvisor_config.c_str());
return run_result::exit();
return run_result::ok();
}

View File

@@ -21,10 +21,9 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_help(falco::app::state& s) {
if(!s.options.help) {
return run_result::ok();
if(s.options.help) {
printf("%s", s.options.usage().c_str());
return run_result::exit();
}
printf("%s", s.options.usage().c_str());
return run_result::exit();
return run_result::ok();
}

View File

@@ -28,25 +28,22 @@ using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_kernel_version(const falco::app::state& s) {
#ifdef __linux__
// We print this info only when a kernel driver is injected
bool const is_kernel_driver_injected = s.is_modern_ebpf() || s.is_ebpf() || s.is_kmod();
if(!is_kernel_driver_injected) {
return run_result::ok();
}
if(s.is_modern_ebpf() || s.is_ebpf() || s.is_kmod()) {
std::ifstream input_file("/proc/version");
if(!input_file.is_open()) {
// We don't want to fail, we just need to log something
falco_logger::log(falco_logger::level::INFO,
"Cannot read under '/proc/version' (err_message: '" +
std::string(strerror(errno)) + "', err_code: " +
std::to_string(errno) + "). No info provided, go on.");
return run_result::ok();
}
std::ifstream input_file("/proc/version");
if(!input_file.is_open()) {
// We don't want to fail, we just need to log something
falco_logger::log(
falco_logger::level::INFO,
"Cannot read under '/proc/version' (err_message: '" + std::string(strerror(errno)) +
"', err_code: " + std::to_string(errno) + "). No info provided, go on.");
return run_result::ok();
std::stringstream buffer;
buffer << input_file.rdbuf();
std::string contents(buffer.str());
falco_logger::log(falco_logger::level::INFO, "System info: " + contents);
}
std::stringstream buffer;
buffer << input_file.rdbuf();
std::string contents(buffer.str());
falco_logger::log(falco_logger::level::INFO, "System info: " + contents);
#endif
return run_result::ok();
}

View File

@@ -24,24 +24,25 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_page_size(const falco::app::state& s) {
if(!s.options.print_page_size) {
return run_result::ok();
}
if(s.options.print_page_size) {
#ifndef _WIN32
long page_size = getpagesize();
long page_size = getpagesize();
#else
SYSTEM_INFO sysInfo;
SYSTEM_INFO sysInfo;
GetSystemInfo(&sysInfo);
GetSystemInfo(&sysInfo);
long page_size = sysInfo.dwPageSize;
long page_size = sysInfo.dwPageSize;
#endif
if(page_size <= 0) {
return run_result::fatal("\nUnable to get the system page size through 'getpagesize()'\n");
if(page_size <= 0) {
return run_result::fatal(
"\nUnable to get the system page size through 'getpagesize()'\n");
} else {
falco_logger::log(
falco_logger::level::INFO,
"Your system page size is: " + std::to_string(page_size) + " bytes\n");
}
return run_result::exit();
}
falco_logger::log(falco_logger::level::INFO,
"Your system page size is: " + std::to_string(page_size) + " bytes\n");
return run_result::exit();
return run_result::ok();
}

View File

@@ -24,81 +24,78 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_plugin_info(const falco::app::state &s) {
if(s.options.print_plugin_info.empty()) {
return run_result::ok();
}
if(!s.options.print_plugin_info.empty()) {
sinsp inspector;
for(auto &pc : s.config->m_plugins) {
if(pc.m_name == s.options.print_plugin_info ||
pc.m_library_path == s.options.print_plugin_info) {
// load the plugin
auto p = inspector.register_plugin(pc.m_library_path);
sinsp inspector;
for(auto &pc : s.config->m_plugins) {
if(pc.m_name != s.options.print_plugin_info &&
pc.m_library_path != s.options.print_plugin_info) {
continue;
}
// print plugin descriptive info
std::ostringstream os;
format_plugin_info(p, os);
os << std::endl;
printf("%s", os.str().c_str());
// found matching plugin; load it
auto p = inspector.register_plugin(pc.m_library_path);
// print plugin descriptive info
std::ostringstream os;
format_plugin_info(p, os);
os << std::endl;
printf("%s", os.str().c_str());
// print plugin init schema
os.str("");
os.clear();
ss_plugin_schema_type type;
auto schema = p->get_init_schema(type);
os << "Init config schema type: ";
switch(type) {
case SS_PLUGIN_SCHEMA_JSON:
os << "JSON" << std::endl;
break;
case SS_PLUGIN_SCHEMA_NONE:
default:
os << "Not available, plugin does not implement the init config schema "
"functionality"
<< std::endl;
break;
}
os << schema << std::endl;
os << std::endl;
printf("%s", os.str().c_str());
// init the plugin
std::string err;
if(!p->init(pc.m_init_config, err)) {
return run_result::fatal(err);
}
// print plugin suggested open parameters
if(p->caps() & CAP_SOURCING) {
os.str("");
os.clear();
auto params = p->list_open_params();
if(params.empty()) {
os << "No suggested open params available: ";
os << "plugin has not been configured, or it does not implement the open "
"params suggestion functionality"
<< std::endl;
} else {
os << "Suggested open params:" << std::endl;
for(const auto &oparam : p->list_open_params()) {
if(oparam.desc == "") {
os << oparam.value << std::endl;
} else {
os << oparam.value << ": " << oparam.desc << std::endl;
}
// print plugin init schema
os.str("");
os.clear();
ss_plugin_schema_type type;
auto schema = p->get_init_schema(type);
os << "Init config schema type: ";
switch(type) {
case SS_PLUGIN_SCHEMA_JSON:
os << "JSON" << std::endl;
break;
case SS_PLUGIN_SCHEMA_NONE:
default:
os << "Not available, plugin does not implement the init config schema "
"functionality"
<< std::endl;
break;
}
}
os << std::endl;
printf("%s", os.str().c_str());
}
os << schema << std::endl;
os << std::endl;
printf("%s", os.str().c_str());
// exit
return run_result::exit();
// init the plugin
std::string err;
if(!p->init(pc.m_init_config, err)) {
return run_result::fatal(err);
}
// print plugin suggested open parameters
if(p->caps() & CAP_SOURCING) {
os.str("");
os.clear();
auto params = p->list_open_params();
if(params.empty()) {
os << "No suggested open params available: ";
os << "plugin has not been configured, or it does not implement the open "
"params suggestion functionality"
<< std::endl;
} else {
os << "Suggested open params:" << std::endl;
for(const auto &oparam : p->list_open_params()) {
if(oparam.desc == "") {
os << oparam.value << std::endl;
} else {
os << oparam.value << ": " << oparam.desc << std::endl;
}
}
}
os << std::endl;
printf("%s", os.str().c_str());
}
// exit
return run_result::exit();
}
}
return run_result::fatal("can't find plugin and print its info: " +
s.options.print_plugin_info);
}
return run_result::fatal("can't find plugin and print its info: " +
s.options.print_plugin_info);
return run_result::ok();
}

View File

@@ -21,10 +21,9 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_rule_schema(falco::app::state &s) {
if(!s.options.print_rule_schema) {
return run_result::ok();
if(s.options.print_rule_schema) {
printf("%s", s.engine->m_rule_schema.dump(2).c_str());
return run_result::exit();
}
printf("%s", s.engine->m_rule_schema.dump(2).c_str());
return run_result::exit();
return run_result::ok();
}

View File

@@ -88,30 +88,31 @@ static int get_sysinfo(nlohmann::json& support) {
#endif
falco::app::run_result falco::app::actions::print_support(falco::app::state& s) {
if(!s.options.print_support) {
return run_result::ok();
if(s.options.print_support) {
nlohmann::json support;
if(get_sysinfo(support) != 0) {
return run_result::fatal(std::string("Could not get system info: ") + strerror(errno));
}
const falco::versions_info infos(s.offline_inspector);
support["version"] = infos.falco_version;
support["engine_info"] = infos.as_json();
support["cmdline"] = s.cmdline;
support["config"] = s.config->dump();
support["rules_files"] = nlohmann::json::array();
for(const auto& filename : s.config->m_loaded_rules_filenames) {
nlohmann::json finfo;
finfo["name"] = filename;
nlohmann::json variant;
variant["content"] = read_file(filename);
finfo["variants"].push_back(variant);
support["rules_files"].push_back(finfo);
}
printf("%s\n", support.dump().c_str());
return run_result::exit();
}
nlohmann::json support;
if(get_sysinfo(support) != 0) {
return run_result::fatal(std::string("Could not get system info: ") + strerror(errno));
}
const falco::versions_info infos(s.offline_inspector);
support["version"] = infos.falco_version;
support["engine_info"] = infos.as_json();
support["cmdline"] = s.cmdline;
support["config"] = s.config->dump();
support["rules_files"] = nlohmann::json::array();
for(const auto& filename : s.config->m_loaded_rules_filenames) {
nlohmann::json finfo;
finfo["name"] = filename;
nlohmann::json variant;
variant["content"] = read_file(filename);
finfo["variants"].push_back(variant);
support["rules_files"].push_back(finfo);
}
printf("%s\n", support.dump().c_str());
return run_result::exit();
return run_result::ok();
}

View File

@@ -157,29 +157,30 @@ static void print_events(const std::vector<event_entry>& events, bool markdown)
}
falco::app::run_result falco::app::actions::print_syscall_events(falco::app::state& s) {
if(!s.options.list_syscall_events) {
return run_result::ok();
if(s.options.list_syscall_events) {
const falco::versions_info info(s.offline_inspector);
printf("The events below are valid for Falco *Schema Version*: %s\n",
info.driver_schema_version.c_str());
const libsinsp::events::set<ppm_event_code> available =
libsinsp::events::all_event_set().diff(
sc_set_to_event_set(falco::app::ignored_sc_set()));
const struct events_by_category events_bc = get_event_entries_by_category(true, available);
printf("## Syscall events\n\n");
print_events(events_bc.syscalls, s.options.markdown);
printf("\n\n## Tracepoint events\n\n");
print_events(events_bc.tracepoints, s.options.markdown);
printf("\n\n## Plugin events\n\n");
print_events(events_bc.pluginevents, s.options.markdown);
printf("\n\n## Metaevents\n\n");
print_events(events_bc.metaevents, s.options.markdown);
return run_result::exit();
}
const falco::versions_info info(s.offline_inspector);
printf("The events below are valid for Falco *Schema Version*: %s\n",
info.driver_schema_version.c_str());
const libsinsp::events::set<ppm_event_code> available = libsinsp::events::all_event_set().diff(
sc_set_to_event_set(falco::app::ignored_sc_set()));
const struct events_by_category events_bc = get_event_entries_by_category(true, available);
printf("## Syscall events\n\n");
print_events(events_bc.syscalls, s.options.markdown);
printf("\n\n## Tracepoint events\n\n");
print_events(events_bc.tracepoints, s.options.markdown);
printf("\n\n## Plugin events\n\n");
print_events(events_bc.pluginevents, s.options.markdown);
printf("\n\n## Metaevents\n\n");
print_events(events_bc.metaevents, s.options.markdown);
return run_result::exit();
return run_result::ok();
}

View File

@@ -22,22 +22,22 @@ using namespace falco::app;
using namespace falco::app::actions;
falco::app::run_result falco::app::actions::print_version(falco::app::state& s) {
if(!s.options.print_version_info) {
return run_result::ok();
if(s.options.print_version_info) {
const falco::versions_info info(s.offline_inspector);
if(s.config->m_json_output) {
printf("%s\n", info.as_json().dump().c_str());
} else {
printf("Falco version: %s\n", info.falco_version.c_str());
printf("Libs version: %s\n", info.libs_version.c_str());
printf("Plugin API: %s\n", info.plugin_api_version.c_str());
printf("Engine: %s\n", info.engine_version.c_str());
printf("Driver:\n");
printf(" API version: %s\n", info.driver_api_version.c_str());
printf(" Schema version: %s\n", info.driver_schema_version.c_str());
printf(" Default driver: %s\n", info.default_driver_version.c_str());
}
return run_result::exit();
}
const falco::versions_info info(s.offline_inspector);
if(s.config->m_json_output) {
printf("%s\n", info.as_json().dump().c_str());
} else {
printf("Falco version: %s\n", info.falco_version.c_str());
printf("Libs version: %s\n", info.libs_version.c_str());
printf("Plugin API: %s\n", info.plugin_api_version.c_str());
printf("Engine: %s\n", info.engine_version.c_str());
printf("Driver:\n");
printf(" API version: %s\n", info.driver_api_version.c_str());
printf(" Schema version: %s\n", info.driver_schema_version.c_str());
printf(" Default driver: %s\n", info.default_driver_version.c_str());
}
return run_result::exit();
return run_result::ok();
}

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2025 The Falco Authors.
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@ limitations under the License.
#include <fcntl.h>
#include <atomic>
#include <unordered_map>
#include <memory>
#include "falco_utils.h"
@@ -37,7 +36,6 @@ 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;
@@ -145,11 +143,6 @@ 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
//
@@ -175,21 +168,11 @@ 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([&]() {
falco::app::g_restart_signal.handle([&s]() {
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;
@@ -243,7 +226,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 = ev->get_param(0)->as<uint32_t>();
auto pluginID = *(uint32_t*)ev->get_param(0)->m_val;
if(pluginID != 0) {
msg += " (plugin ID: " + std::to_string(pluginID) + ")";
}
@@ -277,18 +260,10 @@ static falco::app::run_result do_inspect(
// Reset the timeouts counter, Falco successfully got an event to process
timeouts_since_last_success_or_msg = 0;
if(duration_start == 0) {
duration_start = ev->get_ts();
} else if(duration_to_tot_ns > 0) {
// Highest priority async events (whose timestamp is -1 and get set by sinsp to current
// ts) are processed **before** other events, event if already enqueued. This means that
// we might find ourself in a situation where we have duration_start whose ts is > then
// next ev->get_ts(), leading t ev->get_ts() - duration_start being <0 (and, since we
// are unsigned here, huge). The diff should never need to be that large anyway, use a
// signed.
const int64_t diff = ev->get_ts() - duration_start;
if(diff >= (int64_t)duration_to_tot_ns) {
if(ev->get_ts() - duration_start >= duration_to_tot_ns) {
break;
}
}
@@ -304,10 +279,7 @@ 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,
@@ -315,46 +287,6 @@ 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;
}
}
@@ -494,24 +426,6 @@ 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()) {
@@ -563,10 +477,6 @@ 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,
@@ -596,9 +506,6 @@ 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

@@ -27,46 +27,44 @@ using namespace falco::app::actions;
falco::app::run_result falco::app::actions::start_grpc_server(falco::app::state& s) {
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
// gRPC server
if(!s.config->m_grpc_enabled) {
return run_result::ok();
}
if(s.config->m_grpc_enabled) {
if(s.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG,
"Skipping starting gRPC server in dry-run\n");
return run_result::ok();
}
if(s.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG, "Skipping starting gRPC server in dry-run\n");
return run_result::ok();
falco_logger::log(falco_logger::level::INFO,
"gRPC server threadiness equals to " +
std::to_string(s.config->m_grpc_threadiness) + "\n");
// TODO(fntlnz,leodido): when we want to spawn multiple threads we need to have a queue per
// thread, or implement different queuing mechanisms, round robin, fanout? What we want to
// achieve?
s.grpc_server.init(s.config->m_grpc_bind_address,
s.config->m_grpc_threadiness,
s.config->m_grpc_private_key,
s.config->m_grpc_cert_chain,
s.config->m_grpc_root_certs,
s.config->m_log_level);
s.grpc_server_thread = std::thread([&s] { s.grpc_server.run(); });
}
falco_logger::log(falco_logger::level::INFO,
"gRPC server threadiness equals to " +
std::to_string(s.config->m_grpc_threadiness) + "\n");
// TODO(fntlnz,leodido): when we want to spawn multiple threads we need to have a queue per
// thread, or implement different queuing mechanisms, round robin, fanout? What we want to
// achieve?
s.grpc_server.init(s.config->m_grpc_bind_address,
s.config->m_grpc_threadiness,
s.config->m_grpc_private_key,
s.config->m_grpc_cert_chain,
s.config->m_grpc_root_certs,
s.config->m_log_level);
s.grpc_server_thread = std::thread([&s] { s.grpc_server.run(); });
#endif
return run_result::ok();
}
falco::app::run_result falco::app::actions::stop_grpc_server(falco::app::state& s) {
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
if(!s.config->m_grpc_enabled) {
return run_result::ok();
}
if(s.config->m_grpc_enabled) {
if(s.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG,
"Skipping stopping gRPC server in dry-run\n");
return run_result::ok();
}
if(s.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG, "Skipping stopping gRPC server in dry-run\n");
return run_result::ok();
}
if(s.grpc_server_thread.joinable()) {
s.grpc_server.shutdown();
s.grpc_server_thread.join();
if(s.grpc_server_thread.joinable()) {
s.grpc_server.shutdown();
s.grpc_server_thread.join();
}
}
#endif
return run_result::ok();

View File

@@ -26,41 +26,39 @@ using namespace falco::app::actions;
falco::app::run_result falco::app::actions::start_webserver(falco::app::state& state) {
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
if(state.is_capture_mode() || !state.config->m_webserver_enabled) {
return run_result::ok();
if(!state.is_capture_mode() && state.config->m_webserver_enabled) {
if(state.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG,
"Skipping starting webserver in dry-run\n");
return run_result::ok();
}
falco_configuration::webserver_config webserver_config = state.config->m_webserver_config;
std::string ssl_option = (webserver_config.m_ssl_enabled ? " (SSL)" : "");
falco_logger::log(falco_logger::level::INFO,
"Starting health webserver with threadiness " +
std::to_string(webserver_config.m_threadiness) +
", listening on " + webserver_config.m_listen_address + ":" +
std::to_string(webserver_config.m_listen_port) + ssl_option +
"\n");
state.webserver.start(state, webserver_config);
}
if(state.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG, "Skipping starting webserver in dry-run\n");
return run_result::ok();
}
falco_configuration::webserver_config webserver_config = state.config->m_webserver_config;
std::string ssl_option = (webserver_config.m_ssl_enabled ? " (SSL)" : "");
falco_logger::log(falco_logger::level::INFO,
"Starting health webserver with threadiness " +
std::to_string(webserver_config.m_threadiness) + ", listening on " +
webserver_config.m_listen_address + ":" +
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();
}
falco::app::run_result falco::app::actions::stop_webserver(falco::app::state& state) {
#if !defined(_WIN32) && !defined(__EMSCRIPTEN__) && !defined(MINIMAL_BUILD)
if(state.is_capture_mode() || !state.config->m_webserver_enabled) {
return run_result::ok();
}
if(!state.is_capture_mode() && state.config->m_webserver_enabled) {
if(state.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG,
"Skipping stopping webserver in dry-run\n");
return run_result::ok();
}
if(state.options.dry_run) {
falco_logger::log(falco_logger::level::DEBUG, "Skipping stopping webserver in dry-run\n");
return run_result::ok();
state.webserver.stop();
}
state.webserver.stop();
#endif
return run_result::ok();
}

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