Compare commits

..

2 Commits

Author SHA1 Message Date
Federico Di Pierro
b9d5c39dd4 test
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-09-05 09:36:59 +02:00
Federico Di Pierro
fd6e149db0 chore: test test test ci.
Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
2023-09-05 09:32:02 +02:00
218 changed files with 5280 additions and 7152 deletions

View File

@@ -1,21 +0,0 @@
[![LIBS](https://img.shields.io/badge/LIBS-LIBSVER-yellow)](https://github.com/falcosecurity/libs/releases/tag/LIBSVER)
[![DRIVER](https://img.shields.io/badge/DRIVER-DRIVERVER-yellow)](https://github.com/falcosecurity/libs/releases/tag/DRIVERVER)
| Packages | Download |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 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) |
| 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) |
| Images |
| --------------------------------------------------------------------------- |
| `docker pull docker.io/falcosecurity/falco:FALCOVER` |
| `docker pull public.ecr.aws/falcosecurity/falco:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-driver-loader-legacy:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-no-driver:FALCOVER` |
| `docker pull docker.io/falcosecurity/falco-distroless:FALCOVER` |

View File

@@ -13,6 +13,18 @@ concurrency:
cancel-in-progress: true
jobs:
my-test:
runs-on: [ "self-hosted", "linux", "ARM64" ]
steps:
- name: etc os release
run: cat /etc/os-release
- name: uname
run: uname -a
- name: install deps
run: sudo yum update && sudo yum install make
fetch-version:
uses: ./.github/workflows/reusable_fetch_version.yaml
@@ -23,34 +35,15 @@ jobs:
arch: x86_64
version: ${{ needs.fetch-version.outputs.version }}
build-dev-packages-arm64:
needs: [fetch-version]
uses: ./.github/workflows/reusable_build_packages.yaml
with:
arch: aarch64
version: ${{ needs.fetch-version.outputs.version }}
test-dev-packages:
needs: [fetch-version, build-dev-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
with:
arch: x86_64
# static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
test-dev-packages-arm64:
needs: [fetch-version, build-dev-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: aarch64
arch: x86_64
static: ${{ matrix.static != '' && true || false }}
version: ${{ needs.fetch-version.outputs.version }}
@@ -61,15 +54,7 @@ jobs:
git_ref: ${{ github.event.pull_request.head.sha }}
minimal: true
build_type: Debug
build-dev-minimal-arm64:
uses: ./.github/workflows/reusable_build_dev.yaml
with:
arch: aarch64
git_ref: ${{ github.event.pull_request.head.sha }}
minimal: true
build_type: Debug
# builds using system deps, checking out the PR's code
# note: this also runs a command that generates an output of form: "<engine_version> <some_hash>",
# of which <some_hash> is computed by hashing in order the following:
@@ -83,7 +68,7 @@ jobs:
git_ref: ${{ github.event.pull_request.head.sha }}
minimal: false
build_type: Debug
cmd: "echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Engine:' | awk '{print $2}') $(echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Schema version:' | awk '{print $3}') $(build/userspace/falco/falco -c ./falco.yaml --list --markdown | grep '^`' | sort) $(build/userspace/falco/falco -c ./falco.yaml --list-events | sort) | sha256sum)"
cmd: "echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Engine:' | awk '{print $2}') $(echo $(build/userspace/falco/falco -c ./falco.yaml --version | grep 'Schema version:' | awk '{print $3}') $(build/userspace/falco/falco -c ./falco.yaml --list --markdown | grep '^`' | sort) $(build/userspace/falco/falco -c ./falco.yaml --list-syscall-events | sort) | sha256sum)"
# checks the falco engine checksum for consistency
check-engine-checksum:
@@ -91,7 +76,7 @@ jobs:
needs: [build-dev]
steps:
- name: Checkout PR head ref
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
@@ -116,7 +101,7 @@ jobs:
needs: [build-dev]
steps:
- name: Checkout base ref
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.base_ref }}
@@ -124,10 +109,7 @@ jobs:
- name: Check Engine version
run: |
base_hash=$(grep CHECKSUM "./userspace/engine/falco_engine_version.h" | awk '{print $3}' | sed -e 's/"//g')
base_engine_ver_major=$(grep ENGINE_VERSION_MAJOR "./userspace/engine/falco_engine_version.h" | head -n 1 | awk '{print $3}' | sed -e 's/(//g' -e 's/)//g')
base_engine_ver_minor=$(grep ENGINE_VERSION_MINOR "./userspace/engine/falco_engine_version.h" | head -n 1 | awk '{print $3}' | sed -e 's/(//g' -e 's/)//g')
base_engine_ver_patch=$(grep ENGINE_VERSION_PATCH "./userspace/engine/falco_engine_version.h" | head -n 1 | awk '{print $3}' | sed -e 's/(//g' -e 's/)//g')
base_engine_ver="${base_engine_ver_major}.${base_engine_ver_minor}.${base_engine_ver_patch}"
base_engine_ver=$(grep ENGINE_VERSION "./userspace/engine/falco_engine_version.h" | awk '{print $3}' | sed -e 's/(//g' -e 's/)//g')
cur_hash=$(echo "${{ needs.build-dev.outputs.cmdout }}" | cut -d ' ' -f 2)
cur_engine_ver=$(echo "${{ needs.build-dev.outputs.cmdout }}" | cut -d ' ' -f 1)

View File

@@ -36,19 +36,19 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
@@ -56,7 +56,7 @@ jobs:
run: sudo apt update -y
- name: Install build dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt install libssl-dev libc-ares-dev libprotobuf-dev protobuf-compiler libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-$(uname -r) clang llvm git -y
run: sudo DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libc-ares-dev libprotobuf-dev protobuf-compiler libjq-dev libyaml-cpp-dev libgrpc++-dev protobuf-compiler-grpc rpm libelf-dev cmake build-essential libcurl4-openssl-dev linux-headers-$(uname -r) clang llvm git -y
- name: Prepare project
run: |
@@ -72,4 +72,4 @@ jobs:
popd
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@ddccb873888234080b77e9bc2d4764d5ccaaccf9 # v2.21.9
uses: github/codeql-action/analyze@v2

View File

@@ -5,8 +5,8 @@ jobs:
codespell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- uses: codespell-project/actions-codespell@94259cd8be02ad2903ba34a22d9c13de21a74461 # v2.0
- uses: actions/checkout@v2
- uses: codespell-project/actions-codespell@master
with:
skip: .git
ignore_words_file: .codespellignore

View File

@@ -15,8 +15,8 @@ jobs:
outputs:
engine_version_changed: ${{ steps.filter.outputs.engine_version }}
steps:
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- uses: dorny/paths-filter@4512585405083f25c027a35db413c2b3b9006d50 # v2.11.1
- uses: actions/checkout@v2
- uses: dorny/paths-filter@v2
id: filter
with:
filters: |
@@ -31,7 +31,7 @@ jobs:
if: needs.paths-filter.outputs.engine_version_changed == 'false'
steps:
- name: Check driver Falco engine version
uses: mshick/add-pr-comment@7c0890544fb33b0bdd2e59467fbacb62e028a096 # v2.8.1
uses: mshick/add-pr-comment@v2
with:
message: |
This PR may bring feature or behavior changes in the Falco engine and may require the engine version to be bumped.

View File

@@ -1,26 +0,0 @@
name: Insecure API check
on:
pull_request:
branches:
- master
- 'release/**'
- 'maintainers/**'
jobs:
insecure-api:
name: check-insecure-api
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep:1.41.0@sha256:85956fbe795a0e8a3825d5252f175887c0e0c6ce7a766a07062c0fb68415cd67
steps:
- name: Checkout Falco ⤵️
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 0
- name: Scan PR for insecure API usage 🕵️
run: |
semgrep scan \
--error \
--metrics=off \
--baseline-commit ${{ github.event.pull_request.base.sha }} \
--config=./semgrep

View File

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

View File

@@ -69,16 +69,13 @@ jobs:
test-packages:
needs: [release-settings, build-packages]
uses: ./.github/workflows/reusable_test_packages.yaml
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
# strategy:
# fail-fast: false
# matrix:
# static: ["static", ""]
strategy:
fail-fast: false
matrix:
static: ["static", ""]
with:
arch: x86_64
# static: ${{ matrix.static != '' && true || false }}
static: ${{ matrix.static != '' && true || false }}
version: ${{ github.event.release.tag_name }}
test-packages-arm64:
@@ -125,47 +122,3 @@ jobs:
is_latest: ${{ needs.release-settings.outputs.is_latest == 'true' }}
tag: ${{ github.event.release.tag_name }}
sign: true
release-body:
needs: [release-settings, publish-docker]
if: ${{ needs.release-settings.outputs.is_latest == 'true' }} # only for latest releases
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- name: Clone repo
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
- name: Extract LIBS and DRIVER versions
run: |
cp .github/release_template.md release-body.md
LIBS_VERS=$(cat cmake/modules/falcosecurity-libs.cmake | grep 'set(FALCOSECURITY_LIBS_VERSION' | tail -n1 | grep -o '[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*')
DRIVER_VERS=$(cat cmake/modules/driver.cmake | grep 'set(DRIVER_VERSION' | tail -n1 | grep -o '[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*')
sed -i s/LIBSVER/$LIBS_VERS/g release-body.md
sed -i s/DRIVERVER/$DRIVER_VERS/g release-body.md
- name: Append release matrixes
run: |
sed -i s/FALCOBUCKET/${{ needs.release-settings.outputs.bucket_suffix }}/g release-body.md
sed -i s/FALCOVER/${{ github.event.release.tag_name }}/g release-body.md
- name: Generate release notes
uses: leodido/rn2md@1378404a058ecf86701f3ab533d487333fc675a7
with:
milestone: ${{ github.event.release.tag_name }}
output: ./notes.md
- name: Merge release notes to pre existent body
run: cat notes.md >> release-body.md
- name: Attach release creator to release body
run: |
echo "" >> release-body.md
echo "#### Release Manager @${{ github.event.release.author.login }}" >> release-body.md
- name: Release
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15
with:
body_path: ./release-body.md
tag_name: ${{ github.event.release.tag_name }}
name: ${{ github.event.release.name }}

View File

@@ -27,30 +27,31 @@ on:
required: false
default: ''
type: string
jobs:
build-and-test:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-22.04' }}
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-22.04' }}
container: ${{ (inputs.arch == 'aarch64' && 'ubuntu:22.04') || '' }}
outputs:
cmdout: ${{ steps.run_cmd.outputs.out }}
cmdout: ${{ steps.run_cmd.outputs.out }}
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ inputs.git_ref }}
- name: Update base image
run: sudo apt update -y
- name: Install build dependencies
run: sudo DEBIAN_FRONTEND=noninteractive apt install libelf-dev libyaml-cpp-dev cmake build-essential git -y
run: sudo DEBIAN_FRONTEND=noninteractive apt install libjq-dev libelf-dev libyaml-cpp-dev cmake build-essential git -y
- name: Install build dependencies (non-minimal)
if: inputs.minimal != true
run: sudo DEBIAN_FRONTEND=noninteractive apt install libssl-dev libc-ares-dev libprotobuf-dev protobuf-compiler libgrpc++-dev protobuf-compiler-grpc rpm libcurl4-openssl-dev linux-headers-$(uname -r) clang llvm -y
run: sudo DEBIAN_FRONTEND=noninteractive apt install libssl-dev libyaml-dev libc-ares-dev libprotobuf-dev protobuf-compiler libgrpc++-dev protobuf-compiler-grpc rpm libcurl4-openssl-dev linux-headers-$(uname -r) clang llvm -y
- name: Prepare project
run: |
mkdir build
@@ -73,7 +74,7 @@ jobs:
- name: Run unit tests
run: |
pushd build
sudo ./unit_tests/falco_unit_tests
sudo ./unit_tests/falco_unit_tests
popd
- name: Run command

View File

@@ -27,15 +27,15 @@ on:
jobs:
build-docker:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
env:
TARGETARCH: ${{ (inputs.arch == 'aarch64' && 'arm64') || 'amd64' }}
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@v2
- name: Build no-driver image
run: |
@@ -46,16 +46,6 @@ jobs:
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-no-driver:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-no-driver-${{ inputs.arch }}.tar
- name: Build distroless image
run: |
cd ${{ github.workspace }}/docker/no-driver/
docker build -f Dockerfile.distroless -t docker.io/falcosecurity/falco-distroless:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg VERSION_BUCKET=bin${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-distroless:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-distroless-${{ inputs.arch }}.tar
- name: Build falco image
run: |
@@ -75,19 +65,9 @@ jobs:
--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-legacy image
run: |
cd ${{ github.workspace }}/docker/driver-loader-legacy/
docker build -t docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.arch }}-${{ inputs.tag }} \
--build-arg VERSION_BUCKET=deb${{ inputs.bucket_suffix }} \
--build-arg FALCO_VERSION=${{ inputs.version }} \
--build-arg TARGETARCH=${TARGETARCH} \
.
docker save docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.arch }}-${{ inputs.tag }} --output /tmp/falco-driver-loader-legacy-${{ inputs.arch }}.tar
- name: Upload images tarballs
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: falco-images
path: /tmp/falco-*.tar

View File

@@ -14,16 +14,16 @@ on:
jobs:
build-modern-bpf-skeleton:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
container: fedora:latest
steps:
# Always install deps before invoking checkout action, to properly perform a full clone.
- name: Install build dependencies
run: |
dnf install -y bpftool ca-certificates cmake make automake gcc gcc-c++ kernel-devel clang git pkg-config autoconf automake libbpf-devel elfutils-libelf-devel
dnf install -y bpftool ca-certificates cmake make automake gcc gcc-c++ kernel-devel clang git pkg-config autoconf automake libbpf-devel
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
- name: Build modern BPF skeleton
run: |
@@ -32,7 +32,7 @@ jobs:
make ProbeSkeleton -j6
- name: Upload skeleton
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: skeleton-build/skel_dir/bpf_probe.skel.h
@@ -40,7 +40,7 @@ jobs:
build-packages:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
needs: [build-modern-bpf-skeleton]
container: centos:7
steps:
@@ -50,14 +50,13 @@ jobs:
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++
source /opt/rh/devtoolset-9/enable
yum install -y wget git make m4 rpm-build elfutils-libelf-devel perl-IPC-Cmd
yum install -y wget git make m4 rpm-build perl-IPC-Cmd
- name: Checkout
# It is not possible to upgrade the checkout action to versions >= v4.0.0 because of incompatibilities with centos 7's libc.
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
uses: actions/checkout@v3
- name: Download skeleton
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: bpf_probe_${{ inputs.arch }}.skel.h
path: /tmp
@@ -98,32 +97,29 @@ jobs:
make package
- name: Upload Falco tar.gz package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.tar.gz
path: |
${{ github.workspace }}/build/falco-*.tar.gz
- name: Upload Falco deb package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.deb
path: |
${{ github.workspace }}/build/falco-*.deb
- name: Upload Falco rpm package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-${{ inputs.arch }}.rpm
path: |
${{ github.workspace }}/build/falco-*.rpm
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
build-musl-package:
# x86_64 only for now
# if: ${{ inputs.arch == 'x86_64' }}
if: false
if: ${{ inputs.arch == 'x86_64' }}
runs-on: ubuntu-latest
container: alpine:3.17
steps:
@@ -133,7 +129,7 @@ jobs:
apk add g++ gcc cmake make git bash perl linux-headers autoconf automake m4 libtool elfutils-dev libelf-static patch binutils bpftool clang
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -158,7 +154,7 @@ jobs:
mv falco-${{ inputs.version }}-x86_64.tar.gz falco-${{ inputs.version }}-static-x86_64.tar.gz
- name: Upload Falco static package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
path: |
@@ -175,12 +171,12 @@ jobs:
sudo DEBIAN_FRONTEND=noninteractive apt install cmake build-essential git emscripten -y
- name: Select node version
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3.8.1
uses: actions/setup-node@v3
with:
node-version: 14
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -214,74 +210,8 @@ jobs:
emmake make -j6 package
- name: Upload Falco WASM package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: falco-${{ inputs.version }}-wasm.tar.gz
path: |
${{ github.workspace }}/build/falco-${{ inputs.version }}-wasm.tar.gz
build-win32-package:
if: ${{ inputs.arch == 'x86_64' }}
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 0
- name: Prepare project
run: |
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DMINIMAL_BUILD=On -DUSE_BUNDLED_DEPS=On -DBUILD_FALCO_UNIT_TESTS=On -DFALCO_VERSION=${{ inputs.version }} ..
- name: Build project
run: |
cmake --build build --target package --config Release
- name: Run unit Tests
run: |
build/unit_tests/Release/falco_unit_tests.exe
- name: Upload Falco win32 installer
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: falco-installer-${{ inputs.version }}-win32.exe
path: build/falco-*.exe
- name: Upload Falco win32 package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: falco-${{ inputs.version }}-win32.exe
path: |
${{ github.workspace }}/build/userspace/falco/Release/falco.exe
build-macos-package:
if: ${{ inputs.arch == 'x86_64' }}
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
with:
fetch-depth: 0
- name: Prepare project
run: |
mkdir build
cd build
cmake -DMINIMAL_BUILD=On -DUSE_BUNDLED_DEPS=On -DBUILD_FALCO_UNIT_TESTS=On -DFALCO_VERSION=${{ inputs.version }} ..
- name: Build project
run: |
cmake --build build --target package
- name: Run unit Tests
run: |
sudo build/unit_tests/falco_unit_tests
- name: Upload Falco macos package
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
with:
name: falco-${{ inputs.version }}-macos
path: |
${{ github.workspace }}/build/userspace/falco/falco

View File

@@ -19,7 +19,7 @@ jobs:
version: ${{ steps.store_version.outputs.version }}
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
@@ -31,7 +31,7 @@ jobs:
- name: Configure project
run: |
mkdir build && cd build
cmake -DUSE_BUNDLED_DEPS=On -DUSE_DYNAMIC_LIBELF=Off ..
cmake -DUSE_BUNDLED_DEPS=On ..
- name: Load and store Falco version output
id: store_version

View File

@@ -26,10 +26,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
uses: docker/setup-buildx-action@v2
- name: Download images tarballs
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-images
path: /tmp/falco-images
@@ -39,13 +39,13 @@ jobs:
for img in /tmp/falco-images/falco-*.tar; do docker load --input $img; done
- name: Login to Docker Hub
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USER }}
password: ${{ secrets.DOCKERHUB_SECRET }}
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco-ecr"
aws-region: us-east-1 # The region must be set to us-east-1 in order to access ECR Public.
@@ -57,7 +57,7 @@ jobs:
registry-type: public
- name: Setup Crane
uses: imjasonh/setup-crane@00c9e93efa4e1138c9a7a5c594acd6c75a2fbf0c # v0.3
uses: imjasonh/setup-crane@v0.3
with:
version: v0.15.1
@@ -66,93 +66,66 @@ jobs:
run: |
docker push docker.io/falcosecurity/falco-no-driver:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-no-driver:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-distroless:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-distroless:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader-legacy:aarch64-${{ inputs.tag }}
docker push docker.io/falcosecurity/falco-driver-loader-legacy:x86_64-${{ inputs.tag }}
- name: Create no-driver manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
uses: Noelware/docker-manifest-action@0.3.1
with:
inputs: docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-no-driver:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-no-driver:x86_64-${{ inputs.tag }}
push: true
- name: Create distroless manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco-distroless:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-distroless:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-distroless:x86_64-${{ inputs.tag }}
push: true
- name: Tag slim manifest on Docker Hub
run: |
crane copy docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} docker.io/falcosecurity/falco:${{ inputs.tag }}-slim
- name: Create falco manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
uses: Noelware/docker-manifest-action@0.3.1
with:
inputs: docker.io/falcosecurity/falco:${{ inputs.tag }}
images: docker.io/falcosecurity/falco:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco:x86_64-${{ inputs.tag }}
push: true
- name: Create falco-driver-loader manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
uses: Noelware/docker-manifest-action@0.3.1
with:
inputs: docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-driver-loader:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-driver-loader:x86_64-${{ inputs.tag }}
push: true
- name: Create falco-driver-loader-legacy manifest on Docker Hub
uses: Noelware/docker-manifest-action@8e337e3cb9656abfcf20146b99706fd88716e942 # v0.4.0
with:
inputs: docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }}
images: docker.io/falcosecurity/falco-driver-loader-legacy:aarch64-${{ inputs.tag }},docker.io/falcosecurity/falco-driver-loader-legacy:x86_64-${{ inputs.tag }}
push: true
- name: Get Digests for images
id: digests
# We could probably use the docker-manifest-action output instead of recomputing those with crane
run: |
echo "falco-no-driver=$(crane digest docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-distroless=$(crane digest docker.io/falcosecurity/falco-distroless:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco=$(crane digest docker.io/falcosecurity/falco:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-driver-loader=$(crane digest docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }})" >> $GITHUB_OUTPUT
echo "falco-driver-loader-legacy=$(crane digest docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }})" >> $GITHUB_OUTPUT
- name: Publish images to ECR
run: |
crane copy docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco-distroless:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-distroless:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }}
crane copy docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }}
crane copy public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim
- name: Tag latest on Docker Hub and ECR
if: inputs.is_latest
run: |
crane tag docker.io/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco-distroless:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }} latest
crane tag docker.io/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
crane tag public.ecr.aws/falcosecurity/falco-no-driver:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco-distroless:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco-driver-loader:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco-driver-loader-legacy:${{ inputs.tag }} latest
crane tag public.ecr.aws/falcosecurity/falco:${{ inputs.tag }}-slim latest-slim
- name: Setup Cosign
if: inputs.sign
uses: sigstore/cosign-installer@11086d25041f77fe8fe7b9ea4e48e3b9192b8f19 # v3.1.2
uses: sigstore/cosign-installer@main
with:
cosign-release: v2.0.2
@@ -163,13 +136,9 @@ jobs:
COSIGN_YES: "true"
run: |
cosign sign docker.io/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
cosign sign docker.io/falcosecurity/falco-distroless@${{ steps.digests.outputs.falco-distroless }}
cosign sign docker.io/falcosecurity/falco@${{ steps.digests.outputs.falco }}
cosign sign docker.io/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign docker.io/falcosecurity/falco-driver-loader-legacy@${{ steps.digests.outputs.falco-driver-loader-legacy }}
cosign sign public.ecr.aws/falcosecurity/falco-no-driver@${{ steps.digests.outputs.falco-no-driver }}
cosign sign public.ecr.aws/falcosecurity/falco-distroless@${{ steps.digests.outputs.falco-distroless }}
cosign sign public.ecr.aws/falcosecurity/falco@${{ steps.digests.outputs.falco }}
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader@${{ steps.digests.outputs.falco-driver-loader }}
cosign sign public.ecr.aws/falcosecurity/falco-driver-loader-legacy@${{ steps.digests.outputs.falco-driver-loader-legacy }}

View File

@@ -23,67 +23,77 @@ env:
jobs:
publish-packages:
runs-on: ubuntu-latest
container: docker.io/library/fedora:38
container: docker.io/centos:7
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
- name: Install dependencies
run: |
dnf install rpm-sign expect which createrepo gpg python python-pip -y
pip install awscli==1.29.60
yum install epel-release -y
yum update -y
yum install rpm-sign expect which createrepo gpg python python-pip -y
pip install awscli==1.19.47
# Configure AWS role; see https://github.com/falcosecurity/test-infra/pull/1102
# Note: master CI can only push dev packages as we have 2 different roles for master and release.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco${{ inputs.bucket_suffix }}-s3"
aws-region: ${{ env.AWS_S3_REGION }}
- name: Download RPM x86_64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-x86_64.rpm
path: /tmp/falco-build-rpm
- name: Download RPM aarch64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-aarch64.rpm
path: /tmp/falco-build-rpm
- name: Download binary x86_64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-x86_64.tar.gz
path: /tmp/falco-build-bin
- name: Download binary aarch64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-aarch64.tar.gz
path: /tmp/falco-build-bin
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
- name: Download static binary x86_64
if: false
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-static-x86_64.tar.gz
path: /tmp/falco-build-bin-static
- name: Import gpg key
- name: Import gpg key
env:
GPG_KEY: ${{ secrets.GPG_KEY }}
run: printenv GPG_KEY | gpg --import -
- name: Sign rpms
run: |
rpmsign --define '_gpg_name Falcosecurity Package Signing' --addsign /tmp/falco-build-rpm/falco-*.rpm
echo "%_signature gpg" > ~/.rpmmacros
echo "%_gpg_name Falcosecurity Package Signing" >> ~/.rpmmacros
echo "%__gpg_sign_cmd %{__gpg} --force-v3-sigs --batch --no-armor --passphrase-fd 3 --no-secmem-warning -u \"%{_gpg_name}\" -sb --digest-algo sha256 %{__plaintext_filename}'" >> ~/.rpmmacros
cat > ~/sign <<EOF
#!/usr/bin/expect -f
spawn rpmsign --addsign {*}\$argv
expect -exact "Enter pass phrase: "
send -- "\n"
expect eof
EOF
chmod +x ~/sign
~/sign /tmp/falco-build-rpm/falco-*.rpm
rpm --qf %{SIGPGP:pgpsig} -qp /tmp/falco-build-rpm/falco-*.rpm | grep SHA256
- name: Publish rpm
run: |
./scripts/publish-rpm -f /tmp/falco-build-rpm/falco-${{ inputs.version }}-x86_64.rpm -f /tmp/falco-build-rpm/falco-${{ inputs.version }}-aarch64.rpm -r rpm${{ inputs.bucket_suffix }}
@@ -92,11 +102,8 @@ jobs:
run: |
./scripts/publish-bin -f /tmp/falco-build-bin/falco-${{ inputs.version }}-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
./scripts/publish-bin -f /tmp/falco-build-bin/falco-${{ inputs.version }}-aarch64.tar.gz -r bin${{ inputs.bucket_suffix }} -a aarch64
# The musl build job is currently disabled because we link libelf dynamically and it is
# not possible to dynamically link with musl
- name: Publish static
if: false
run: |
./scripts/publish-bin -f /tmp/falco-build-bin-static/falco-${{ inputs.version }}-static-x86_64.tar.gz -r bin${{ inputs.bucket_suffix }} -a x86_64
@@ -105,7 +112,7 @@ jobs:
container: docker.io/debian:stable
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
- name: Install dependencies
run: |
@@ -115,19 +122,19 @@ jobs:
# Configure AWS role; see https://github.com/falcosecurity/test-infra/pull/1102
# Note: master CI can only push dev packages as we have 2 different roles for master and release.
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: "arn:aws:iam::292999226676:role/github_actions-falco${{ inputs.bucket_suffix }}-s3"
aws-region: ${{ env.AWS_S3_REGION }}
- name: Download deb x86_64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-x86_64.deb
path: /tmp/falco-build-deb
- name: Download deb aarch64
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}-aarch64.deb
path: /tmp/falco-build-deb

View File

@@ -19,21 +19,21 @@ on:
jobs:
test-packages:
# See https://github.com/actions/runner/issues/409#issuecomment-1158849936
runs-on: ${{ (inputs.arch == 'aarch64' && 'actuated-arm64-8cpu-16gb') || 'ubuntu-latest' }}
runs-on: ${{ (inputs.arch == 'aarch64' && fromJSON('[ "self-hosted", "linux", "ARM64" ]')) || 'ubuntu-latest' }}
steps:
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: 'true'
- name: Setup Go
uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe # v4.1.0
uses: actions/setup-go@v3
with:
go-version: '>=1.17.0'
- name: Download binary
uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2
uses: actions/download-artifact@v3
with:
name: falco-${{ inputs.version }}${{ inputs.static && '-static' || '' }}-${{ inputs.arch }}.tar.gz
@@ -43,17 +43,16 @@ jobs:
tar -xvf $(ls falco-*.tar.gz)
cd falco-${{ inputs.version }}-${{ inputs.arch }}
sudo cp -r * /
# Note: most probably the plugin related tests should be moved to the plugin repo sooner or later.
- name: Install needed artifacts using falcoctl
if: ${{ inputs.static == false }}
# aarch64 job run on amazon-linux-2
- name: Install dependencies for falco-driver-loader tests on aarch64
if: ${{ inputs.arch == 'aarch64' }}
run: |
sudo mkdir -p /usr/share/falco/plugins
sudo falcoctl artifact install k8saudit-rules
sudo falcoctl artifact install cloudtrail-rules
# We only run driver loader tests on x86_64
- name: Install dependencies for falco-driver-loader tests
sudo yum update -y
sudo yum install -y build-essential clang make llvm gcc dkms kernel-devel-$(uname -r)
# x86_64 job run on ubuntu-22.04
- name: Install dependencies for falco-driver-loader tests on x86
if: ${{ inputs.arch == 'x86_64' }}
run: |
sudo apt update -y
@@ -72,25 +71,20 @@ jobs:
popd
- name: Run regression tests
env:
# fixme(leogr): this is a workaround for https://github.com/falcosecurity/falco/issues/2784
HOST_ROOT: ""
run: |
pushd submodules/falcosecurity-testing
./build/falco.test -falco-static=${{ inputs.static && 'true' || 'false' }} -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
if ${{ inputs.static && 'false' || 'true' }}; then
./build/falcoctl.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
./build/k8saudit.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
if ${{ inputs.arch == 'x86_64' && 'true' || 'false' }}; then
sudo ./build/falco-driver-loader.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
fi
sudo ./build/falco-driver-loader.test -test.timeout=90s -test.v >> ./report.txt 2>&1 || true
fi
cat ./report.txt | go-junit-report -set-exit-code > report.xml
popd
- name: Test Summary
if: always() # run this even if previous step fails
uses: test-summary/action@62bc5c68de2a6a0d02039763b8c754569df99e3f # v2.1
uses: test-summary/action@v2
with:
paths: "submodules/falcosecurity-testing/report.xml"
show: "fail"

View File

@@ -1,79 +0,0 @@
# This workflow uses actions that are not certified by GitHub. They are provided
# by a third-party and are governed by separate terms of service, privacy
# policy, and support documentation.
name: Scorecard supply-chain security
on:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
# Weekly on Mondays at 00:00.
- cron: '0 0 * * 1'
# The OSSF recommendation encourages to enable branch protection rules trigger
# to update the scorecard
# (https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection)
# but due to our GitHub org management this check is triggered too often and is
# therefore disabled.
# branch_protection_rule:
push:
branches: [ "master" ]
# Declare default permissions as read only.
permissions: read-all
jobs:
analysis:
name: Scorecard analysis
runs-on: ubuntu-latest
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
# Needed to publish results and get a badge (see publish_results below).
id-token: write
# Uncomment the permissions below if installing in a private repository.
# contents: read
# actions: read
steps:
- name: "Checkout code"
uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
with:
persist-credentials: false
- name: "Run analysis"
uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.1.2
with:
results_file: results.sarif
results_format: sarif
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
# - you want to enable the Branch-Protection check on a *public* repository, or
# - you are installing Scorecard on a *private* repository
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
# repo_token: ${{ secrets.SCORECARD_TOKEN }}
# Public repositories:
# - Publish results to OpenSSF REST API for easy access by consumers
# - Allows the repository to include the Scorecard badge.
# - See https://github.com/ossf/scorecard-action#publishing-results.
# For private repositories:
# - `publish_results` will always be set to `false`, regardless
# of the value entered here.
publish_results: true
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
with:
name: SARIF file
path: results.sarif
retention-days: 5
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4
with:
sarif_file: results.sarif

View File

@@ -7,7 +7,7 @@ jobs:
steps:
- name: Checkout ⤵️
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608 # v4.1.0
uses: actions/checkout@v3
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}
@@ -20,12 +20,12 @@ jobs:
- name: Build and run cppcheck 🏎️
run: |
mkdir build
cd build && cmake -DUSE_BUNDLED_DEPS=On -DUSE_DYNAMIC_LIBELF=Off -DBUILD_WARNINGS_AS_ERRORS=ON -DCREATE_TEST_TARGETS=Off -DCMAKE_BUILD_TYPE="release" -DBUILD_BPF=Off -DBUILD_DRIVER=Off ..
cd build && cmake -DUSE_BUNDLED_DEPS=On -DBUILD_WARNINGS_AS_ERRORS=ON -DCREATE_TEST_TARGETS=Off -DCMAKE_BUILD_TYPE="release" -DBUILD_BPF=Off -DBUILD_DRIVER=Off ..
make -j4 cppcheck
make -j4 cppcheck_htmlreport
- name: Upload reports ⬆️
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
uses: actions/upload-artifact@v3
with:
name: static-analysis-reports
path: ./build/static-analysis-reports

1
.gitignore vendored
View File

@@ -5,4 +5,3 @@
.vscode/*
*.idea*
CMakeUserPresets.json

View File

@@ -72,8 +72,6 @@ This is a list of production adopters of Falco (in alphabetical order):
* [Thales Group](https://www.thalesgroup.com) Thales is a global technology leader with more than 81,000 employees on five continents. The Thales Group is investing in digital and “deep tech” innovations Big Data, artificial intelligence, connectivity, cybersecurity and quantum technology to build a future we can all trust. In the past few years, the Cloud-Native paradigms and its frameworks and tools have challenged the way applications and services are developed, delivered, and instantiated. All sorts of services are container-based workloads managed by higher level layers of orchestration such as the Kubernetes environment. Thales is committed to develop Cloud-Native services and to provide its customers with security features that ensure their applications and services are protected against cyber threats. Falco is a framework that can help Thales' products and services reach the level of trust, security and safety our clients need.
* [Thought Machine](https://www.thoughtmachine.net) Thought Machine builds Vault Core and Vault Payments: cloud-native core and payments technology enabling banks and fintechs to remain competitive and flourish into the future. Vault Core and Vault Payments are the foundation layer of a bank's technology stack. They can run any bank, any product, and any payment set. Thought Machine uses Falco to perform cloud agnostic real time detections of suspicious container behaviour.
* [Vinted](https://vinted.com/) Vinted uses Falco to continuously monitor container activities, identifying security threats, and ensuring compliance. The container-native approach, rule-based real-time threat detection, community support, extensibility, and compliance capabilities are the main factors why we chose it to enhance Vinted Kubernetes security. Falco Sidekick is used to send critical and warning severity alerts to our incident management solution (RTIR).
* [Xenit AB](https://xenit.se/contact/) Xenit is a growth company with services within cloud and digital transformation. We provide an open-source Kubernetes framework that we leverage to help our customers get their applications to production as quickly and as securely as possible. We use Falco's detection capabilities to identify anomalous behaviour within our clusters in both Azure and AWS.
@@ -88,8 +86,6 @@ This is a list of production adopters of Falco (in alphabetical order):
* [StackRox](https://stackrox.io) is the industrys first Kubernetes-native security platform enabling organizations to build, deploy, and run cloud-native applications securely. The platform works with Kubernetes environments and integrates with DevOps and security tools, enabling teams to operationalize and secure their supply chain, infrastructure, and workloads. StackRox aims to harness containerized applications development speed while giving operations and security teams greater context and risk profiling. StackRox leverages cloud-native principles and declarative artifacts to automate DevSecOps best practices.
* [Wireshark](https://www.wireshark.org) is the world's most powerful and popular network protocol analyzer. The Wireshark team is combining Wireshark's features and Falco libs to create Logray, a cloud and system log analyzer with advanced filtering, capture, and scripting capabilities.
## Adding a name
If you would like to add your name to this file, submit a pull request with your change.

View File

@@ -1,307 +1,5 @@
# Change Log
## v0.37.1
Released on 2024-02-13
### Major Changes
* new(docker): added option for insecure http driver download to falco and driver-loader images [[#3058](https://github.com/falcosecurity/falco/pull/3058)] - [@toamto94](https://github.com/toamto94)
### Minor Changes
* update(cmake): bumped falcoctl to v0.7.2 [[#3076](https://github.com/falcosecurity/falco/pull/3076)] - [@FedeDP](https://github.com/FedeDP)
* update(build): link libelf dynamically [[#3048](https://github.com/falcosecurity/falco/pull/3048)] - [@LucaGuerra](https://github.com/LucaGuerra)
### Bug Fixes
* fix(userspace/engine): always consider all rules (even the ones below min_prio) in m_rule_stats_manager [[#3060](https://github.com/falcosecurity/falco/pull/3060)] - [@FedeDP](https://github.com/FedeDP)
### Non user-facing changes
* Added http headers option for driver download in docker images [[#3075](https://github.com/falcosecurity/falco/pull/3075)] - [@toamto94](https://github.com/toamto94)
* fix(build): install libstdc++ in the Wolfi image [[#3053](https://github.com/falcosecurity/falco/pull/3053)] - [@LucaGuerra](https://github.com/LucaGuerra)
## v0.37.0
Released on 2024-01-30
### Breaking Changes
- The deprecated `rate-limiter` mechanism is removed as it is no longer used.
- the deprecated `outputs.rate` Falco config is removed.
- the deprecated `outputs.max_burst` Falco config is removed.
- The deprecated `--userspace` CLI option is removed as it is no longer used.
- The `falco-driver-loader` script will be removed and embedded into falcoctl. The new falcoctl driven implementation will drop:
- `--source-only` CLI option.
- `BPF_USE_LOCAL_KERNEL_SOURCES` environment variable.
- `DRIVER_CURL_OPTIONS` environment variable.
- `FALCO_BPF_PROBE` environment variable is not used by the new falcoctl driver loader, since it is already deprecated and will be removed in the next major version.
Some env vars were renamed:
- `DRIVERS_REPO` env variable has been replaced by `FALCOCTL_DRIVER_NAME` or `--name` command line argument for `falcoctl driver` command
- `DRIVERS_NAME` env variable has been replaced by `FALCOCTL_DRIVER_REPOS`, or `--repo` command line argument for `falcoctl driver` command
- `DRIVER_KERNEL_RELEASE` env variable has been replaced by `--kernelrelease` command line argument for `falcoctl driver install` command
- `DRIVER_KERNEL_VERSION` env variable has been replaced by `--kernelversion` command line argument for `falcoctl driver install` command
- `DRIVER_INSECURE_DOWNLOAD` env variable has been replaced by `--http-insecure` command line argument for `falcoctl driver install` command
- Remove `-K/-k` options from Falco in favor of the new `k8smeta` plugin.
- Drop plugins shipped with Falco since plugins are now be managed by falcoctl.
- Falco 0.37.0 allows environment variables to be expanded even if they are part of a string. This introduces small breaking changes:
- Previously, environment variables used in YAML that were empty or defined as `“”` would be expanded to the default value. This was not consistent with the way YAML was handled in other cases, where we only returned the default values if the node was not defined. Now expanded env vars retain the same behavior of all other variables.
- Falco 0.37.0 will return default value for nodes that cannot be parsed to chosen type.
- `program_output` command will be env-expanded at init time, instead of letting `popen` and thus the `sh` shell expand it. This is technically a breaking change even if no behavioral change is expected. Also, you can avoid env var expansion by using `${{FOO}}` instead of `${FOO}`. It will resolve to `${FOO}` and won't be resolved to the env var value.
### Major Changes
* new!: dropped falco-driver-loader script in favor of new falcoctl driver command [[#2905](https://github.com/falcosecurity/falco/pull/2905)] - [@FedeDP](https://github.com/FedeDP)
* update!: bump libs to latest and deprecation of k8s metadata options and configs [[#2914](https://github.com/falcosecurity/falco/pull/2914)] - [@jasondellaluce](https://github.com/jasondellaluce)
* cleanup(falco)!: remove `outputs.rate` and `outputs.max_burst` from Falco config [[#2841](https://github.com/falcosecurity/falco/pull/2841)] - [@Andreagit97](https://github.com/Andreagit97)
* cleanup(falco)!: remove `--userspace` support [[#2839](https://github.com/falcosecurity/falco/pull/2839)] - [@Andreagit97](https://github.com/Andreagit97)
* new(engine): add selective overrides for Falco rules [[#2981](https://github.com/falcosecurity/falco/pull/2981)] - [@LucaGuerra](https://github.com/LucaGuerra)
* feat(userspace/falco): falco administrators can now configure the http output to compress the data sent as well as enable keep alive for the connection. Two new fields (compress_uploads and keep_alive) in the http_output block of the `falco.yaml` file can be used for that purpose. Both are disabled by default. [[#2974](https://github.com/falcosecurity/falco/pull/2974)] - [@sgaist](https://github.com/sgaist)
* new(userspace): support env variable expansion in all yaml, even inside strings. [[#2918](https://github.com/falcosecurity/falco/pull/2918)] - [@FedeDP](https://github.com/FedeDP)
* new(scripts): add a way to enforce driver kind and falcoctl enablement when installing Falco from packages and dialog is not present. [[#2773](https://github.com/falcosecurity/falco/pull/2773)] - [@vjjmiras](https://github.com/vjjmiras)
* new(falco): print system info when Falco starts [[#2927](https://github.com/falcosecurity/falco/pull/2927)] - [@Andreagit97](https://github.com/Andreagit97)
* new: driver selection in falco.yaml [[#2413](https://github.com/falcosecurity/falco/pull/2413)] - [@therealbobo](https://github.com/therealbobo)
* new(build): enable compilation on win32 and macOS. [[#2889](https://github.com/falcosecurity/falco/pull/2889)] - [@therealbobo](https://github.com/therealbobo)
* feat(userspace/falco): falco administrators can now configure the address on which the webserver listen using the new listen_address field in the webserver block of the `falco.yaml` file. [[#2890](https://github.com/falcosecurity/falco/pull/2890)] - [@sgaist](https://github.com/sgaist)
### Minor Changes
* update(userspace/falco): add `engine_version_semver` key in `/versions` endpoint [[#2899](https://github.com/falcosecurity/falco/pull/2899)] - [@loresuso](https://github.com/loresuso)
* update: default ruleset upgrade to version 3.0 [[#3034](https://github.com/falcosecurity/falco/pull/3034)] - [@leogr](https://github.com/leogr)
* update!(config): soft deprecation of drop stats counters in `syscall_event_drops` [[#3015](https://github.com/falcosecurity/falco/pull/3015)] - [@incertum](https://github.com/incertum)
* update(cmake): bumped falcoctl tool to v0.7.1. [[#3030](https://github.com/falcosecurity/falco/pull/3030)] - [@FedeDP](https://github.com/FedeDP)
* update(rule_loader): deprecate the `append` flag in Falco rules [[#2992](https://github.com/falcosecurity/falco/pull/2992)] - [@Andreagit97](https://github.com/Andreagit97)
* cleanup!(cmake): drop bundled plugins in Falco [[#2997](https://github.com/falcosecurity/falco/pull/2997)] - [@FedeDP](https://github.com/FedeDP)
* update(config): clarify deprecation notices + list all env vars [[#2988](https://github.com/falcosecurity/falco/pull/2988)] - [@incertum](https://github.com/incertum)
* update: now the `watch_config_files` config option monitors file/directory moving and deletion, too [[#2965](https://github.com/falcosecurity/falco/pull/2965)] - [@NitroCao](https://github.com/NitroCao)
* update(userspace): enhancements in rule description feature [[#2934](https://github.com/falcosecurity/falco/pull/2934)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update(userspace/falco): add libsinsp state metrics option [[#2883](https://github.com/falcosecurity/falco/pull/2883)] - [@incertum](https://github.com/incertum)
* update(doc): Add Thought Machine as adopters [[#2919](https://github.com/falcosecurity/falco/pull/2919)] - [@RichardoC](https://github.com/RichardoC)
* update(docs): add Wireshark/Logray as adopter [[#2867](https://github.com/falcosecurity/falco/pull/2867)] - [@geraldcombs](https://github.com/geraldcombs)
* update: engine_version in semver representation [[#2838](https://github.com/falcosecurity/falco/pull/2838)] - [@loresuso](https://github.com/loresuso)
* update(userspace/engine): modularize rule compiler, fix and enrich rule descriptions [[#2817](https://github.com/falcosecurity/falco/pull/2817)] - [@jasondellaluce](https://github.com/jasondellaluce)
### Bug Fixes
* fix(userspace/metric): minor fixes in new libsinsp state metrics handling [[#3033](https://github.com/falcosecurity/falco/pull/3033)] - [@incertum](https://github.com/incertum)
* fix(userspace/engine): avoid storing escaped strings in engine defs [[#3028](https://github.com/falcosecurity/falco/pull/3028)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(userspace/engine): cache latest rules compilation output [[#2900](https://github.com/falcosecurity/falco/pull/2900)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(userspace/engine): solve description of macro-only rules [[#2898](https://github.com/falcosecurity/falco/pull/2898)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(userspace/engine): fix memory leak [[#2877](https://github.com/falcosecurity/falco/pull/2877)] - [@therealbobo](https://github.com/therealbobo)
### Non user-facing changes
* fix: nlohmann_json lib include path [[#3032](https://github.com/falcosecurity/falco/pull/3032)] - [@federico-sysdig](https://github.com/federico-sysdig)
* chore: bump falco rules [[#3021](https://github.com/falcosecurity/falco/pull/3021)] - [@Andreagit97](https://github.com/Andreagit97)
* chore: bump Falco to libs 0.14.1 [[#3020](https://github.com/falcosecurity/falco/pull/3020)] - [@Andreagit97](https://github.com/Andreagit97)
* chore(build): remove outdated development libs [[#2946](https://github.com/falcosecurity/falco/pull/2946)] - [@federico-sysdig](https://github.com/federico-sysdig)
* chore(falco): bump Falco to `000d576` libs commit [[#2944](https://github.com/falcosecurity/falco/pull/2944)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(gha): update rpmsign [[#2856](https://github.com/falcosecurity/falco/pull/2856)] - [@LucaGuerra](https://github.com/LucaGuerra)
* build(deps): Bump submodules/falcosecurity-rules from `424b258` to `1221b9e` [[#3000](https://github.com/falcosecurity/falco/pull/3000)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `2ac430b` to `c39d31a` [[#3019](https://github.com/falcosecurity/falco/pull/3019)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* cleanup(falco.yaml): rename `none` in `nodriver` [[#3012](https://github.com/falcosecurity/falco/pull/3012)] - [@Andreagit97](https://github.com/Andreagit97)
* update(config): graduate outputs_queue to stable [[#3016](https://github.com/falcosecurity/falco/pull/3016)] - [@incertum](https://github.com/incertum)
* update(cmake): bump falcoctl to v0.7.0. [[#3009](https://github.com/falcosecurity/falco/pull/3009)] - [@FedeDP](https://github.com/FedeDP)
* build(deps): Bump submodules/falcosecurity-rules from `1221b9e` to `2ac430b` [[#3007](https://github.com/falcosecurity/falco/pull/3007)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore(ci): bumped rn2md to latest master. [[#3006](https://github.com/falcosecurity/falco/pull/3006)] - [@FedeDP](https://github.com/FedeDP)
* chore: bump Falco to latest libs [[#3002](https://github.com/falcosecurity/falco/pull/3002)] - [@Andreagit97](https://github.com/Andreagit97)
* chore: bump driver version [[#2998](https://github.com/falcosecurity/falco/pull/2998)] - [@Andreagit97](https://github.com/Andreagit97)
* Add addl source related methods [[#2939](https://github.com/falcosecurity/falco/pull/2939)] - [@mstemm](https://github.com/mstemm)
* build(deps): Bump submodules/falcosecurity-rules from `cd33bc3` to `424b258` [[#2993](https://github.com/falcosecurity/falco/pull/2993)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* cleanup(engine): clarify deprecation notice for engines [[#2987](https://github.com/falcosecurity/falco/pull/2987)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(cmake): bumped falcoctl to v0.7.0-rc1. [[#2983](https://github.com/falcosecurity/falco/pull/2983)] - [@FedeDP](https://github.com/FedeDP)
* chore(ci): revert #2961. [[#2984](https://github.com/falcosecurity/falco/pull/2984)] - [@FedeDP](https://github.com/FedeDP)
* build(deps): Bump submodules/falcosecurity-testing from `930170b` to `9b9630e` [[#2980](https://github.com/falcosecurity/falco/pull/2980)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore: bump Falco to latest libs [[#2977](https://github.com/falcosecurity/falco/pull/2977)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `262f569` to `cd33bc3` [[#2976](https://github.com/falcosecurity/falco/pull/2976)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* Allow enabling rules by ruleset id in addition to name [[#2920](https://github.com/falcosecurity/falco/pull/2920)] - [@mstemm](https://github.com/mstemm)
* chore(ci): enable aarch64 falco driver loader tests. [[#2961](https://github.com/falcosecurity/falco/pull/2961)] - [@FedeDP](https://github.com/FedeDP)
* chore(unit_tests): added more tests for yaml env vars expansion. [[#2972](https://github.com/falcosecurity/falco/pull/2972)] - [@FedeDP](https://github.com/FedeDP)
* chore(falco.yaml): use HOME env var for ebpf probe path. [[#2971](https://github.com/falcosecurity/falco/pull/2971)] - [@FedeDP](https://github.com/FedeDP)
* chore: bump falco to latest libs [[#2970](https://github.com/falcosecurity/falco/pull/2970)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `dd38952` to `262f569` [[#2969](https://github.com/falcosecurity/falco/pull/2969)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(readme): add actuated.dev badge [[#2967](https://github.com/falcosecurity/falco/pull/2967)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore(cmake,docker): bumped falcoctl to v0.7.0-beta5. [[#2968](https://github.com/falcosecurity/falco/pull/2968)] - [@FedeDP](https://github.com/FedeDP)
* build(deps): Bump submodules/falcosecurity-rules from `64e2adb` to `dd38952` [[#2959](https://github.com/falcosecurity/falco/pull/2959)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix(docker): small fixes in docker entrypoints for new driver loader. [[#2966](https://github.com/falcosecurity/falco/pull/2966)] - [@FedeDP](https://github.com/FedeDP)
* chore(build): allow usage of non-bundled nlohmann-json [[#2947](https://github.com/falcosecurity/falco/pull/2947)] - [@federico-sysdig](https://github.com/federico-sysdig)
* update(ci): enable actuated.dev [[#2945](https://github.com/falcosecurity/falco/pull/2945)] - [@LucaGuerra](https://github.com/LucaGuerra)
* cleanup: fix several warnings from a Clang build [[#2948](https://github.com/falcosecurity/falco/pull/2948)] - [@federico-sysdig](https://github.com/federico-sysdig)
* chore(docker/falco): add back some deps to falco docker image. [[#2932](https://github.com/falcosecurity/falco/pull/2932)] - [@FedeDP](https://github.com/FedeDP)
* build(deps): Bump submodules/falcosecurity-testing from `92c313f` to `5248e6d` [[#2937](https://github.com/falcosecurity/falco/pull/2937)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `e206c1a` to `8f0520f` [[#2904](https://github.com/falcosecurity/falco/pull/2904)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* cleanup(falco): remove decode_uri as it is no longer used [[#2933](https://github.com/falcosecurity/falco/pull/2933)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(engine): port decode_uri in falco engine [[#2912](https://github.com/falcosecurity/falco/pull/2912)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore(falco): update to libs on nov 28th [[#2929](https://github.com/falcosecurity/falco/pull/2929)] - [@LucaGuerra](https://github.com/LucaGuerra)
* cleanup(falco): remove `init` in the configuration constructor [[#2917](https://github.com/falcosecurity/falco/pull/2917)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `8f0520f` to `64e2adb` [[#2908](https://github.com/falcosecurity/falco/pull/2908)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* cleanup(userspace/engine): remove legacy k8saudit implementation [[#2913](https://github.com/falcosecurity/falco/pull/2913)] - [@jasondellaluce](https://github.com/jasondellaluce)
* fix(gha): disable branch protection rule trigger for scorecard [[#2911](https://github.com/falcosecurity/falco/pull/2911)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore(gha): set cosign-installer to v3.1.2 [[#2901](https://github.com/falcosecurity/falco/pull/2901)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(docs): sync changelog for 0.36.2. [[#2894](https://github.com/falcosecurity/falco/pull/2894)] - [@FedeDP](https://github.com/FedeDP)
* Run OpenSSF Scorecard in pipeline [[#2888](https://github.com/falcosecurity/falco/pull/2888)] - [@maxgio92](https://github.com/maxgio92)
* cleanup: replace banned.h with semgrep [[#2881](https://github.com/falcosecurity/falco/pull/2881)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore(gha): upgrade GitHub actions [[#2876](https://github.com/falcosecurity/falco/pull/2876)] - [@LucaGuerra](https://github.com/LucaGuerra)
* build(deps): Bump submodules/falcosecurity-rules from `a22d0d7` to `e206c1a` [[#2865](https://github.com/falcosecurity/falco/pull/2865)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `d119706` to `a22d0d7` [[#2860](https://github.com/falcosecurity/falco/pull/2860)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix(gha): use fedora instead of centos 7 for package publishing [[#2854](https://github.com/falcosecurity/falco/pull/2854)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore(gha): pin versions to hashes [[#2849](https://github.com/falcosecurity/falco/pull/2849)] - [@LucaGuerra](https://github.com/LucaGuerra)
* build(deps): Bump submodules/falcosecurity-rules from `c366d5b` to `d119706` [[#2847](https://github.com/falcosecurity/falco/pull/2847)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* new(ci): properly link libs and driver releases linked to a Falco release [[#2846](https://github.com/falcosecurity/falco/pull/2846)] - [@FedeDP](https://github.com/FedeDP)
* build(deps): Bump submodules/falcosecurity-rules from `7a7cf24` to `c366d5b` [[#2842](https://github.com/falcosecurity/falco/pull/2842)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `77ba57a` to `7a7cf24` [[#2836](https://github.com/falcosecurity/falco/pull/2836)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore(ci): bumped rn2md to latest master. [[#2844](https://github.com/falcosecurity/falco/pull/2844)] - [@FedeDP](https://github.com/FedeDP)
## v0.36.2
Released on 2023-10-27
NO CHANGES IN FALCO, ALL CHANGES IN LIBS.
## v0.36.1
Released on 2023-10-16
### Major Changes
### Minor Changes
* feat(userspace): remove experimental outputs queue recovery strategies [[#2863](https://github.com/falcosecurity/falco/pull/2863)] - [@incertum](https://github.com/incertum)
### Bug Fixes
* fix(userspace/falco): timer_delete() workaround due to bug in older GLIBC [[#2851](https://github.com/falcosecurity/falco/pull/2851)] - [@incertum](https://github.com/incertum)
## v0.36.0
Released on 2023-09-26
### Breaking Changes
- The default rules file that is shipped in the Falco image and/or can be downloaded via falcoctl as `falco-rules` is now a _stable_ rule file. This file **contains a much smaller number of rules** that are less noisy and have been vetted by the community. This serves as a much requested "starter" Falco rule set that covers many common use case. The rest of that file has been expanded and split into `falco-incubating-rules` and `falco-sandbox-rules`. For more information, see the [rules repository](https://github.com/falcosecurity/rules)
- The main `falcosecurity/falco` container image and its `falco-driver-loader` counterpart have been upgraded. Now they are able to compile the kernel module or classic eBPF probe for relatively newer version of the kernel (5.x and above) while we no longer ship toolchains to compile the kernel module for older versions in the default images. Downloading of prebuilt drivers and the modern eBPF will work exactly like before. The older image, meant for compatibility with older kernels (4.x and below), is currently retained as `falcosecurity/falco-driver-loader-legacy`.
- The Falco HTTP output no longer logs to stdout by default for performance reasons. You can set stdout logging preferences and restore the previous behavior with the configuration option `http_output.echo` in `falco.yaml`.
- The `--list-syscall-events` command line option has been replaced by `--list-events` which prints all supported system events (syscall, tracepoints, metaevents, internal plugin events) in addition to extra information about flags.
- The semantics of `proc.exepath` have changed. Now that field contains the executable path on disk even if the binary was launched from a symbolic link.
- The `-d` daemonize option has been removed.
- The `-p` option is now changed:
- when only `-pc` is set Falco will print `container_id=%container.id container_image=%container.image.repository container_image_tag=%container.image.tag container_name=%container.name`
- when `-pk` is set it will print as above, but with `k8s_ns=%k8s.ns.name k8s_pod_name=%k8s.pod.name` appended
### Major Changes
* new(falco-driver-loader): --source-only now prints the values as env vars [[#2353](https://github.com/falcosecurity/falco/pull/2353)] - [@steakunderscore](https://github.com/steakunderscore)
* new(docker): allow passing options to falco-driver-loader from the driver loader container [[#2781](https://github.com/falcosecurity/falco/pull/2781)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new(docker): add experimental falco-distroless image based on Wolfi [[#2768](https://github.com/falcosecurity/falco/pull/2768)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new: the legacy falco image is available as driver-loader-legacy [[#2718](https://github.com/falcosecurity/falco/pull/2718)] - [@LucaGuerra](https://github.com/LucaGuerra)
* new: added option to enable/disable echoing of server answer to stdout (disabled by default) when using HTTP output [[#2602](https://github.com/falcosecurity/falco/pull/2602)] - [@FedeDP](https://github.com/FedeDP)
* new: support systemctl reload for Falco services [[#2588](https://github.com/falcosecurity/falco/pull/2588)] - [@jabdr](https://github.com/jabdr)
* new(falco/config): add new configurations for http_output that allow mTLS [[#2633](https://github.com/falcosecurity/falco/pull/2633)] - [@annadorottya](https://github.com/annadorottya)
* new: allow falco to match multiple rules on same event [[#2705](https://github.com/falcosecurity/falco/pull/2705)] - [@loresuso](https://github.com/loresuso)
### Minor Changes
* update(cmake): bumped bundled falcoctl to 0.6.2 [[#2829](https://github.com/falcosecurity/falco/pull/2829)] - [@FedeDP](https://github.com/FedeDP)
* update(rules)!: major rule update to version 2.0.0 [[#2823](https://github.com/falcosecurity/falco/pull/2823)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(cmake): bumped plugins to latest stable versions [[#2820](https://github.com/falcosecurity/falco/pull/2820)] - [@FedeDP](https://github.com/FedeDP)
* update(cmake): bumped libs to 0.13.0-rc2 and driver to 6.0.1+driver [[#2806](https://github.com/falcosecurity/falco/pull/2806)] - [@FedeDP](https://github.com/FedeDP)
* update!: default substitution for `%container.info` is now equal `container_id=%container.id container_name=%container.name` [[#2793](https://github.com/falcosecurity/falco/pull/2793)] - [@leogr](https://github.com/leogr)
* update!: the --list-syscall-events flag is now called --list-events and lists all events [[#2771](https://github.com/falcosecurity/falco/pull/2771)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update!: the Falco base image is now based on Debian 12 with gcc 11-12 [[#2718](https://github.com/falcosecurity/falco/pull/2718)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update(docker): the Falco no-driver image is now based on Debian 12 [[#2782](https://github.com/falcosecurity/falco/pull/2782)] - [@LucaGuerra](https://github.com/LucaGuerra)
* feat(userspace)!: remove `-d` daemonize option [[#2677](https://github.com/falcosecurity/falco/pull/2677)] - [@incertum](https://github.com/incertum)
* build(deps): Bump submodules/falcosecurity-rules from 3f52480 to 0d0e333 [[#2693](https://github.com/falcosecurity/falco/pull/2693)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from 3f52480 to b42893a [[#2756](https://github.com/falcosecurity/falco/pull/2756)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from b42893a to 6ed73fe [[#2780](https://github.com/falcosecurity/falco/pull/2780)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake): bumped libs to 0.13.0-rc1 and driver to 6.0.0+driver. [[#2783](https://github.com/falcosecurity/falco/pull/2783)] - [@FedeDP](https://github.com/FedeDP)
* feat: support parsing of system environment variables in yaml [[#2562](https://github.com/falcosecurity/falco/pull/2562)] - [@therealdwright](https://github.com/therealdwright)
* feat(userspace)!: deprecate stats command args option in favor of metrics configs in falco.yaml [[#2739](https://github.com/falcosecurity/falco/pull/2739)] - [@incertum](https://github.com/incertum)
* update: upgrade `falcoctl` to version 0.6.0 [[#2764](https://github.com/falcosecurity/falco/pull/2764)] - [@leogr](https://github.com/leogr)
* cleanup: deprecate rate limiter mechanism [[#2762](https://github.com/falcosecurity/falco/pull/2762)] - [@Andreagit97](https://github.com/Andreagit97)
* cleanup(config): add more info [[#2758](https://github.com/falcosecurity/falco/pull/2758)] - [@incertum](https://github.com/incertum)
* update(userspace/engine): improve skip-if-unknown-filter YAML field [[#2749](https://github.com/falcosecurity/falco/pull/2749)] - [@jasondellaluce](https://github.com/jasondellaluce)
* chore: improved HTTP output performance [[#2602](https://github.com/falcosecurity/falco/pull/2602)] - [@FedeDP](https://github.com/FedeDP)
* update!: HTTP output will no more echo to stdout by default [[#2602](https://github.com/falcosecurity/falco/pull/2602)] - [@FedeDP](https://github.com/FedeDP)
* chore: remove b64 from falco dependencies [[#2746](https://github.com/falcosecurity/falco/pull/2746)] - [@Andreagit97](https://github.com/Andreagit97)
* update(cmake): support building libs and driver from forks [[#2747](https://github.com/falcosecurity/falco/pull/2747)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update: `-p` presets have been updated to reflect the new rules style guide [[#2737](https://github.com/falcosecurity/falco/pull/2737)] - [@leogr](https://github.com/leogr)
* feat: Allow specifying explicit kernel release and version for falco-driver-loader [[#2728](https://github.com/falcosecurity/falco/pull/2728)] - [@johananl](https://github.com/johananl)
* cleanup(config): assign Stable to `base_syscalls` config [[#2740](https://github.com/falcosecurity/falco/pull/2740)] - [@incertum](https://github.com/incertum)
* update : support build for wasm [[#2663](https://github.com/falcosecurity/falco/pull/2663)] - [@Rohith-Raju](https://github.com/Rohith-Raju)
* docs(config.yaml): fix wrong severity levels for sinsp logger [[#2736](https://github.com/falcosecurity/falco/pull/2736)] - [@Andreagit97](https://github.com/Andreagit97)
* update(cmake): bump libs and driver to 0.12.0 [[#2721](https://github.com/falcosecurity/falco/pull/2721)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update(docker): remove experimental image based on RedHat UBI [[#2720](https://github.com/falcosecurity/falco/pull/2720)] - [@leogr](https://github.com/leogr)
### Bug Fixes
* fix(outputs): expose queue_capacity_outputs config for memory control [[#2711](https://github.com/falcosecurity/falco/pull/2711)] - [@incertum](https://github.com/incertum)
* fix(userspace/falco): cleanup metrics timer upon leaving. [[#2759](https://github.com/falcosecurity/falco/pull/2759)] - [@FedeDP](https://github.com/FedeDP)
* fix: restore Falco MINIMAL_BUILD and deprecate `userspace` option [[#2761](https://github.com/falcosecurity/falco/pull/2761)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(userspace/engine): support appending to unknown sources [[#2753](https://github.com/falcosecurity/falco/pull/2753)] - [@jasondellaluce](https://github.com/jasondellaluce)
### Non user-facing changes
* build(deps): Bump submodules/falcosecurity-rules from `69c9be8` to `77ba57a` [[#2833](https://github.com/falcosecurity/falco/pull/2833)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* chore: bump submodule testing to 62edc65 [[#2831](https://github.com/falcosecurity/falco/pull/2831)] - [@Andreagit97](https://github.com/Andreagit97)
* update(gha): add version for rn2md [[#2830](https://github.com/falcosecurity/falco/pull/2830)] - [@LucaGuerra](https://github.com/LucaGuerra)
* chore: automatically attach release author to release body. [[#2828](https://github.com/falcosecurity/falco/pull/2828)] - [@FedeDP](https://github.com/FedeDP)
* new(ci): autogenerate release body. [[#2812](https://github.com/falcosecurity/falco/pull/2812)] - [@FedeDP](https://github.com/FedeDP)
* fix(dockerfile): remove useless CMD [[#2824](https://github.com/falcosecurity/falco/pull/2824)] - [@Andreagit97](https://github.com/Andreagit97)
* chore: bump to the latest libs [[#2822](https://github.com/falcosecurity/falco/pull/2822)] - [@Andreagit97](https://github.com/Andreagit97)
* update: add SPDX license identifier [[#2809](https://github.com/falcosecurity/falco/pull/2809)] - [@leogr](https://github.com/leogr)
* chore: bump to latest libs [[#2815](https://github.com/falcosecurity/falco/pull/2815)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `ee5fb38` to `bea364e` [[#2814](https://github.com/falcosecurity/falco/pull/2814)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix(build): set the right bucket and version for driver legacy [[#2800](https://github.com/falcosecurity/falco/pull/2800)] - [@LucaGuerra](https://github.com/LucaGuerra)
* build(deps): Bump submodules/falcosecurity-rules from `43580b4` to `ee5fb38` [[#2810](https://github.com/falcosecurity/falco/pull/2810)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* cleanup(userspace): thrown exceptions and avoid multiple logs [[#2803](https://github.com/falcosecurity/falco/pull/2803)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `c6e01fa` to `43580b4` [[#2801](https://github.com/falcosecurity/falco/pull/2801)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-testing from `76d1743` to `30c3643` [[#2802](https://github.com/falcosecurity/falco/pull/2802)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix(userspace/falco): clearing full output queue [[#2798](https://github.com/falcosecurity/falco/pull/2798)] - [@jasondellaluce](https://github.com/jasondellaluce)
* update(docs): add driver-loader-legacy to readme and fix bad c&p [[#2799](https://github.com/falcosecurity/falco/pull/2799)] - [@LucaGuerra](https://github.com/LucaGuerra)
* build(deps): Bump submodules/falcosecurity-rules from `d31dbc2` to `c6e01fa` [[#2797](https://github.com/falcosecurity/falco/pull/2797)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* docs: add LICENSE file [[#2796](https://github.com/falcosecurity/falco/pull/2796)] - [@leogr](https://github.com/leogr)
* build(deps): Bump submodules/falcosecurity-rules from `b6372d2` to `d31dbc2` [[#2794](https://github.com/falcosecurity/falco/pull/2794)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix(stats): always initialize m_output field [[#2789](https://github.com/falcosecurity/falco/pull/2789)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `6ed73fe` to `b6372d2` [[#2786](https://github.com/falcosecurity/falco/pull/2786)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* update(cmake/modules): bump rules to falco-rules-2.0.0-rc1 [[#2775](https://github.com/falcosecurity/falco/pull/2775)] - [@leogr](https://github.com/leogr)
* update(OWNERS): add LucaGuerra to owners [[#2650](https://github.com/falcosecurity/falco/pull/2650)] - [@LucaGuerra](https://github.com/LucaGuerra)
* build(deps): Bump submodules/falcosecurity-rules from `9126bef` to `0328c59` [[#2709](https://github.com/falcosecurity/falco/pull/2709)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `0d0e333` to `64ce419` [[#2731](https://github.com/falcosecurity/falco/pull/2731)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `3ceea88` to `40a9817` [[#2745](https://github.com/falcosecurity/falco/pull/2745)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* docs(README.md): correct URL [[#2772](https://github.com/falcosecurity/falco/pull/2772)] - [@vjjmiras](https://github.com/vjjmiras)
* #2393 Document why Falco is written in C++ rather than anything else [[#2410](https://github.com/falcosecurity/falco/pull/2410)] - [@RichardoC](https://github.com/RichardoC)
* chore: bump Falco to latest libs [[#2769](https://github.com/falcosecurity/falco/pull/2769)] - [@Andreagit97](https://github.com/Andreagit97)
* ci: disable falco-driver-loader tests on ARM64 [[#2770](https://github.com/falcosecurity/falco/pull/2770)] - [@Andreagit97](https://github.com/Andreagit97)
* update(userspace/falco): revised CLI help messages [[#2755](https://github.com/falcosecurity/falco/pull/2755)] - [@leogr](https://github.com/leogr)
* fix(engine): fix reorder warning for m_watch_config_files / m_rule_matching [[#2767](https://github.com/falcosecurity/falco/pull/2767)] - [@LucaGuerra](https://github.com/LucaGuerra)
* update: introduce new stats updated to the latest libs version [[#2766](https://github.com/falcosecurity/falco/pull/2766)] - [@Andreagit97](https://github.com/Andreagit97)
* ci: support tests on amazon-linux [[#2765](https://github.com/falcosecurity/falco/pull/2765)] - [@Andreagit97](https://github.com/Andreagit97)
* chore: bump Falco to latest libs master [[#2754](https://github.com/falcosecurity/falco/pull/2754)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-testing from `b39c807` to `9110022` [[#2760](https://github.com/falcosecurity/falco/pull/2760)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* fix: fix "ebpf_enabled" output stat [[#2751](https://github.com/falcosecurity/falco/pull/2751)] - [@Andreagit97](https://github.com/Andreagit97)
* fix(userspace/engine): support both old and new gcc + std::move [[#2748](https://github.com/falcosecurity/falco/pull/2748)] - [@jasondellaluce](https://github.com/jasondellaluce)
* cleanup: turn some warnings into errors [[#2744](https://github.com/falcosecurity/falco/pull/2744)] - [@Andreagit97](https://github.com/Andreagit97)
* update(ci): minimize retention days for build-only CI artifacts [[#2743](https://github.com/falcosecurity/falco/pull/2743)] - [@jasondellaluce](https://github.com/jasondellaluce)
* cleanup: remove unused `--pidfile` option from systemd units [[#2742](https://github.com/falcosecurity/falco/pull/2742)] - [@Andreagit97](https://github.com/Andreagit97)
* build(deps): Bump submodules/falcosecurity-rules from `bf1639a` to `3ceea88` [[#2741](https://github.com/falcosecurity/falco/pull/2741)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* build(deps): Bump submodules/falcosecurity-rules from `64ce419` to `bf1639a` [[#2738](https://github.com/falcosecurity/falco/pull/2738)] - [@dependabot[bot]](https://github.com/apps/dependabot)
* Relocate tools on Flatcar in BPF mode [[#2729](https://github.com/falcosecurity/falco/pull/2729)] - [@johananl](https://github.com/johananl)
* build: update versioning with cmake [[#2727](https://github.com/falcosecurity/falco/pull/2727)] - [@leogr](https://github.com/leogr)
* update(userspace/engine): make rule_matching strategy stateless [[#2726](https://github.com/falcosecurity/falco/pull/2726)] - [@loresuso](https://github.com/loresuso)
* chore: bump Falco to latest libs version [[#2722](https://github.com/falcosecurity/falco/pull/2722)] - [@Andreagit97](https://github.com/Andreagit97)
* update: enforce bumping engine version whenever appropriate [[#2719](https://github.com/falcosecurity/falco/pull/2719)] - [@jasondellaluce](https://github.com/jasondellaluce)
## v0.35.1
Released on 2023-06-29
@@ -1261,7 +959,7 @@ Released on 2021-01-18
### Minor Changes
* build: bump b64 to v2.0.0.1 [[#1441](https://github.com/falcosecurity/falco/pull/1441)] - [@fntlnz](https://github.com/fntlnz)
* rules(macro container_started): reuse `spawned_process` macro inside `container_started` macro [[#1449](https://github.com/falcosecurity/falco/pull/1449)] - [@leodido](https://github.com/leodido)
* rules(macro container_started): re-use `spawned_process` macro inside `container_started` macro [[#1449](https://github.com/falcosecurity/falco/pull/1449)] - [@leodido](https://github.com/leodido)
* docs: reach out documentation [[#1472](https://github.com/falcosecurity/falco/pull/1472)] - [@fntlnz](https://github.com/fntlnz)
* docs: Broken outputs.proto link [[#1493](https://github.com/falcosecurity/falco/pull/1493)] - [@deepskyblue86](https://github.com/deepskyblue86)
* docs(README.md): correct broken links [[#1506](https://github.com/falcosecurity/falco/pull/1506)] - [@leogr](https://github.com/leogr)

View File

@@ -1,4 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
@@ -16,17 +15,12 @@ cmake_minimum_required(VERSION 3.5.1)
project(falco)
option(USE_BUNDLED_DEPS "Bundle hard to find dependencies into the Falco binary" OFF)
option(USE_DYNAMIC_LIBELF "Dynamically link libelf" ON)
option(BUILD_WARNINGS_AS_ERRORS "Enable building with -Wextra -Werror flags" OFF)
option(MINIMAL_BUILD "Build a minimal version of Falco, containing only the engine and basic input/output (EXPERIMENTAL)" OFF)
option(MUSL_OPTIMIZED_BUILD "Enable if you want a musl optimized build" OFF)
option(BUILD_FALCO_UNIT_TESTS "Build falco unit tests" OFF)
if(WIN32)
set(CPACK_GENERATOR "NSIS") # this needs NSIS installed, and available
elseif (APPLE)
set(CPACK_GENERATOR "DragNDrop")
elseif(EMSCRIPTEN)
if(EMSCRIPTEN)
set(USE_BUNDLED_DEPS ON CACHE BOOL "" FORCE)
set(BUILD_DRIVER OFF CACHE BOOL "" FORCE)
set(ENABLE_DKMS OFF CACHE BOOL "" FORCE)
@@ -58,6 +52,9 @@ if (${EP_UPDATE_DISCONNECTED})
PROPERTY EP_UPDATE_DISCONNECTED TRUE)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
# Elapsed time
# set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time") # TODO(fntlnz, leodido): add a flag to enable this
@@ -85,7 +82,56 @@ else()
set(FALCO_TARGET_ARCH ${CMAKE_SYSTEM_PROCESSOR})
endif()
include(CompilerFlags)
if(NOT FALCO_EXTRA_DEBUG_FLAGS)
set(FALCO_EXTRA_DEBUG_FLAGS "-D_DEBUG")
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
if(CMAKE_BUILD_TYPE STREQUAL "debug")
set(KBUILD_FLAGS "${FALCO_EXTRA_DEBUG_FLAGS} ${FALCO_EXTRA_FEATURE_FLAGS}")
else()
set(CMAKE_BUILD_TYPE "release")
set(KBUILD_FLAGS "${FALCO_EXTRA_FEATURE_FLAGS}")
add_definitions(-DBUILD_TYPE_RELEASE)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if(MINIMAL_BUILD)
set(MINIMAL_BUILD_FLAGS "-DMINIMAL_BUILD")
endif()
if(MUSL_OPTIMIZED_BUILD)
set(MUSL_FLAGS "-static -Os -fPIE -pie")
add_definitions(-DMUSL_OPTIMIZED)
endif()
# explicitly set hardening flags
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(FALCO_SECURITY_FLAGS "")
if(NOT EMSCRIPTEN)
set(FALCO_SECURITY_FLAGS "${FALCO_SECURITY_FLAGS} -Wl,-z,relro,-z,now -fstack-protector-strong")
endif()
if(CMAKE_BUILD_TYPE STREQUAL "release")
set(FALCO_SECURITY_FLAGS "${FALCO_SECURITY_FLAGS} -D_FORTIFY_SOURCE=2")
endif()
set(CMAKE_COMMON_FLAGS "${FALCO_SECURITY_FLAGS} -Wall -ggdb ${FALCO_EXTRA_FEATURE_FLAGS} ${MINIMAL_BUILD_FLAGS} ${MUSL_FLAGS}")
if(BUILD_WARNINGS_AS_ERRORS)
set(CMAKE_SUPPRESSED_WARNINGS
"-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_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wextra -Werror ${CMAKE_SUPPRESSED_WARNINGS}")
endif()
set(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS "-std=c++17 ${CMAKE_COMMON_FLAGS} -Wno-class-memaccess")
set(CMAKE_C_FLAGS_DEBUG "${FALCO_EXTRA_DEBUG_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${FALCO_EXTRA_DEBUG_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
set(PACKAGE_NAME "falco")
set(DRIVER_NAME "falco")
@@ -117,6 +163,9 @@ include(falcosecurity-libs)
# compute FALCO_VERSION (depends on libs)
include(falco-version)
# jq
include(jq)
# nlohmann-json
include(njson)
@@ -142,8 +191,8 @@ if (NOT EMSCRIPTEN)
include(tbb)
endif()
include(zlib)
if (NOT MINIMAL_BUILD)
include(zlib)
if (NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN)
include(cares)
include(protobuf)
@@ -153,16 +202,7 @@ if (NOT MINIMAL_BUILD)
endif()
# Installation
if(WIN32)
set(FALCO_INSTALL_CONF_FILE "%PROGRAMFILES%/${PACKAGE_NAME}-${FALCO_VERSION}/etc/falco/falco.yaml")
install(FILES falco.yaml DESTINATION etc/falco/ COMPONENT "${FALCO_COMPONENT_NAME}")
elseif(APPLE)
set(FALCO_INSTALL_CONF_FILE "/etc/falco/falco.yaml")
install(FILES falco.yaml DESTINATION etc/falco/ COMPONENT "${FALCO_COMPONENT_NAME}")
else()
set(FALCO_INSTALL_CONF_FILE "/etc/falco/falco.yaml")
install(FILES falco.yaml DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
endif()
install(FILES falco.yaml DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
if(NOT MINIMAL_BUILD)
# Coverage
@@ -181,6 +221,7 @@ include(static-analysis)
# Shared build variables
set(FALCO_SINSP_LIBRARY sinsp)
set(FALCO_SHARE_DIR share/falco)
set(FALCO_PLUGINS_DIR ${FALCO_SHARE_DIR}/plugins)
set(FALCO_ABSOLUTE_SHARE_DIR "${CMAKE_INSTALL_PREFIX}/${FALCO_SHARE_DIR}")
set(FALCO_BIN_DIR bin)
@@ -189,6 +230,7 @@ add_subdirectory(userspace/engine)
add_subdirectory(userspace/falco)
if(NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN AND NOT MUSL_OPTIMIZED_BUILD)
include(plugins)
include(falcoctl)
endif()

202
LICENSE
View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2019 The Falco Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

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 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 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 Best Practices](https://img.shields.io/cii/summary/2317?label=OpenSSF%20Best%20Practices&style=for-the-badge)](https://bestpractices.coreinfrastructure.org/projects/2317)
[![Falco](https://falco.org/img/brand/falco-horizontal-color.svg)](https://falco.org)
@@ -46,7 +46,8 @@ Considerations and guidance for Falco adopters:
## How to Contribute
Please refer to the [contributing guide](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) and the [code of conduct](https://github.com/falcosecurity/evolution/blob/main/CODE_OF_CONDUCT.md) for more information on how to contribute.
Please refer to the [contributing guide](https://github.com/falcosecurity/.github/blob/main/CONTRIBUTING.md) and the [code of conduct](https://github.com/falcosecurity/evolution/CODE_OF_CONDUCT.md) for more information on how to contribute.
## Join the Community

View File

@@ -146,8 +146,46 @@ 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
- Do NOT fill body, since it will be autogenerated by the [github release workflow](.github/workflows/release.yaml)
- Publish the release!
- Use the following template to fill the release description:
```
<!-- Substitute M.m.p with the current release version -->
| Packages | Download |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| rpm-x86_64 | [![rpm](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpm/falco-M.m.p-x86_64.rpm) |
| deb-x86_64 | [![deb](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/deb/stable/falco-M.m.p-x86_64.deb) |
| tgz-x86_64 | [![tgz](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/bin/x86_64/falco-M.m.p-x86_64.tar.gz) |
| rpm-aarch64 | [![rpm](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/rpm/falco-M.m.p-aarch64.rpm) |
| deb-aarch64 | [![deb](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/deb/stable/falco-M.m.p-aarch64.deb) |
| tgz-aarch64 | [![tgz](https://img.shields.io/badge/Falco-M.m.p-%2300aec7?style=flat-square)](https://download.falco.org/packages/bin/aarch64/falco-M.m.p-aarch64.tar.gz) |
| Images |
| --------------------------------------------------------------------------- |
| `docker pull docker.io/falcosecurity/falco:M.m.p` |
| `docker pull public.ecr.aws/falcosecurity/falco:M.m.p` |
| `docker pull docker.io/falcosecurity/falco-driver-loader:M.m.p` |
| `docker pull docker.io/falcosecurity/falco-no-driver:M.m.p` |
<changelog>
<!-- Substitute <changelog> with the one generated by [rn2md](https://github.com/leodido/rn2md) -->
### Statistics
| Merged PRs | Number |
| --------------- | ------ |
| Not user-facing | x |
| Release note | x |
| Total | x |
<!-- Calculate stats and fill the above table -->
#### Release Manager <github handle>
<!-- Substitute GitHub handle with the release manager's one -->
```
- Finally, publish the release!
- The release pipeline will start automatically upon publication and all packages and container images will be uploaded to the stable repositories.
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.

View File

@@ -1,17 +1,3 @@
# 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.
#
if(CPACK_GENERATOR MATCHES "DEB" OR CPACK_GENERATOR MATCHES "RPM")
list(APPEND CPACK_INSTALL_COMMANDS "mkdir -p _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")
list(APPEND CPACK_INSTALL_COMMANDS "cp scripts/systemd/falco-kmod-inject.service _CPack_Packages/${CPACK_TOPLEVEL_TAG}/${CPACK_GENERATOR}/${CPACK_PACKAGE_FILE_NAME}/usr/lib/systemd/system")

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
@@ -30,10 +29,6 @@ else()
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-${CMAKE_SYSTEM_PROCESSOR}")
endif()
if(WIN32)
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}")
endif()
# Built packages will include only the following components
set(CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_CURRENT_BINARY_DIR};${FALCO_COMPONENT_NAME};${FALCO_COMPONENT_NAME};/"
@@ -44,6 +39,11 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux") # only Linux has drivers
"${CMAKE_CURRENT_BINARY_DIR};${DRIVER_COMPONENT_NAME};${DRIVER_COMPONENT_NAME};/")
endif()
if(NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN AND NOT MUSL_OPTIMIZED_BUILD) # static builds do not have plugins
list(APPEND CPACK_INSTALL_CMAKE_PROJECTS
"${CMAKE_CURRENT_BINARY_DIR};${PLUGINS_COMPONENT_NAME};${PLUGINS_COMPONENT_NAME};/")
endif()
if(NOT CPACK_GENERATOR)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
set(CPACK_GENERATOR DEB RPM TGZ)

View File

@@ -1,101 +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.
#
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
if(NOT FALCO_EXTRA_DEBUG_FLAGS)
set(FALCO_EXTRA_DEBUG_FLAGS "-D_DEBUG")
endif()
string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE)
if(CMAKE_BUILD_TYPE STREQUAL "debug")
set(KBUILD_FLAGS "${FALCO_EXTRA_DEBUG_FLAGS} ${FALCO_EXTRA_FEATURE_FLAGS}")
else()
set(CMAKE_BUILD_TYPE "release")
set(KBUILD_FLAGS "${FALCO_EXTRA_FEATURE_FLAGS}")
add_definitions(-DBUILD_TYPE_RELEASE)
endif()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
if(MINIMAL_BUILD)
set(MINIMAL_BUILD_FLAGS "-DMINIMAL_BUILD")
endif()
if(MUSL_OPTIMIZED_BUILD)
set(MUSL_FLAGS "-static -Os -fPIE -pie")
add_definitions(-DMUSL_OPTIMIZED)
endif()
# explicitly set hardening flags
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(FALCO_SECURITY_FLAGS "")
if(LINUX)
set(FALCO_SECURITY_FLAGS "${FALCO_SECURITY_FLAGS} -Wl,-z,relro,-z,now -fstack-protector-strong")
endif()
if(NOT MSVC)
if(CMAKE_BUILD_TYPE STREQUAL "release")
set(FALCO_SECURITY_FLAGS "${FALCO_SECURITY_FLAGS} -D_FORTIFY_SOURCE=2")
endif()
set(CMAKE_COMMON_FLAGS "${FALCO_SECURITY_FLAGS} -Wall -ggdb ${FALCO_EXTRA_FEATURE_FLAGS} ${MINIMAL_BUILD_FLAGS} ${MUSL_FLAGS}")
if(BUILD_WARNINGS_AS_ERRORS)
set(CMAKE_SUPPRESSED_WARNINGS
"-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_COMMON_FLAGS "${CMAKE_COMMON_FLAGS} -Wextra -Werror ${CMAKE_SUPPRESSED_WARNINGS}")
endif()
set(CMAKE_C_FLAGS "${CMAKE_COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS "-std=c++17 ${CMAKE_COMMON_FLAGS} -Wno-class-memaccess")
set(CMAKE_C_FLAGS_DEBUG "${FALCO_EXTRA_DEBUG_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${FALCO_EXTRA_DEBUG_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -fno-strict-aliasing -DNDEBUG")
else() # MSVC
set(MINIMAL_BUILD ON)
# The WIN32_LEAN_AND_MEAN define avoids possible macro pollution
# when a libsinsp consumer includes the windows.h header.
# See: https://stackoverflow.com/a/28380820
add_compile_definitions(
_HAS_STD_BYTE=0
_CRT_SECURE_NO_WARNINGS
WIN32
MINIMAL_BUILD
WIN32_LEAN_AND_MEAN
)
set(FALCOSECURITY_LIBS_COMMON_FLAGS "/EHsc /W3 /Zi /std:c++17")
set(FALCOSECURITY_LIBS_DEBUG_FLAGS "/MTd /Od")
set(FALCOSECURITY_LIBS_RELEASE_FLAGS "/MT")
set(CMAKE_C_FLAGS "${FALCOSECURITY_LIBS_COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS "${FALCOSECURITY_LIBS_COMMON_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${FALCOSECURITY_LIBS_DEBUG_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "${FALCOSECURITY_LIBS_DEBUG_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "${FALCOSECURITY_LIBS_RELEASE_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${FALCOSECURITY_LIBS_RELEASE_FLAGS}")
endif()

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
@@ -34,8 +33,8 @@ else()
# In case you want to test against another driver version (or branch, or commit) just pass the variable -
# ie., `cmake -DDRIVER_VERSION=dev ..`
if(NOT DRIVER_VERSION)
set(DRIVER_VERSION "7.0.0+driver")
set(DRIVER_CHECKSUM "SHA256=9f2a0f14827c0d9d1c3d1abe45b8f074dea531ebeca9859363a92f0d2475757e")
set(DRIVER_VERSION "6301c01b9279c3f4981df24b3e8e0d97c18f76e8")
set(DRIVER_CHECKSUM "SHA256=cc5c51b4a01cf83d36c3af0670a36b2c8b55f3baebc03736725dc6425898d018")
endif()
# cd /path/to/build && cmake /path/to/source

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,4 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
@@ -16,14 +15,14 @@ include(ExternalProject)
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} FALCOCTL_SYSTEM_NAME)
set(FALCOCTL_VERSION "0.7.2")
set(FALCOCTL_VERSION "0.6.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(FALCOCTL_SYSTEM_PROC_GO "amd64")
set(FALCOCTL_HASH "abbbef2beefceb3d518a638fbad220ca6002840d33a20a7f1de9b358c4dbef45")
set(FALCOCTL_HASH "b81c36449b525e1de871288741beeadead021ac133d9b306f0636be1befe58a5")
else() # aarch64
set(FALCOCTL_SYSTEM_PROC_GO "arm64")
set(FALCOCTL_HASH "8dafef99948355febfa311bb940f8c714af631a249f4ae05ffd7d4c5f181e2c4")
set(FALCOCTL_HASH "6e99fd765f67cdd46fa8c5b2969e97497856d2e615698ced04046c8898187b18")
endif()
ExternalProject_Add(

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at

View File

@@ -1,4 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
@@ -26,17 +25,17 @@ if(FALCOSECURITY_LIBS_SOURCE_DIR)
else()
# FALCOSECURITY_LIBS_REPO accepts a repository name (<org name>/<repo name>) alternative to the falcosecurity/libs repository.
# In case you want to test against a fork of falcosecurity/libs just pass the variable -
# ie., `cmake -DFALCOSECURITY_LIBS_REPO=<your-gh-handle>/libs ..`
# ie., `cmake -DFALCOSECURITY_LIBS_REPO=<your-gh-handle>/libs ..`
if (NOT FALCOSECURITY_LIBS_REPO)
set(FALCOSECURITY_LIBS_REPO "falcosecurity/libs")
endif()
# FALCOSECURITY_LIBS_VERSION accepts a git reference (branch name, commit hash, or tag) to the falcosecurity/libs repository.
# In case you want to test against another falcosecurity/libs version (or branch, or commit) just pass the variable -
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
# ie., `cmake -DFALCOSECURITY_LIBS_VERSION=dev ..`
if(NOT FALCOSECURITY_LIBS_VERSION)
set(FALCOSECURITY_LIBS_VERSION "0.14.3")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=da3d2df24947f1f3c96c3aa8b8999dde691c5ba8bb15beba4486b4c7d6b9d7f9")
set(FALCOSECURITY_LIBS_VERSION "6301c01b9279c3f4981df24b3e8e0d97c18f76e8")
set(FALCOSECURITY_LIBS_CHECKSUM "SHA256=cc5c51b4a01cf83d36c3af0670a36b2c8b55f3baebc03736725dc6425898d018")
endif()
# cd /path/to/build && cmake /path/to/source
@@ -84,15 +83,10 @@ set(CREATE_TEST_TARGETS OFF CACHE BOOL "")
set(BUILD_LIBSCAP_EXAMPLES OFF CACHE BOOL "")
set(USE_BUNDLED_TBB ON CACHE BOOL "")
set(USE_BUNDLED_B64 ON CACHE BOOL "")
set(USE_BUNDLED_JSONCPP ON CACHE BOOL "")
set(USE_BUNDLED_NLOHMANN_JSON ON CACHE BOOL "")
set(USE_BUNDLED_VALIJSON ON CACHE BOOL "")
set(USE_BUNDLED_RE2 ON CACHE BOOL "")
set(USE_BUNDLED_UTHASH ON CACHE BOOL "")
if(USE_DYNAMIC_LIBELF)
set(USE_BUNDLED_LIBELF OFF CACHE BOOL "")
set(USE_SHARED_LIBELF ON CACHE BOOL "")
endif()
list(APPEND CMAKE_MODULE_PATH "${FALCOSECURITY_LIBS_SOURCE_DIR}/cmake/modules")
@@ -100,15 +94,12 @@ include(CheckSymbolExists)
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
if(HAVE_STRLCPY)
message(STATUS "Existing strlcpy and strlcat found, will *not* use local definition by setting -DHAVE_STRLCPY and -DHAVE_STRLCAT.")
message(STATUS "Existing strlcpy found, will *not* use local definition by setting -DHAVE_STRLCPY.")
add_definitions(-DHAVE_STRLCPY)
add_definitions(-DHAVE_STRLCAT)
else()
message(STATUS "No strlcpy and strlcat found, will use local definition")
message(STATUS "No strlcpy found, will use local definition")
endif()
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
include(driver)
endif()
include(driver)
include(libscap)
include(libsinsp)

View File

@@ -0,0 +1,27 @@
#
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
set(LIBYAML_SRC "${PROJECT_BINARY_DIR}/libyaml-prefix/src/libyaml")
set(LIBYAML_INSTALL_DIR "${LIBYAML_SRC}/target")
message(STATUS "Using bundled libyaml in '${LIBYAML_SRC}'")
set(LIBYAML_LIB "${LIBYAML_SRC}/src/.libs/libyaml.a")
externalproject_add(
libyaml
URL "https://github.com/yaml/libyaml/releases/download/0.2.5/yaml-0.2.5.tar.gz"
URL_HASH "SHA256=c642ae9b75fee120b2d96c712538bd2cf283228d2337df2cf2988e3c02678ef4"
CONFIGURE_COMMAND ./configure --prefix=${LIBYAML_INSTALL_DIR} CFLAGS=-fPIC CPPFLAGS=-fPIC --enable-static=true --enable-shared=false
BUILD_COMMAND ${CMD_MAKE}
BUILD_IN_SOURCE 1
BUILD_BYPRODUCTS ${LIBYAML_LIB}
INSTALL_COMMAND ${CMD_MAKE} install
)

View File

@@ -1,4 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
@@ -12,16 +11,24 @@
# specific language governing permissions and limitations under the License.
#
if(USE_BUNDLED_NLOHMANN_JSON)
ExternalProject_Add(njson
#
# nlohmann-json
#
if(NJSON_INCLUDE)
# Adding the custom target we can use it with `add_dependencies()`
if(NOT TARGET njson)
add_custom_target(njson)
endif()
else()
# We always use the bundled version
set(NJSON_SRC "${PROJECT_BINARY_DIR}/njson-prefix/src/njson")
set(NJSON_INCLUDE "${NJSON_SRC}/single_include")
ExternalProject_Add(
njson
URL "https://github.com/nlohmann/json/archive/v3.3.0.tar.gz"
URL_HASH "SHA256=2fd1d207b4669a7843296c41d3b6ac5b23d00dec48dba507ba051d14564aa801"
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${PROJECT_BINARY_DIR}/njson-prefix -DJSON_BuildTests=OFF -DBUILD_TESTING=OFF
)
set(nlohmann_json_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/njson-prefix/include)
else()
find_package(nlohmann_json CONFIG REQUIRED)
get_target_property(nlohmann_json_INCLUDE_DIRS nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)
add_custom_target(njson)
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
message(STATUS "Using bundled nlohmann-json in '${NJSON_SRC}'")
endif()

View File

@@ -0,0 +1,97 @@
#
# Copyright (C) 2023 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
#
include(ExternalProject)
# 'stable' or 'dev'
set(PLUGINS_DOWNLOAD_BUCKET "stable")
string(TOLOWER ${CMAKE_HOST_SYSTEM_NAME} PLUGINS_SYSTEM_NAME)
if(NOT DEFINED PLUGINS_COMPONENT_NAME)
set(PLUGINS_COMPONENT_NAME "${CMAKE_PROJECT_NAME}-plugins")
endif()
# k8saudit
set(PLUGIN_K8S_AUDIT_VERSION "0.6.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_K8S_AUDIT_HASH "560e8f8dc8fd169e524d95462d65b5227415a7a157442e82383c7d9f456ce58f")
else() # aarch64
set(PLUGIN_K8S_AUDIT_HASH "e4757af1bac42b21c5937340790841dedc3805759050a6ffb22d1761e1dd1d31")
endif()
ExternalProject_Add(
k8saudit-plugin
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/k8saudit-${PLUGIN_K8S_AUDIT_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=${PLUGIN_K8S_AUDIT_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/k8saudit-plugin-prefix/src/k8saudit-plugin/libk8saudit.so" DESTINATION "${FALCO_PLUGINS_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
ExternalProject_Add(
k8saudit-rules
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/k8saudit-rules-${PLUGIN_K8S_AUDIT_VERSION}.tar.gz"
URL_HASH "SHA256=44cee2fb88312d889213e1dbe1b9902d0a3f5c594cce73b2cac8e54fb51321b7"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/k8saudit-rules-prefix/src/k8saudit-rules/k8s_audit_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
# cloudtrail
set(PLUGIN_CLOUDTRAIL_VERSION "0.8.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_CLOUDTRAIL_HASH "13ba77602c0859936f6e3b00f93bd218c463300c6a797b694a0d5aeecde13976")
else() # aarch64
set(PLUGIN_CLOUDTRAIL_HASH "a01730738e9d5769f69957a204c8afe528b059e9a22f59792dfc65e19d6a43db")
endif()
ExternalProject_Add(
cloudtrail-plugin
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/cloudtrail-${PLUGIN_CLOUDTRAIL_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=${PLUGIN_CLOUDTRAIL_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-plugin-prefix/src/cloudtrail-plugin/libcloudtrail.so" DESTINATION "${FALCO_PLUGINS_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
ExternalProject_Add(
cloudtrail-rules
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/cloudtrail-rules-${PLUGIN_CLOUDTRAIL_VERSION}.tar.gz"
URL_HASH "SHA256=27f2fc0a74d39476ad968a61318dec65a82b109c4a462b9fa22be45425ddaaad"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/cloudtrail-rules-prefix/src/cloudtrail-rules/aws_cloudtrail_rules.yaml" DESTINATION "${FALCO_ETC_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")
# json
set(PLUGIN_JSON_VERSION "0.7.0")
if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")
set(PLUGIN_JSON_HASH "a7bf52009a935f22b473724f722566fde27aec5c7d618ecd426eed81e477e94d")
else() # aarch64
set(PLUGIN_JSON_HASH "9cd65fac3f1cbc7f723b69671d42d35901cd322a23d8f2b9dc95fb0593918a7e")
endif()
ExternalProject_Add(
json-plugin
URL "https://download.falco.org/plugins/${PLUGINS_DOWNLOAD_BUCKET}/json-${PLUGIN_JSON_VERSION}-${PLUGINS_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}.tar.gz"
URL_HASH "SHA256=${PLUGIN_JSON_HASH}"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
install(FILES "${PROJECT_BINARY_DIR}/json-plugin-prefix/src/json-plugin/libjson.so" DESTINATION "${FALCO_PLUGINS_DIR}" COMPONENT "${PLUGINS_COMPONENT_NAME}")

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2024 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
@@ -16,8 +15,8 @@ include(GNUInstallDirs)
include(ExternalProject)
# falco_rules.yaml
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-3.0.0")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM "SHA256=2e91799fee49c2daf58fb482e47410a21433eb116e02cde18206f7af87449ddb")
set(FALCOSECURITY_RULES_FALCO_VERSION "falco-rules-1.0.1")
set(FALCOSECURITY_RULES_FALCO_CHECKSUM "SHA256=2348d43196bbbdea92e3f67fa928721a241b0406d0ef369693bdefcec2b3fa13")
set(FALCOSECURITY_RULES_FALCO_PATH "${PROJECT_BINARY_DIR}/falcosecurity-rules-falco-prefix/src/falcosecurity-rules-falco/falco_rules.yaml")
ExternalProject_Add(
falcosecurity-rules-falco
@@ -34,11 +33,7 @@ set(FALCOSECURITY_RULES_LOCAL_PATH "${PROJECT_BINARY_DIR}/falcosecurity-rules-lo
file(WRITE "${FALCOSECURITY_RULES_LOCAL_PATH}" "# Your custom rules!\n")
if(NOT DEFINED FALCO_ETC_DIR)
set(FALCO_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falco")
endif()
if(WIN32 OR APPLE)
set(FALCO_ETC_DIR "etc/falco")
set(FALCO_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falco")
endif()
if(NOT DEFINED FALCO_RULES_DEST_FILENAME)

View File

@@ -1,17 +1,3 @@
# 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.
#
# create the reports folder
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/static-analysis-reports)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/static-analysis-reports/cppcheck)

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
@@ -24,18 +23,13 @@ if(NOT USE_BUNDLED_DEPS)
else()
set(YAMLCPP_SRC "${PROJECT_BINARY_DIR}/yamlcpp-prefix/src/yamlcpp")
message(STATUS "Using bundled yaml-cpp in '${YAMLCPP_SRC}'")
if(NOT WIN32)
set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a")
else()
set(YAMLCPP_LIB "${YAMLCPP_SRC}/${CMAKE_BUILD_TYPE}/yaml-cpp.lib")
endif()
set(YAMLCPP_LIB "${YAMLCPP_SRC}/libyaml-cpp.a")
set(YAMLCPP_INCLUDE_DIR "${YAMLCPP_SRC}/include")
ExternalProject_Add(
yamlcpp
URL "https://github.com/jbeder/yaml-cpp/archive/yaml-cpp-0.7.0.tar.gz"
URL_HASH "SHA256=43e6a9fcb146ad871515f0d0873947e5d497a1c9c60c58cb102a97b47208b7c3"
URL "https://github.com/jbeder/yaml-cpp/archive/yaml-cpp-0.6.2.tar.gz"
URL_HASH "SHA256=e4d8560e163c3d875fd5d9e5542b5fd5bec810febdcba61481fe5fc4e6b1fd05"
BUILD_BYPRODUCTS ${YAMLCPP_LIB}
CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DYAML_MSVC_SHARED_RT=Off -DYAML_BUILD_SHARED_LIBS=Off -DYAML_CPP_BUILD_TESTS=Off -DYAML_CPP_BUILD_TOOLS=OFF -DYAML_CPP_BUILD_CONTRIB=OFF -DCMAKE_DEBUG_POSTFIX=''
BUILD_IN_SOURCE 1
INSTALL_COMMAND "")
endif()

View File

@@ -9,10 +9,3 @@ This directory contains various ways to package Falco as a container and related
| [falcosecurity/falco:latest](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco), [falcosecurity/falco:master](https://hub.docker.com/repository/docker/falcosecurity/falco) | docker/falco | Falco (DEB built from git tag or from the master) with all the building toolchain. |
| [falcosecurity/falco-driver-loader:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader), [falcosecurity/falco-driver-loader:master](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader) | docker/driver-loader | `falco-driver-loader` as entrypoint with the building toolchain. |
| [falcosecurity/falco-no-driver:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver), [falcosecurity/falco-no-driver:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver),[falcosecurity/falco-no-driver:master](https://hub.docker.com/repository/docker/falcosecurity/falco-no-driver) | docker/no-driver | Falco (TGZ built from git tag or from the master) without the building toolchain. |
| [falcosecurity/falco-driver-loader-legacy:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader-legacy), [falcosecurity/falco-driver-loader-legacy:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-driver-loader-legacy) | docker/driver-loader-legacy | `falco-driver-loader` as entrypoint with the legacy building toolchain. Recommended for kernels < 4.0 |
## Experimental Images
| Name | Directory | Description |
|---|---|---|
| [falcosecurity/falco-distroless:latest](https://hub.docker.com/repository/docker/falcosecurity/falco-distroless), [falcosecurity/falco-distroless:_tag_](https://hub.docker.com/repository/docker/falcosecurity/falco-distroless),[falcosecurity/falco-distroless:master](https://hub.docker.com/repository/docker/falcosecurity/falco-distroless) | docker/no-driver/Dockerfile.distroless | Falco without the building toolchain built from a distroless base image. This results in a smaller image that has less potentially vulnerable components. |

View File

@@ -1,128 +0,0 @@
FROM debian:buster
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
LABEL usage="docker run -i -t --privileged -v /var/run/docker.sock:/host/var/run/docker.sock -v /dev:/host/dev -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc --name NAME IMAGE"
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
RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash-completion \
bc \
bison \
clang-7 \
ca-certificates \
curl \
dkms \
flex \
gnupg2 \
gcc \
jq \
libc6-dev \
libelf-dev \
libssl-dev \
llvm-7 \
netcat \
patchelf \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
RUN if [ "$TARGETARCH" = "amd64" ]; \
then apt-get install -y --no-install-recommends libmpx2; \
fi
# gcc 6 is no longer included in debian stable, but we need it to
# build kernel modules on the default debian-based ami used by
# kops. So grab copies we've saved from debian snapshots with the
# prefix https://snapshot.debian.org/archive/debian/20170517T033514Z
# or so.
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
curl -L -o cpp-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o gcc-6-base_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o gcc-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libasan3_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libubsan0_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libubsan0_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libmpfr4_3.1.3-2_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_${TARGETARCH}.deb \
&& curl -L -o libisl15_0.18-1_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-1_${TARGETARCH}.deb \
&& dpkg -i cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb; \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb \
&& rm -f cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb libcilkrts5_6.3.0-18_${TARGETARCH}.deb libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb
# gcc 5 is no longer included in debian stable, but we need it to
# build centos kernels, which are 3.x based and explicitly want a gcc
# version 3, 4, or 5 compiler. So grab copies we've saved from debian
# snapshots with the prefix https://snapshot.debian.org/archive/debian/20190122T000000Z.
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libmpx0_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
curl -L -o cpp-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o gcc-5-base_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o gcc-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libasan2_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libisl15_0.18-4_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-4_${TARGETARCH}.deb \
&& dpkg -i cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb; \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb \
&& rm -f cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb libmpx0_5.5.0-12_${TARGETARCH}.deb
# Since our base Debian image ships with GCC 7 which breaks older kernels, revert the
# default to gcc-5.
RUN rm -rf /usr/bin/gcc && ln -s /usr/bin/gcc-5 /usr/bin/gcc
RUN rm -rf /usr/bin/clang \
&& rm -rf /usr/bin/llc \
&& ln -s /usr/bin/clang-7 /usr/bin/clang \
&& ln -s /usr/bin/llc-7 /usr/bin/llc
RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& echo "deb https://download.falco.org/packages/${VERSION_BUCKET} stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list \
&& apt-get update -y \
&& if [ "$FALCO_VERSION" = "latest" ]; then apt-get install -y --no-install-recommends falco; else apt-get install -y --no-install-recommends falco=${FALCO_VERSION}; fi \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 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
# silently overwriting the existing directory
RUN rm -df /lib/modules \
&& ln -s $HOST_ROOT/lib/modules /lib/modules
# debian:stable head contains binutils 2.31, which generates
# binaries that are incompatible with kernels < 4.16. So manually
# forcibly install binutils 2.30-22 instead.
RUN if [ "$TARGETARCH" = "amd64" ] ; then \
curl -L -o binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
else \
curl -L -o binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
fi
RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils_2.30-22_${TARGETARCH}.deb \
&& curl -L -o libbinutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/libbinutils_2.30-22_${TARGETARCH}.deb \
&& curl -L -o binutils-common_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-common_2.30-22_${TARGETARCH}.deb \
&& dpkg -i *binutils*.deb \
&& rm -f *binutils*.deb
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -1,117 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
print_usage() {
echo ""
echo "Usage:"
echo " docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader-legacy:latest [driver] [options]"
echo ""
echo "Available drivers:"
echo " kmod kernel module (default)"
echo " ebpf eBPF probe"
echo ""
echo "Options:"
echo " --help show this help message"
echo " --clean try to remove an already present driver installation"
echo " --compile try to compile the driver locally (default true)"
echo " --download try to download a prebuilt driver (default true)"
echo " --http-insecure enable insecure downloads"
echo " --print-env skip execution and print env variables for other tools to consume"
echo ""
echo "Environment variables:"
echo " FALCOCTL_DRIVER_REPOS specify different URL(s) where to look for prebuilt Falco drivers (comma separated)"
echo " FALCOCTL_DRIVER_NAME specify a different name for the driver"
echo " FALCOCTL_DRIVER_HTTP_HEADERS specify comma separated list of http headers for driver download (e.g. 'x-emc-namespace: default,Proxy-Authenticate: Basic')"
echo ""
}
echo "* Setting up /usr/src links from host"
for i in "$HOST_ROOT/usr/src"/*
do
base=$(basename "$i")
ln -s "$i" "/usr/src/$base"
done
ENABLE_COMPILE="false"
ENABLE_DOWNLOAD="false"
HTTP_INSECURE="false"
has_driver=
has_opts=
while test $# -gt 0; do
case "$1" in
kmod|ebpf)
if [ -n "$has_driver" ]; then
>&2 echo "Only one driver per invocation"
print_usage
exit 1
else
/usr/bin/falcoctl driver config --type $1
has_driver="true"
fi
;;
-h|--help)
print_usage
exit 0
;;
--clean)
/usr/bin/falcoctl driver cleanup
exit 0
;;
--compile)
ENABLE_COMPILE="true"
has_opts="true"
;;
--download)
ENABLE_DOWNLOAD="true"
has_opts="true"
;;
--http-insecure)
HTTP_INSECURE="true"
;;
--source-only)
>&2 echo "Support dropped in Falco 0.37.0."
print_usage
exit 1
;;
--print-env)
/usr/bin/falcoctl driver printenv
exit 0
;;
--*)
>&2 echo "Unknown option: $1"
print_usage
exit 1
;;
*)
>&2 echo "Unknown driver: $1"
print_usage
exit 1
;;
esac
shift
done
if [ -z "$has_opts" ]; then
ENABLE_COMPILE="true"
ENABLE_DOWNLOAD="true"
fi
/usr/bin/falcoctl driver install --compile=$ENABLE_COMPILE --download=$ENABLE_DOWNLOAD --http-insecure=$HTTP_INSECURE --http-headers="$FALCOCTL_DRIVER_HTTP_HEADERS"

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,30 +17,6 @@
#
print_usage() {
echo ""
echo "Usage:"
echo " docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro falcosecurity/falco-driver-loader:latest [driver] [options]"
echo ""
echo "Available drivers:"
echo " kmod kernel module (default)"
echo " ebpf eBPF probe"
echo ""
echo "Options:"
echo " --help show this help message"
echo " --clean try to remove an already present driver installation"
echo " --compile try to compile the driver locally (default true)"
echo " --download try to download a prebuilt driver (default true)"
echo " --http-insecure enable insecure downloads"
echo " --print-env skip execution and print env variables for other tools to consume"
echo ""
echo "Environment variables:"
echo " FALCOCTL_DRIVER_REPOS specify different URL(s) where to look for prebuilt Falco drivers (comma separated)"
echo " FALCOCTL_DRIVER_NAME specify a different name for the driver"
echo " FALCOCTL_DRIVER_HTTP_HEADERS specify comma separated list of http headers for driver download (e.g. 'x-emc-namespace: default,Proxy-Authenticate: Basic')"
echo ""
}
echo "* Setting up /usr/src links from host"
for i in "$HOST_ROOT/usr/src"/*
@@ -50,68 +25,4 @@ do
ln -s "$i" "/usr/src/$base"
done
ENABLE_COMPILE="false"
ENABLE_DOWNLOAD="false"
HTTP_INSECURE="false"
has_driver=
has_opts=
while test $# -gt 0; do
case "$1" in
kmod|ebpf)
if [ -n "$has_driver" ]; then
>&2 echo "Only one driver per invocation"
print_usage
exit 1
else
/usr/bin/falcoctl driver config --type $1
has_driver="true"
fi
;;
-h|--help)
print_usage
exit 0
;;
--clean)
/usr/bin/falcoctl driver cleanup
exit 0
;;
--compile)
ENABLE_COMPILE="true"
has_opts="true"
;;
--download)
ENABLE_DOWNLOAD="true"
has_opts="true"
;;
--http-insecure)
HTTP_INSECURE="true"
;;
--source-only)
>&2 echo "Support dropped in Falco 0.37.0."
print_usage
exit 1
;;
--print-env)
/usr/bin/falcoctl driver printenv
exit 0
;;
--*)
>&2 echo "Unknown option: $1"
print_usage
exit 1
;;
*)
>&2 echo "Unknown driver: $1"
print_usage
exit 1
;;
esac
shift
done
if [ -z "$has_opts" ]; then
ENABLE_COMPILE="true"
ENABLE_DOWNLOAD="true"
fi
/usr/bin/falcoctl driver install --compile=$ENABLE_COMPILE --download=$ENABLE_DOWNLOAD --http-insecure=$HTTP_INSECURE --http-headers="$FALCOCTL_DRIVER_HTTP_HEADERS"
/usr/bin/falco-driver-loader "$@"

View File

@@ -1,4 +1,4 @@
FROM debian:bookworm
FROM debian:buster
LABEL maintainer="cncf-falco-dev@lists.cncf.io"
LABEL org.opencontainers.image.source="https://github.com/falcosecurity/falco"
@@ -19,28 +19,76 @@ RUN cp /etc/skel/.bashrc /root && cp /etc/skel/.profile /root
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
bash-completion \
bc \
bison \
clang-7 \
ca-certificates \
clang \
curl \
dkms \
dwarves \
flex \
gcc \
gcc-11 \
gnupg2 \
gcc \
jq \
libc6-dev \
libelf-dev \
libssl-dev \
llvm \
make \
netcat-openbsd \
llvm-7 \
netcat \
patchelf \
xz-utils \
&& rm -rf /var/lib/apt/lists/*
RUN if [ "$TARGETARCH" = "amd64" ]; \
then apt-get install -y --no-install-recommends libmpx2; \
fi
# gcc 6 is no longer included in debian stable, but we need it to
# build kernel modules on the default debian-based ami used by
# kops. So grab copies we've saved from debian snapshots with the
# prefix https://snapshot.debian.org/archive/debian/20170517T033514Z
# or so.
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libcilkrts5_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
curl -L -o cpp-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-6_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o gcc-6-base_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6-base_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o gcc-6_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-6_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libasan3_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan3_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libubsan0_6.3.0-18_${TARGETARCH}.deb https://download.falco.org/dependencies/libubsan0_6.3.0-18_${TARGETARCH}.deb \
&& curl -L -o libmpfr4_3.1.3-2_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpfr4_3.1.3-2_${TARGETARCH}.deb \
&& curl -L -o libisl15_0.18-1_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-1_${TARGETARCH}.deb \
&& dpkg -i cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb; \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libcilkrts5_6.3.0-18_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb \
&& rm -f cpp-6_6.3.0-18_${TARGETARCH}.deb gcc-6-base_6.3.0-18_${TARGETARCH}.deb gcc-6_6.3.0-18_${TARGETARCH}.deb libasan3_6.3.0-18_${TARGETARCH}.deb libcilkrts5_6.3.0-18_${TARGETARCH}.deb libgcc-6-dev_6.3.0-18_${TARGETARCH}.deb libubsan0_6.3.0-18_${TARGETARCH}.deb libmpfr4_3.1.3-2_${TARGETARCH}.deb libisl15_0.18-1_${TARGETARCH}.deb
# gcc 5 is no longer included in debian stable, but we need it to
# build centos kernels, which are 3.x based and explicitly want a gcc
# version 3, 4, or 5 compiler. So grab copies we've saved from debian
# snapshots with the prefix https://snapshot.debian.org/archive/debian/20190122T000000Z.
RUN if [ "$TARGETARCH" = "amd64" ]; then curl -L -o libmpx0_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
curl -L -o cpp-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/cpp-5_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o gcc-5-base_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5-base_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o gcc-5_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/gcc-5_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libasan2_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libasan2_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb https://download.falco.org/dependencies/libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb \
&& curl -L -o libisl15_0.18-4_${TARGETARCH}.deb https://download.falco.org/dependencies/libisl15_0.18-4_${TARGETARCH}.deb \
&& dpkg -i cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb; \
if [ "$TARGETARCH" = "amd64" ]; then dpkg -i libmpx0_5.5.0-12_${TARGETARCH}.deb; fi; \
dpkg -i libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb \
&& rm -f cpp-5_5.5.0-12_${TARGETARCH}.deb gcc-5-base_5.5.0-12_${TARGETARCH}.deb gcc-5_5.5.0-12_${TARGETARCH}.deb libasan2_5.5.0-12_${TARGETARCH}.deb libgcc-5-dev_5.5.0-12_${TARGETARCH}.deb libisl15_0.18-4_${TARGETARCH}.deb libmpx0_5.5.0-12_${TARGETARCH}.deb
# Since our base Debian image ships with GCC 7 which breaks older kernels, revert the
# default to gcc-5.
RUN rm -rf /usr/bin/gcc && ln -s /usr/bin/gcc-5 /usr/bin/gcc
RUN rm -rf /usr/bin/clang \
&& rm -rf /usr/bin/llc \
&& ln -s /usr/bin/clang-7 /usr/bin/clang \
&& ln -s /usr/bin/llc-7 /usr/bin/llc
RUN curl -s https://falco.org/repo/falcosecurity-packages.asc | apt-key add - \
&& echo "deb https://download.falco.org/packages/${VERSION_BUCKET} stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list \
&& apt-get update -y \
@@ -59,6 +107,22 @@ RUN sed -e 's/time_format_iso_8601: false/time_format_iso_8601: true/' < /etc/fa
RUN rm -df /lib/modules \
&& ln -s $HOST_ROOT/lib/modules /lib/modules
# debian:stable head contains binutils 2.31, which generates
# binaries that are incompatible with kernels < 4.16. So manually
# forcibly install binutils 2.30-22 instead.
RUN if [ "$TARGETARCH" = "amd64" ] ; then \
curl -L -o binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-x86-64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
else \
curl -L -o binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-aarch64-linux-gnu_2.30-22_${TARGETARCH}.deb; \
fi
RUN curl -L -o binutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils_2.30-22_${TARGETARCH}.deb \
&& curl -L -o libbinutils_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/libbinutils_2.30-22_${TARGETARCH}.deb \
&& curl -L -o binutils-common_2.30-22_${TARGETARCH}.deb https://download.falco.org/dependencies/binutils-common_2.30-22_${TARGETARCH}.deb \
&& dpkg -i *binutils*.deb \
&& rm -f *binutils*.deb
COPY ./docker-entrypoint.sh /
ENTRYPOINT ["/docker-entrypoint.sh"]

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,31 +16,6 @@
# limitations under the License.
#
print_usage() {
echo ""
echo "Usage:"
echo " docker run -i -t --privileged -v /root/.falco:/root/.falco -v /proc:/host/proc:ro -v /boot:/host/boot:ro -v /lib/modules:/host/lib/modules:ro -v /usr:/host/usr:ro -v /etc:/host/etc:ro -e 'FALCO_DRIVER_LOADER_OPTIONS=[driver] [options]' falcosecurity/falco:latest"
echo ""
echo "Available FALCO_DRIVER_LOADER_OPTIONS drivers:"
echo " kmod kernel module (default)"
echo " ebpf eBPF probe"
echo ""
echo "FALCO_DRIVER_LOADER_OPTIONS options:"
echo " --help show this help message"
echo " --clean try to remove an already present driver installation"
echo " --compile try to compile the driver locally (default true)"
echo " --download try to download a prebuilt driver (default true)"
echo " --http-insecure enable insecure downloads"
echo " --print-env skip execution and print env variables for other tools to consume"
echo ""
echo "Environment variables:"
echo " FALCOCTL_DRIVER_REPOS specify different URL(s) where to look for prebuilt Falco drivers (comma separated)"
echo " FALCOCTL_DRIVER_NAME specify a different name for the driver"
echo " FALCOCTL_DRIVER_HTTP_HEADERS specify comma separated list of http headers for driver download (e.g. 'x-emc-namespace: default,Proxy-Authenticate: Basic')"
echo ""
}
# Set the SKIP_DRIVER_LOADER variable to skip loading the driver
if [[ -z "${SKIP_DRIVER_LOADER}" ]]; then
@@ -53,74 +27,7 @@ if [[ -z "${SKIP_DRIVER_LOADER}" ]]; then
ln -s "$i" "/usr/src/$base"
done
# convert the optional space-separated env variable FALCO_DRIVER_LOADER_OPTIONS to array, prevent
# shell expansion and use it as argument list for falcoctl
read -a falco_driver_loader_option_arr <<< $FALCO_DRIVER_LOADER_OPTIONS
ENABLE_COMPILE="false"
ENABLE_DOWNLOAD="false"
HTTP_INSECURE="false"
has_driver=
has_opts=
for opt in "${falco_driver_loader_option_arr[@]}"
do
case "$opt" in
kmod|ebpf)
if [ -n "$has_driver" ]; then
>&2 echo "Only one driver per invocation"
print_usage
exit 1
else
/usr/bin/falcoctl driver config --type $opt
has_driver="true"
fi
;;
-h|--help)
print_usage
exit 0
;;
--clean)
/usr/bin/falcoctl driver cleanup
exit 0
;;
--compile)
ENABLE_COMPILE="true"
has_opts="true"
;;
--download)
ENABLE_DOWNLOAD="true"
has_opts="true"
;;
--http-insecure)
HTTP_INSECURE="true"
;;
--source-only)
>&2 echo "Support dropped in Falco 0.37.0."
print_usage
exit 1
;;
--print-env)
/usr/bin/falcoctl driver printenv
exit 0
;;
--*)
>&2 echo "Unknown option: $1"
print_usage
exit 1
;;
*)
>&2 echo "Unknown driver: $1"
print_usage
exit 1
;;
esac
done
if [ -z "$has_opts" ]; then
ENABLE_COMPILE="true"
ENABLE_DOWNLOAD="true"
fi
/usr/bin/falcoctl driver install --compile=$ENABLE_COMPILE --download=$ENABLE_DOWNLOAD --http-insecure=$HTTP_INSECURE --http-headers="$FALCOCTL_DRIVER_HTTP_HEADERS"
/usr/bin/falco-driver-loader
fi
exec "$@"
exec "$@"

View File

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

View File

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

View File

@@ -1,4 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
@@ -27,8 +26,6 @@
# (Falco environment variables)
# Falco rules files
# rules_file
# Falco engine
# engine
# Falco plugins
# load_plugins
# plugins
@@ -41,8 +38,7 @@
# json_include_output_property
# json_include_tags_property
# buffered_outputs
# rule_matching
# outputs_queue
# outputs (throttling)
# Falco outputs channels
# stdout_output
# syslog_output
@@ -61,13 +57,16 @@
# Falco logging / alerting / metrics related to software functioning (advanced)
# output_timeout
# syscall_event_timeouts
# syscall_event_drops -> [CHANGE NOTICE] Automatic notifications will be simplified in Falco 0.38! If you depend on the detailed drop counters payload, use 'metrics.output_rule' along with 'metrics.kernel_event_counters_enabled' instead
# syscall_event_drops
# metrics
# Falco performance tuning (advanced)
# syscall_buf_size_preset [DEPRECATED] -> Replaced by `engine.<driver>.buf_size_preset` starting Falco 0.38!
# syscall_drop_failed_exit [DEPRECATED] -> Replaced by `engine.<driver>.drop_failed_exit` starting Falco 0.38!
# syscall_buf_size_preset
# syscall_drop_failed_exit
# base_syscalls
# modern_bpf.cpus_for_each_syscall_buffer [DEPRECATED] -> Replaced by `engine.modern_ebpf.cpus_for_each_buffer` starting Falco 0.38!
# modern_bpf.cpus_for_each_syscall_buffer
# Falco cloud orchestration systems integration
# metadata_download
# (Guidance for Kubernetes container engine command-line args settings)
################################
@@ -79,9 +78,9 @@
# configuration options from this config file as command-line arguments by using
# the `-o` flag followed by the option name and value. In the following example,
# three config options (`json_output`, `log_level`, and
# `engine.kind`) are passed as command-line
# `modern_bpf.cpus_for_each_syscall_buffer`) are passed as command-line
# arguments with their corresponding values: falco -o "json_output=true"
# -o "log_level=debug" -o "engine.kind=kmod"
# -o "log_level=debug" -o "modern_bpf.cpus_for_each_syscall_buffer=4"
# Please note that command-line arguments take precedence over the options
# specified in this config file.
@@ -92,32 +91,16 @@
# Customize Falco settings using environment variables:
#
# - HOST_ROOT: Specifies the prefix to the underlying host `/proc` filesystem
# - "HOST_ROOT": Specifies the prefix to the underlying host `/proc` filesystem
# when deploying Falco over a container with read-only host mounts instead of
# directly on the host. Defaults to "/host".
#
# - !!! [DEPRECATED] FALCO_BPF_PROBE: Specify a custom path to the BPF object code file (`bpf`
# - "FALCO_BPF_PROBE": Specify a custom path to the BPF object code file (`bpf`
# driver). This is not needed for the modern_bpf driver.
# -> Replaced by `engine.kind: ebpf` and `engine.ebpf` starting Falco 0.38!
#
# - FALCO_HOSTNAME: Customize the hostname output field logged by Falco by
# - "FALCO_HOSTNAME": Customize the hostname output field logged by Falco by
# setting the "FALCO_HOSTNAME" environment variable.
#
# - FALCO_CGROUP_MEM_PATH: Specifies the file path holding the container
# - "FALCO_CGROUP_MEM_PATH": Specifies the file path holding the container
# memory usage metric for the `metrics` feature. Defaults to
# "/sys/fs/cgroup/memory/memory.usage_in_bytes" (Kubernetes).
#
# - SKIP_DRIVER_LOADER is used by the Falco fat image to skip the driver loading part.
#
# - FALCO_FRONTEND is useful when set to noninteractive to skip the dialog choice during
# the installation of Falco deb/rpm packages. This setting is somewhat similar to DEBIAN_FRONTEND.
#
# - FALCO_DRIVER_CHOICE is useful when set to kmod, ebpf, or modern_ebpf (matching the names
# used in engine.kind in the Falco config) during the installation of Falco deb/rpm packages.
# It skips the dialog choice but retains the driver configuration.
#
# - FALCOCTL_ENABLED is useful when set to 'no' during the installation of Falco deb/rpm packages,
# disabling the automatic artifacts followed by falcoctl.
#####################
@@ -162,197 +145,6 @@ rules_file:
- /etc/falco/falco_rules.local.yaml
- /etc/falco/rules.d
################
# Falco engine #
################
# [Stable] `engine`
#
# --- [Description]
#
# Falco supports different engines to generate events.
# Choose the appropriate engine kind based on your system's configuration and requirements.
#
# Available engines:
# - `kmod`: Kernel Module (Kernel Module)
# - `ebpf`: eBPF (eBPF probe)
# - `modern_ebpf`: Modern eBPF (CO-RE eBPF probe)
# - `gvisor`: gVisor (gVisor sandbox)
# - `replay`: Replay a scap trace file
# - `nodriver`: No driver is injected into the system.
# This is useful to debug and to run plugins with 'syscall' source.
#
# Only one engine can be specified in the `kind` key.
# Moreover, for each engine multiple options might be available,
# grouped under engine-specific configuration keys.
# Some of them deserve an in-depth description:
#
################### `buf_size_preset`
#
# --- [Description]
#
# The syscall buffer index determines the size of the shared space between Falco
# and its drivers. This shared space serves as a temporary storage for syscall
# events, allowing them to be transferred from the kernel to the userspace
# efficiently. The buffer size for each online CPU is determined by the buffer
# index, and each CPU has its own dedicated buffer. Adjusting this index allows
# you to control the overall size of the syscall buffers.
#
# --- [Usage]
#
# The index 0 is reserved, and each subsequent index corresponds to an
# increasing size in bytes. For example, index 1 corresponds to a size of 1 MB,
# index 2 corresponds to 2 MB, and so on:
#
# [(*), 1 MB, 2 MB, 4 MB, 8 MB, 16 MB, 32 MB, 64 MB, 128 MB, 256 MB, 512 MB]
# ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
# | | | | | | | | | | |
# 0 1 2 3 4 5 6 7 8 9 10
#
#
# The buffer dimensions in bytes are determined by the following requirements:
# (1) a power of 2.
# (2) a multiple of your system_page_dimension.
# (3) greater than `2 * (system_page_dimension).
#
# The buffer size constraints may limit the usability of certain indexes. Let's
# consider an example to illustrate this:
#
# If your system has a page size of 1 MB, the first available buffer size would
# be 4 MB because 2 MB is exactly equal to 2 * (system_page_size), which is not
# sufficient as we require more than 2 * (system_page_size). In this example, it
# is evident that if the page size is 1 MB, the first index that can be used is 3.
#
# However, in most cases, these constraints do not pose a limitation, and all
# indexes from 1 to 10 can be used. You can check your system's page size using
# the Falco `--page-size` command-line option.
#
# --- [Suggestions]
#
# The buffer size was previously fixed at 8 MB (index 4). You now have the
# option to adjust the size based on your needs. Increasing the size, such as to
# 16 MB (index 5), can reduce syscall drops in heavy production systems, but may
# impact performance. Decreasing the size can speed up the system but may
# increase syscall drops. It's important to note that the buffer size is mapped
# twice in the process' virtual memory, so a buffer of 8 MB will result in a 16
# MB area in virtual memory. Use this parameter with caution and only modify it
# if the default size is not suitable for your use case.
#
################### `drop_failed_exit`
#
# --- [Description]
#
# Enabling this option in Falco allows it to drop failed system call exit events
# in the kernel drivers before pushing them onto the ring buffer. This
# optimization can result in lower CPU usage and more efficient utilization of
# the ring buffer, potentially reducing the number of event losses. However, it
# is important to note that enabling this option also means sacrificing some
# visibility into the system.
#
################### `cpus_for_each_buffer` (modern_ebpf only)
#
# --- [Description]
#
# The modern_bpf driver in Falco utilizes the new BPF ring buffer, which has a
# different memory footprint compared to the current BPF driver that uses the
# perf buffer. The Falco core maintainers have discussed the differences and
# their implications, particularly in Kubernetes environments where limits need
# to be carefully set to avoid interference with the Falco daemonset deployment
# from the OOM killer. Based on guidance received from the kernel mailing list,
# it is recommended to assign multiple CPUs to one buffer instead of allocating
# a buffer for each CPU individually. This helps optimize resource allocation
# and prevent potential issues related to memory usage.
#
# This is an index that controls how many CPUs you want to assign to a single
# syscall buffer (ring buffer). By default, for modern_bpf every syscall buffer
# is associated to 2 CPUs, so the mapping is 1:2. The modern BPF probe allows
# you to choose different mappings, for example, changing the value to `1`
# results in a 1:1 mapping and would mean one syscall buffer for each CPU (this
# is the default for the `bpf` driver).
#
# --- [Usage]
#
# You can choose an index from 0 to MAX_NUMBER_ONLINE_CPUs to set the dimension
# of the syscall buffers. The value 0 represents a single buffer shared among
# all online CPUs. It serves as a flexible option when the exact number of
# online CPUs is unknown. Here's an example to illustrate this:
#
# Consider a system with 7 online CPUs:
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
#
# - `1` means a syscall buffer for each CPU so 7 buffers
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 1 2 3 4 5 6
#
# - `2` (Default value) means a syscall buffer for each CPU pair, so 4 buffers
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 0 1 1 2 2 3
#
# Please note that in this example, there are 4 buffers in total. Three of the
# buffers are associated with pairs of CPUs, while the last buffer is mapped to
# a single CPU. This arrangement is necessary because we have an odd number of
# CPUs.
#
# - `0` or `MAX_NUMBER_ONLINE_CPUs` mean a syscall buffer shared between all
# CPUs, so 1 buffer
#
# CPUs 0 X 2 3 X X 6 7 8 9 (X means offline CPU)
# | | | | | | |
# BUFFERs 0 0 0 0 0 0 0
#
# Moreover, you have the option to combine this parameter with
# `buf_size_preset` index. For instance, you can create a large shared
# syscall buffer of 512 MB (using buf_size_preset=10) that is
# allocated among all the online CPUs.
#
# --- [Suggestions]
#
# The default choice of index 2 (one syscall buffer for each CPU pair) was made
# because the modern bpf probe utilizes a different memory allocation strategy
# compared to the other two drivers (bpf and kernel module). However, you have
# the flexibility to experiment and find the optimal configuration for your
# system.
#
# When considering a fixed buf_size_preset and a fixed buffer dimension:
# - Increasing this configs value results in lower number of buffers and you can
# speed up your system and reduce memory usage
# - However, using too few buffers may increase contention in the kernel,
# leading to a slowdown.
#
# If you have low event throughputs and minimal drops, reducing the number of
# buffers (higher `cpus_for_each_buffer`) can lower the memory footprint.
#
engine:
kind: kmod
kmod:
buf_size_preset: 4
drop_failed_exit: false
ebpf:
# path to the elf file to load.
probe: ${HOME}/.falco/falco-bpf.o
buf_size_preset: 4
drop_failed_exit: false
modern_ebpf:
cpus_for_each_buffer: 2
buf_size_preset: 4
drop_failed_exit: false
replay:
# path to the capture file to replay (eg: /path/to/file.scap)
capture_file: ""
gvisor:
# A Falco-compatible configuration file can be generated with
# '--gvisor-generate-config' and utilized for both runsc and Falco.
config: ""
# Set gVisor root directory for storage of container state when used
# in conjunction with 'gvisor.config'. The 'gvisor.root' to be passed
# is the one usually passed to 'runsc --root' flag.
root: ""
#################
# Falco plugins #
#################
@@ -375,10 +167,11 @@ engine:
#
# Please note that if your intention is to enrich Falco syscall logs with fields
# such as `k8s.ns.name`, `k8s.pod.name`, and `k8s.pod.*`, you do not need to use
# the `k8saudit` plugin. This information is automatically extracted from
# the container runtime socket. The `k8saudit` plugin is specifically designed
# to integrate with Kubernetes audit logs and is not required for basic enrichment
# of syscall logs with Kubernetes-related fields.
# the `k8saudit` plugin nor the `-k`/`-K` Kubernetes metadata enrichment. This
# information is automatically extracted from the container runtime socket. The
# `k8saudit` plugin is specifically designed to integrate with Kubernetes audit
# logs and is not required for basic enrichment of syscall logs with
# Kubernetes-related fields.
#
# --- [Usage]
#
@@ -477,6 +270,34 @@ json_include_tags_property: true
# output mechanism. By default, buffering is disabled (false).
buffered_outputs: false
# [Stable] `outputs`
#
# [DEPRECATED]
# This config is deprecated and it will be removed in Falco 0.37
#
# A throttling mechanism, implemented as a token bucket, can be used to control
# the rate of Falco outputs. Each event source has its own rate limiter,
# ensuring that alerts from one source do not affect the throttling of others.
# The following options control the mechanism:
# - rate: the number of tokens (i.e. right to send a notification) gained per
# second. When 0, the throttling mechanism is disabled. Defaults to 0.
# - max_burst: the maximum number of tokens outstanding. Defaults to 1000.
#
# For example, setting the rate to 1 allows Falco to send up to 1000
# notifications initially, followed by 1 notification per second. The burst
# capacity is fully restored after 1000 seconds of no activity.
#
# Throttling can be useful in various scenarios, such as preventing notification
# floods, managing system load, controlling event processing, or complying with
# rate limits imposed by external systems or APIs. It allows for better resource
# utilization, avoids overwhelming downstream systems, and helps maintain a
# balanced and controlled flow of notifications.
#
# With the default settings, the throttling mechanism is disabled.
outputs:
rate: 0
max_burst: 1000
# [Experimental] `rule_matching`
#
# The `rule_matching` configuration key's values are:
@@ -498,27 +319,6 @@ buffered_outputs: false
# deploying it in production.
rule_matching: first
# [Stable] `outputs_queue`
#
# Falco utilizes tbb::concurrent_bounded_queue for handling outputs, and this parameter
# allows you to customize the queue capacity. Please refer to the official documentation:
# https://oneapi-src.github.io/oneTBB/main/tbb_userguide/Concurrent_Queue_Classes.html.
# On a healthy system with optimized Falco rules, the queue should not fill up.
# If it does, it is most likely happening due to the entire event flow being too slow,
# indicating that the server is under heavy load.
#
# `capacity`: the maximum number of items allowed in the queue is determined by this value.
# Setting the value to 0 (which is the default) is equivalent to keeping the queue unbounded.
# In other words, when this configuration is set to 0, the number of allowed items is
# effectively set to the largest possible long value, disabling this setting.
#
# In the case of an unbounded queue, if the available memory on the system is consumed,
# the Falco process would be OOM killed. When using this option and setting the capacity,
# the current event would be dropped, and the event loop would continue. This behavior mirrors
# kernel-side event drops when the buffer between kernel space and user space is full.
outputs_queue:
capacity: 0
##########################
# Falco outputs channels #
@@ -582,8 +382,6 @@ http_output:
client_key: "/etc/ssl/certs/client.key"
# Whether to echo server answers to stdout
echo: false
compress_uploads: false
keep_alive: false
# [Stable] `program_output`
#
@@ -698,8 +496,6 @@ webserver:
# the appropriate number of threads based on the number of online cores in the system.
threadiness: 0
listen_port: 8765
# Can be an IPV4 or IPV6 address, defaults to IPV4
listen_address: 0.0.0.0
k8s_healthz_endpoint: /healthz
ssl_enabled: false
ssl_certificate: /etc/falco/falco.pem
@@ -793,7 +589,7 @@ output_timeout: 2000
syscall_event_timeouts:
max_consecutives: 1000
# [Stable] `syscall_event_drops` -> [CHANGE NOTICE] Automatic notifications will be simplified in Falco 0.38! If you depend on the detailed drop counters payload, use 'metrics.output_rule' along with 'metrics.kernel_event_counters_enabled' instead
# [Stable] `syscall_event_drops`
#
# Generates "Falco internal: syscall event drop" rule output when `priority=debug` at minimum
#
@@ -848,12 +644,6 @@ syscall_event_drops:
# periodic metric snapshots (including stats and resource utilization) captured
# at regular intervals
#
# --- [Warning]
#
# Due to a regression (https://github.com/falcosecurity/falco/issues/2821) some metrics
# like `falco.host_num_cpus` or `falco.start_ts` will not be available when you use
# source plugins (like k8saudit).
#
# --- [Description]
#
# Consider these key points about the `metrics` feature in Falco:
@@ -935,22 +725,13 @@ syscall_event_drops:
# number of CPUs to determine overall usage. Memory metrics are provided in raw
# units (`kb` for `RSS`, `PSS` and `VSZ` or `bytes` for `container_memory_used`)
# and can be uniformly converted to megabytes (MB) using the
# `convert_memory_to_mb` functionality. In environments such as Kubernetes when
# deployed as daemonset, it is crucial to track Falco's container memory usage.
# To customize the path of the memory metric file, you can create an environment
# variable named `FALCO_CGROUP_MEM_PATH` and set it to the desired file path. By
# default, Falco uses the file `/sys/fs/cgroup/memory/memory.usage_in_bytes` to
# monitor container memory usage, which aligns with Kubernetes'
# `container_memory_working_set_bytes` metric. Finally, we emit the overall host
# CPU and memory usages, along with the total number of processes and open file
# descriptors (fds) on the host, obtained from the proc file system unrelated to
# Falco's monitoring. These metrics help assess Falco's usage in relation to the
# server's workload intensity.
#
# `state_counters_enabled`: Emit counters related to Falco's state engine, including
# added, removed threads or file descriptors (fds), and failed lookup, store, or
# retrieve actions in relation to Falco's underlying process cache table (threadtable).
# We also log the number of currently cached containers if applicable.
# `convert_memory_to_mb` functionality. In environments such as Kubernetes, it
# is crucial to track Falco's container memory usage. To customize the path of
# the memory metric file, you can create an environment variable named
# `FALCO_CGROUP_MEM_PATH` and set it to the desired file path. By default, Falco
# uses the file `/sys/fs/cgroup/memory/memory.usage_in_bytes` to monitor
# container memory usage, which aligns with Kubernetes'
# `container_memory_working_set_bytes` metric.
#
# `kernel_event_counters_enabled`: Emit kernel side event and drop counters, as
# an alternative to `syscall_event_drops`, but with some differences. These
@@ -983,21 +764,17 @@ metrics:
output_rule: true
# output_file: /tmp/falco_stats.jsonl
resource_utilization_enabled: true
state_counters_enabled: true
kernel_event_counters_enabled: true
libbpf_stats_enabled: true
convert_memory_to_mb: true
include_empty_values: false
#######################################
# Falco performance tuning (advanced) #
#######################################
# [DEPRECATED] `syscall_buf_size_preset` -> Replaced by `engine.<driver>.buf_size_preset` starting Falco 0.38!
#
# Deprecated in favor of engine.{kmod,ebpf,modern_ebpf}.buf_size_preset.
# This config is evaluated only if the default `engine` config block is not changed,
# otherwise it is ignored.
# [Stable] `syscall_buf_size_preset`
#
# --- [Description]
#
@@ -1049,14 +826,10 @@ metrics:
# if the default size is not suitable for your use case.
syscall_buf_size_preset: 4
# [DEPRECATED] `syscall_drop_failed_exit` -> Replaced by `engine.<driver>.drop_failed_exit` starting Falco 0.38!
#
# Deprecated in favor of engine.{kmod,ebpf,modern_ebpf}.drop_failed_exit.
# This config is evaluated only if the default `engine` config block is not changed,
# otherwise it is ignored.
# [Experimental] `syscall_drop_failed_exit`
#
# Enabling this option in Falco allows it to drop failed system call exit events
# in the kernel drivers before pushing them onto the ring buffer. This
# in the kernel driver before pushing them onto the ring buffer. This
# optimization can result in lower CPU usage and more efficient utilization of
# the ring buffer, potentially reducing the number of event losses. However, it
# is important to note that enabling this option also means sacrificing some
@@ -1178,11 +951,7 @@ base_syscalls:
custom_set: []
repair: false
# [DEPRECATED] `modern_bpf.cpus_for_each_syscall_buffer`, modern_bpf only -> Replaced by `engine.modern_ebpf.cpus_for_each_buffer` starting Falco 0.38!
#
# Deprecated in favor of engine.modern_ebpf.cpus_for_each_buffer.
# This config is evaluated only if the default `engine` config block is not changed,
# otherwise it is ignored.
# [Stable] `modern_bpf.cpus_for_each_syscall_buffer`, modern_bpf only
#
# --- [Description]
#
@@ -1262,6 +1031,35 @@ base_syscalls:
modern_bpf:
cpus_for_each_syscall_buffer: 2
#################################################
# Falco cloud orchestration systems integration #
#################################################
# [Stable] `metadata_download`
#
# When connected to an orchestrator like Kubernetes, Falco has the capability to
# collect metadata and enrich system call events with contextual data. The
# parameters mentioned here control the downloading process of this metadata.
#
# Please note that support for Mesos is deprecated, so these parameters
# currently apply only to Kubernetes. When using Falco with Kubernetes, you can
# enable this functionality by using the `-k` or `-K` command-line flag.
#
# However, it's worth mentioning that for important Kubernetes metadata fields
# such as namespace or pod name, these fields are automatically extracted from
# the container runtime, providing the necessary enrichment for common use cases
# of syscall-based threat detection.
#
# In summary, the `-k` flag is typically not required for most scenarios involving
# Kubernetes workload owner enrichment. The `-k` flag is primarily used when
# additional metadata is required beyond the standard fields, catering to more
# specific use cases, see https://falco.org/docs/reference/rules/supported-fields/#field-class-k8s.
metadata_download:
max_mb: 100
chunk_wait_us: 1000
watch_freq_sec: 1
# [Stable] Guidance for Kubernetes container engine command-line args settings
#
# Modern cloud environments, particularly Kubernetes, heavily rely on

View File

@@ -69,7 +69,7 @@ The allowed publishing channels are:
Both channels are equivalent and may publish the same artifacts. However, for historical reasons and to avoid confusion, the **`docker.io` registry should only be used for container images** and not for other kinds of artifacts (e.g., plugins, rules, etc.).
Mirrors are allowed and encouraged if they facilitate artifacts consumption by our users. This proposal recommends to enable mirrors on the major public OCI registry, such as [Amazon ECR](https://gallery.ecr.aws/) (which is already implentend in our infra at the time of writing).
Mirrors are allowed and encouraged if they facilitate artifacts consumption by our users. This proposal reccomends to enable mirrors on the major public OCI registry, such as [Amazon ECR](https://gallery.ecr.aws/) (which is already implentend in our infra at the time of writing).
Official **channels and mirrors must be listed at [falco.org](https://falco.org/)**.

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2021 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -41,6 +40,11 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux")
configure_file(rpm/postinstall.in rpm/postinstall COPYONLY)
configure_file(rpm/postuninstall.in rpm/postuninstall COPYONLY)
configure_file(rpm/preuninstall.in rpm/preuninstall COPYONLY)
# driver loader
configure_file(falco-driver-loader falco-driver-loader @ONLY)
install(PROGRAMS ${PROJECT_BINARY_DIR}/scripts/falco-driver-loader
DESTINATION ${FALCO_BIN_DIR} COMPONENT "${FALCO_COMPONENT_NAME}")
endif()
# Install Falcoctl config file
@@ -48,6 +52,5 @@ if (NOT WIN32 AND NOT APPLE AND NOT EMSCRIPTEN AND NOT MUSL_OPTIMIZED_BUILD)
if(NOT DEFINED FALCOCTL_ETC_DIR)
set(FALCOCTL_ETC_DIR "${CMAKE_INSTALL_FULL_SYSCONFDIR}/falcoctl")
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/falcoctl/falcoctl.yaml.in ${PROJECT_BINARY_DIR}/scripts/falcoctl/falcoctl.yaml)
install(FILES ${PROJECT_BINARY_DIR}/scripts/falcoctl/falcoctl.yaml DESTINATION "${FALCOCTL_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/falcoctl/falcoctl.yaml DESTINATION "${FALCOCTL_ETC_DIR}" COMPONENT "${FALCO_COMPONENT_NAME}")
endif()

View File

@@ -1,7 +1,6 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,8 +17,6 @@
#
chosen_driver=
chosen_unit=
CHOICE=
# Every time we call this script we want to stat from a clean state.
echo "[POST-INSTALL] Disable all possible 'falco' services:"
@@ -38,63 +35,39 @@ systemctl --system disable 'falcoctl-artifact-follow.service' || true
systemctl --system unmask falcoctl-artifact-follow.service || true
if [ "$1" = "configure" ]; then
case $FALCO_DRIVER_CHOICE in
kmod)
CHOICE=2
;;
ebpf)
CHOICE=3
;;
modern_ebpf)
CHOICE=4
;;
esac
if [ -z $CHOICE ] && [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
# If dialog is installed, create a dialog to let users choose the correct driver for them
CHOICE=$(dialog --clear --title "Falco drivers" --menu "Choose your preferred driver:" 12 55 4 \
1 "Manual configuration (no unit is started)" \
2 "Kmod" \
3 "eBPF" \
4 "Modern eBPF" \
if [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
# If dialog is installed, create a dialog to let users choose the correct driver for them
CHOICE=$(dialog --clear --title "Falco drivers" --menu "Choose your preferred driver:" 12 55 4 \
1 "Manual configuration (no unit is started)" \
2 "Kmod" \
3 "eBPF" \
4 "Modern eBPF" \
2>&1 >/dev/tty)
case $CHOICE in
2)
chosen_driver="kmod"
;;
3)
chosen_driver="bpf"
;;
4)
chosen_driver="modern-bpf"
;;
esac
if [ -n "$chosen_driver" ]; then
CHOICE=$(dialog --clear --title "Falcoctl" --menu "Do you want to follow automatic ruleset updates?" 10 40 2 \
1 "Yes" \
2 "No" \
2>&1 >/dev/tty)
fi
case $CHOICE in
2)
chosen_driver="kmod"
chosen_unit="kmod"
;;
3)
chosen_driver="ebpf"
chosen_unit="bpf"
;;
4)
chosen_driver="modern_ebpf"
chosen_unit="modern-bpf"
;;
esac
if [ -n "$CHOICE" ]; then
echo "[POST-INSTALL] Configure falcoctl driver type:"
falcoctl driver config --type $chosen_driver
CHOICE=
case $FALCOCTL_ENABLED in
no)
CHOICE=2
;;
esac
if [ -z $CHOICE ] && [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
CHOICE=$(dialog --clear --title "Falcoctl" --menu "Do you want to follow automatic ruleset updates?" 10 40 2 \
1 "Yes" \
2 "No" \
2>&1 >/dev/tty)
fi
case $CHOICE in
2)
# we don't want falcoctl enabled, we mask it
systemctl --system mask falcoctl-artifact-follow.service || true
# we don't want falcoctl enabled, we mask it
systemctl --system mask falcoctl-artifact-follow.service || true
;;
esac
fi
clear
fi
clear
fi
fi
set -e
@@ -102,25 +75,25 @@ set -e
echo "[POST-INSTALL] Trigger deamon-reload:"
systemctl --system daemon-reload || true
# If needed, try to load/compile the driver through falcoctl
# If needed, try to load/compile the driver through falco-driver-loader
case "$chosen_driver" in
"kmod")
# Only compile for kmod, in this way we use dkms
echo "[POST-INSTALL] Call 'falcoctl driver install for kmod:"
falcoctl driver install --download=false
echo "[POST-INSTALL] Call 'falco-driver-loader --compile module':"
falco-driver-loader --compile module
;;
"ebpf")
echo "[POST-INSTALL] Call 'falcoctl driver install for ebpf':"
falcoctl driver install
"bpf")
echo "[POST-INSTALL] Call 'falco-driver-loader bpf':"
falco-driver-loader bpf
;;
esac
if [ "$1" = "configure" ] || [ "$1" = "abort-upgrade" ] || [ "$1" = "abort-deconfigure" ] || [ "$1" = "abort-remove" ] ; then
if [ -n "$chosen_unit" ]; then
if [ -n "$chosen_driver" ]; then
# we do this in 2 steps because `enable --now` is not always supported
echo "[POST-INSTALL] Enable 'falco-$chosen_unit.service':"
systemctl --system enable "falco-$chosen_unit.service" || true
echo "[POST-INSTALL] Start 'falco-$chosen_unit.service':"
systemctl --system start "falco-$chosen_unit.service" || true
echo "[POST-INSTALL] Enable 'falco-$chosen_driver.service':"
systemctl --system enable "falco-$chosen_driver.service" || true
echo "[POST-INSTALL] Start 'falco-$chosen_driver.service':"
systemctl --system start "falco-$chosen_driver.service" || true
fi
fi

View File

@@ -1,7 +1,6 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");

View File

@@ -1,7 +1,6 @@
#!/bin/sh
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -31,7 +30,7 @@ case "$1" in
systemctl --system stop 'falco-custom.service' || true
systemctl --system stop 'falcoctl-artifact-follow.service' || true
echo "[PRE-REMOVE] Call 'falcoctl driver cleanup:'"
falcoctl driver cleanup
echo "[PRE-REMOVE] Call 'falco-driver-loader --clean:'"
falco-driver-loader --clean
;;
esac

865
scripts/falco-driver-loader Executable file
View File

@@ -0,0 +1,865 @@
#!/usr/bin/env bash
#
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Simple script that desperately tries to load the kernel instrumentation by
# looking for it in a bunch of ways. Convenient when running Falco inside
# a container or in other weird environments.
#
#
# Returns 1 if $cos_ver > $base_ver, 0 otherwise
#
cos_version_greater() {
if [[ $cos_ver == "${base_ver}" ]]; then
return 0
fi
#
# COS build numbers are in the format x.y.z
#
a=$(echo "${cos_ver}" | cut -d. -f1)
b=$(echo "${cos_ver}" | cut -d. -f2)
c=$(echo "${cos_ver}" | cut -d. -f3)
d=$(echo "${base_ver}" | cut -d. -f1)
e=$(echo "${base_ver}" | cut -d. -f2)
f=$(echo "${base_ver}" | cut -d. -f3)
# Test the first component
if [[ $a -gt $d ]]; then
return 1
elif [[ $d -gt $a ]]; then
return 0
fi
# Test the second component
if [[ $b -gt $e ]]; then
return 1
elif [[ $e -gt $b ]]; then
return 0
fi
# Test the third component
if [[ $c -gt $f ]]; then
return 1
elif [[ $f -gt $c ]]; then
return 0
fi
# If we get here, probably malformatted version string?
return 0
}
get_kernel_config() {
if [ -f /proc/config.gz ]; then
echo "* Found kernel config at /proc/config.gz"
KERNEL_CONFIG_PATH=/proc/config.gz
elif [ -f "/boot/config-${KERNEL_RELEASE}" ]; then
echo "* Found kernel config at /boot/config-${KERNEL_RELEASE}"
KERNEL_CONFIG_PATH=/boot/config-${KERNEL_RELEASE}
elif [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/boot/config-${KERNEL_RELEASE}" ]; then
echo "* Found kernel config at ${HOST_ROOT}/boot/config-${KERNEL_RELEASE}"
KERNEL_CONFIG_PATH="${HOST_ROOT}/boot/config-${KERNEL_RELEASE}"
elif [ -f "/usr/lib/ostree-boot/config-${KERNEL_RELEASE}" ]; then
echo "* Found kernel config at /usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
KERNEL_CONFIG_PATH="/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
elif [ -n "${HOST_ROOT}" ] && [ -f "${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}" ]; then
echo "* Found kernel config at ${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
KERNEL_CONFIG_PATH="${HOST_ROOT}/usr/lib/ostree-boot/config-${KERNEL_RELEASE}"
elif [ -f "/lib/modules/${KERNEL_RELEASE}/config" ]; then
# This code works both for native host and containers assuming that
# Dockerfile sets up the desired symlink /lib/modules -> $HOST_ROOT/lib/modules
echo "* Found kernel config at /lib/modules/${KERNEL_RELEASE}/config"
KERNEL_CONFIG_PATH="/lib/modules/${KERNEL_RELEASE}/config"
fi
if [ -z "${KERNEL_CONFIG_PATH}" ]; then
>&2 echo "Cannot find kernel config"
exit 1
fi
if [[ "${KERNEL_CONFIG_PATH}" == *.gz ]]; then
HASH=$(zcat "${KERNEL_CONFIG_PATH}" | md5sum - | cut -d' ' -f1)
else
HASH=$(md5sum "${KERNEL_CONFIG_PATH}" | cut -d' ' -f1)
fi
}
get_target_id() {
if [ -f "${HOST_ROOT}/etc/os-release" ]; then
# freedesktop.org and systemd
# shellcheck source=/dev/null
source "${HOST_ROOT}/etc/os-release"
OS_ID=$ID
elif [ -f "${HOST_ROOT}/etc/debian_version" ]; then
# Older debian distros
# fixme > Can this happen on older Ubuntu?
OS_ID=debian
elif [ -f "${HOST_ROOT}/etc/centos-release" ]; then
# Older CentOS distros
OS_ID=centos
elif [ -f "${HOST_ROOT}/etc/redhat-release" ]; then
# Older RHEL distros
OS_ID=rhel
else
# No target id can be determinand
TARGET_ID="undetermined"
return
fi
# Overwrite the OS_ID if /etc/VERSION file is present.
# Not sure if there is a better way to detect minikube.
if [ -f "${HOST_ROOT}/etc/VERSION" ]; then
OS_ID=minikube
fi
case "${OS_ID}" in
("amzn")
case "${VERSION_ID}" in
("2")
TARGET_ID="amazonlinux2"
;;
("2022")
TARGET_ID="amazonlinux2022"
;;
("2023")
TARGET_ID="amazonlinux2023"
;;
(*)
TARGET_ID="amazonlinux"
;;
esac
;;
("debian")
# Workaround: debian kernelreleases might now be actual kernel running;
# instead, they might be the Debian kernel package
# providing the compatible kernel ABI
# See https://lists.debian.org/debian-user/2017/03/msg00485.html
# Real kernel release is embedded inside the kernel version.
# Moreover, kernel arch, when present, is attached to the former,
# therefore make sure to properly take it and attach it to the latter.
# Moreover, we support 3 flavors for debian kernels: cloud, rt and normal.
# KERNEL-RELEASE will have a `-rt`, or `-cloud` if we are in one of these flavors.
# Manage it to download the correct driver.
#
# Example: KERNEL_RELEASE="5.10.0-0.deb10.22-rt-amd64" and `uname -v`="5.10.178-3"
# should lead to: KERNEL_RELEASE="5.10.178-3-rt-amd64"
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
local ARCH_extra=""
if [[ $KERNEL_RELEASE =~ -?(rt-|cloud-|)(amd64|arm64) ]];
then
ARCH_extra="-${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
fi
if [[ ${DRIVER_KERNEL_VERSION} =~ ([0-9]+\.[0-9]+\.[0-9]+\-[0-9]+) ]];
then
KERNEL_RELEASE="${BASH_REMATCH[1]}${ARCH_extra}"
fi
;;
("ubuntu")
# Extract the flavor from the kernelrelease
# Examples:
# 5.0.0-1028-aws-5.0 -> ubuntu-aws
# 5.15.0-1009-aws -> ubuntu-aws
if [[ $KERNEL_RELEASE =~ -([a-zA-Z]+)(-.*)?$ ]];
then
TARGET_ID="ubuntu-${BASH_REMATCH[1]}"
else
TARGET_ID="ubuntu-generic"
fi
# In the case that the kernelversion isn't just a number
# we keep also the remaining part excluding `-Ubuntu`.
# E.g.:
# from the following `uname -v` result
# `#26~22.04.1-Ubuntu SMP Mon Apr 24 01:58:15 UTC 2023`
# we obtain the kernelversion`26~22.04.1`
if [[ ${DRIVER_KERNEL_VERSION} =~ (^\#[0-9]+\~[^-]*-Ubuntu .*$) ]];
then
KERNEL_VERSION=$(echo "${DRIVER_KERNEL_VERSION}" | sed 's/#\([^-\\ ]*\).*/\1/g')
fi
;;
("flatcar")
KERNEL_RELEASE="${VERSION_ID}"
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
("minikube")
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
# Extract the minikube version. Ex. With minikube version equal to "v1.26.0-1655407986-14197" the extracted version
# will be "1.26.0"
if [[ $(cat ${HOST_ROOT}/etc/VERSION) =~ ([0-9]+(\.[0-9]+){2}) ]]; then
# kernel version for minikube is always in "1_minikubeversion" format. Ex "1_1.26.0".
KERNEL_VERSION="1_${BASH_REMATCH[1]}"
else
echo "* Unable to extract minikube version from ${HOST_ROOT}/etc/VERSION"
exit 1
fi
;;
("bottlerocket")
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
# variant_id has been sourced from os-release. Get only the first variant part
if [[ -n ${VARIANT_ID} ]]; then
# take just first part (eg: VARIANT_ID=aws-k8s-1.15 -> aws)
VARIANT_ID_CUT=${VARIANT_ID%%-*}
fi
# version_id has been sourced from os-release. Build a kernel version like: 1_1.11.0-aws
KERNEL_VERSION="1_${VERSION_ID}-${VARIANT_ID_CUT}"
;;
("talos")
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
# version_id has been sourced from os-release. Build a kernel version like: 1_1.4.1
KERNEL_VERSION="1_${VERSION_ID}"
;;
(*)
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
esac
}
flatcar_relocate_tools() {
local -a tools=(
scripts/basic/fixdep
scripts/mod/modpost
tools/objtool/objtool
)
local -r hostld=$(ls /host/usr/lib64/ld-linux-*.so.*)
local -r kdir=/lib/modules/$(ls /lib/modules/)/build
echo "** Found host dl interpreter: ${hostld}"
for host_tool in ${tools[@]}; do
t=${host_tool}
tool=$(basename $t)
tool_dir=$(dirname $t)
host_tool=${kdir}/${host_tool}
if [ ! -f ${host_tool} ]; then
continue
fi
umount ${host_tool} 2>/dev/null || true
mkdir -p /tmp/${tool_dir}/
cp -a ${host_tool} /tmp/${tool_dir}/
echo "** Setting host dl interpreter for $host_tool"
patchelf --set-interpreter ${hostld} --set-rpath /host/usr/lib64 /tmp/${tool_dir}/${tool}
mount -o bind /tmp/${tool_dir}/${tool} ${host_tool}
done
}
load_kernel_module_compile() {
# Skip dkms on UEK hosts because it will always fail
if [[ ${DRIVER_KERNEL_RELEASE} == *uek* ]]; then
>&2 echo "Skipping because the dkms install always fail (on UEK hosts)"
return
fi
if ! hash dkms >/dev/null 2>&1; then
>&2 echo "This program requires dkms"
return
fi
if [ "${TARGET_ID}" == "flatcar" ]; then
KERNEL_RELEASE=${DRIVER_KERNEL_RELEASE}
echo "* Flatcar detected (version ${VERSION_ID}); relocating kernel tools"
flatcar_relocate_tools
fi
# Try to compile using all the available gcc versions
for CURRENT_GCC in $(ls "$(dirname "$(which gcc)")"/gcc*); do
# Filter away gcc-{ar,nm,...}
# Only gcc compiler has `-print-search-dirs` option.
${CURRENT_GCC} -print-search-dirs 2>&1 | grep "install:"
if [ "$?" -ne "0" ]; then
continue
fi
echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
echo "#!/usr/bin/env bash" > "${TMPDIR}/falco-dkms-make"
echo "make CC=${CURRENT_GCC} \$@" >> "${TMPDIR}/falco-dkms-make"
chmod +x "${TMPDIR}/falco-dkms-make"
if dkms install --directive="MAKE='${TMPDIR}/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "* ${DRIVER_NAME} module installed in dkms"
KO_FILE="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}"
if [ -f "$KO_FILE.ko" ]; then
KO_FILE="$KO_FILE.ko"
elif [ -f "$KO_FILE.ko.gz" ]; then
KO_FILE="$KO_FILE.ko.gz"
elif [ -f "$KO_FILE.ko.xz" ]; then
KO_FILE="$KO_FILE.ko.xz"
elif [ -f "$KO_FILE.ko.zst" ]; then
KO_FILE="$KO_FILE.ko.zst"
else
>&2 echo "${DRIVER_NAME} module file not found"
return
fi
echo "* ${DRIVER_NAME} module found: ${KO_FILE}"
echo "* Trying to insmod"
chcon -t modules_object_t "$KO_FILE" > /dev/null 2>&1 || true
if insmod "$KO_FILE" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded in dkms"
exit 0
fi
echo "* Unable to insmod ${DRIVER_NAME} module"
else
DKMS_LOG="/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/build/make.log"
if [ -f "${DKMS_LOG}" ]; then
echo "* Running dkms build failed, dumping ${DKMS_LOG} (with GCC ${CURRENT_GCC})"
cat "${DKMS_LOG}"
else
echo "* Running dkms build failed, couldn't find ${DKMS_LOG} (with GCC ${CURRENT_GCC})"
fi
fi
done
}
load_kernel_module_download() {
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
local URL=$(echo "${1}/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" | sed s/+/%2B/g)
echo "* Trying to download a prebuilt ${DRIVER_NAME} module from ${URL}"
if curl -L --create-dirs ${FALCO_DRIVER_CURL_OPTIONS} -o "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
echo "* Download succeeded"
chcon -t modules_object_t "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
if insmod "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}"; then
echo "* Success: ${DRIVER_NAME} module found and inserted"
exit 0
fi
>&2 echo "Unable to insmod the prebuilt ${DRIVER_NAME} module"
else
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} module"
return
fi
}
print_clean_termination() {
echo
echo "[SUCCESS] Cleaning phase correctly terminated."
echo
echo "================ Cleaning phase ================"
echo
}
print_filename_components() {
echo " - driver name: ${DRIVER_NAME}"
echo " - target identifier: ${TARGET_ID}"
echo " - kernel release: ${KERNEL_RELEASE}"
echo " - kernel version: ${KERNEL_VERSION}"
}
print_as_env_vars() {
echo "ARCH=\"${ARCH}\""
echo "KERNEL_RELEASE=\"${KERNEL_RELEASE}\""
echo "KERNEL_VERSION=\"${KERNEL_VERSION}\""
echo "ENABLE_COMPILE=\"${ENABLE_COMPILE}\""
echo "ENABLE_DOWNLOAD=\"${ENABLE_DOWNLOAD}\""
echo "TARGET_ID=\"${TARGET_ID}\""
echo "DRIVER=\"${DRIVER}\""
echo "DRIVERS_REPO=\"${DRIVERS_REPO}\""
echo "DRIVER_VERSION=\"${DRIVER_VERSION}\""
echo "DRIVER_NAME=\"${DRIVER_NAME}\""
echo "FALCO_VERSION=\"${FALCO_VERSION}\""
}
clean_kernel_module() {
echo
echo "================ Cleaning phase ================"
echo
if ! hash lsmod > /dev/null 2>&1; then
>&2 echo "This program requires lsmod."
exit 1
fi
if ! hash rmmod > /dev/null 2>&1; then
>&2 echo "This program requires rmmod."
exit 1
fi
KMOD_NAME=$(echo "${DRIVER_NAME}" | tr "-" "_")
echo "* 1. Check if kernel module '${KMOD_NAME}' is still loaded:"
if ! lsmod | cut -d' ' -f1 | grep -qx "${KMOD_NAME}"; then
echo "- OK! There is no '${KMOD_NAME}' module loaded."
echo
fi
# Wait 50s = MAX_RMMOD_WAIT * 5s
MAX_RMMOD_WAIT=10
# Remove kernel module if is still loaded.
while lsmod | cut -d' ' -f1 | grep -qx "${KMOD_NAME}" && [ $MAX_RMMOD_WAIT -gt 0 ]; do
echo "- Kernel module '${KMOD_NAME}' is still loaded."
echo "- Trying to unload it with 'rmmod ${KMOD_NAME}'..."
if rmmod ${KMOD_NAME}; then
echo "- OK! Unloading '${KMOD_NAME}' module succeeded."
echo
else
echo "- Nothing to do...'falco-driver-loader' will wait until you remove the kernel module to have a clean termination."
echo "- Check that no process is using the kernel module with 'lsmod | grep ${KMOD_NAME}'."
echo "- Sleep 5 seconds..."
echo
((--MAX_RMMOD_WAIT))
sleep 5
fi
done
if [ ${MAX_RMMOD_WAIT} -eq 0 ]; then
echo "[WARNING] '${KMOD_NAME}' module is still loaded, you could have incompatibility issues."
echo
fi
if ! hash dkms >/dev/null 2>&1; then
echo "- Skipping dkms remove (dkms not found)."
print_clean_termination
return
fi
# Remove all versions of this module from dkms.
echo "* 2. Check all versions of kernel module '${KMOD_NAME}' in dkms:"
DRIVER_VERSIONS=$(dkms status -m "${KMOD_NAME}" | tr -d "," | tr -d ":" | tr "/" " " | cut -d' ' -f2)
if [ -z "${DRIVER_VERSIONS}" ]; then
echo "- OK! There are no '${KMOD_NAME}' module versions in dkms."
else
echo "- There are some versions of '${KMOD_NAME}' module in dkms."
echo
echo "* 3. Removing all the following versions from dkms:"
echo "${DRIVER_VERSIONS}"
echo
fi
for CURRENT_VER in ${DRIVER_VERSIONS}; do
echo "- Removing ${CURRENT_VER}..."
if dkms remove -m ${KMOD_NAME} -v "${CURRENT_VER}" --all; then
echo
echo "- OK! Removing '${CURRENT_VER}' succeeded."
echo
else
echo "[WARNING] Removing '${KMOD_NAME}' version '${CURRENT_VER}' failed."
fi
done
print_clean_termination
}
load_kernel_module() {
clean_kernel_module
echo "* Looking for a ${DRIVER_NAME} module locally (kernel ${KERNEL_RELEASE})"
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
echo "* Filename '${FALCO_KERNEL_MODULE_FILENAME}' is composed of:"
print_filename_components
if [ -f "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" ]; then
echo "* Found a prebuilt ${DRIVER_NAME} module at ${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}, loading it"
chcon -t modules_object_t "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
insmod "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module found and inserted"
exit $?
fi
if [ -n "$ENABLE_DOWNLOAD" ]; then
IFS=", " read -r -a urls <<< "${DRIVERS_REPO}"
for url in "${urls[@]}"; do
load_kernel_module_download $url
done
fi
if [ -n "$ENABLE_COMPILE" ]; then
load_kernel_module_compile
fi
# Last try (might load a previous driver version)
echo "* Trying to load a system ${DRIVER_NAME} module, if present"
if modprobe "${DRIVER_NAME}" > /dev/null 2>&1; then
echo "* Success: ${DRIVER_NAME} module found and loaded with modprobe"
exit 0
fi
# Not able to download a prebuilt module nor to compile one on-the-fly
>&2 echo "Consider compiling your own ${DRIVER_NAME} driver and loading it or getting in touch with the Falco community"
exit 1
}
load_bpf_probe_compile() {
local BPF_KERNEL_SOURCES_URL=""
local STRIP_COMPONENTS=1
customize_kernel_build() {
if [ -n "${KERNEL_EXTRA_VERSION}" ]; then
sed -i "s/LOCALVERSION=\"\"/LOCALVERSION=\"${KERNEL_EXTRA_VERSION}\"/" .config
fi
make olddefconfig > /dev/null
make modules_prepare > /dev/null
}
if [ "${TARGET_ID}" == "flatcar" ]; then
KERNEL_RELEASE=${DRIVER_KERNEL_RELEASE}
echo "* Flatcar detected (version ${VERSION_ID}); relocating kernel tools"
flatcar_relocate_tools
fi
if [ "${TARGET_ID}" == "cos" ]; then
echo "* COS detected (build ${BUILD_ID}), using COS kernel headers"
BPF_KERNEL_SOURCES_URL="https://storage.googleapis.com/cos-tools/${BUILD_ID}/kernel-headers.tgz"
KERNEL_EXTRA_VERSION="+"
STRIP_COMPONENTS=0
customize_kernel_build() {
pushd usr/src/* > /dev/null || exit
# Note: this overrides the KERNELDIR set while untarring the tarball
KERNELDIR=$(pwd)
export KERNELDIR
sed -i '/^#define randomized_struct_fields_start struct {$/d' include/linux/compiler-clang.h
sed -i '/^#define randomized_struct_fields_end };$/d' include/linux/compiler-clang.h
popd > /dev/null || exit
# Might need to configure our own sources depending on COS version
cos_ver=${BUILD_ID}
base_ver=11553.0.0
cos_version_greater
greater_ret=$?
if [[ greater_ret -eq 1 ]]; then
export KBUILD_EXTRA_CPPFLAGS=-DCOS_73_WORKAROUND
fi
}
fi
if [ "${TARGET_ID}" == "minikube" ]; then
MINIKUBE_VERSION="$(cat "${HOST_ROOT}/etc/VERSION")"
echo "* Minikube detected (${MINIKUBE_VERSION}), using linux kernel sources for minikube kernel"
local kernel_version
kernel_version=${DRIVER_KERNEL_RELEASE}
local -r kernel_version_major=$(echo "${kernel_version}" | cut -d. -f1)
local -r kernel_version_minor=$(echo "${kernel_version}" | cut -d. -f2)
local -r kernel_version_patch=$(echo "${kernel_version}" | cut -d. -f3)
if [ "${kernel_version_patch}" == "0" ]; then
kernel_version="${kernel_version_major}.${kernel_version_minor}"
fi
BPF_KERNEL_SOURCES_URL="http://mirrors.edge.kernel.org/pub/linux/kernel/v${kernel_version_major}.x/linux-${kernel_version}.tar.gz"
fi
if [ -n "${BPF_USE_LOCAL_KERNEL_SOURCES}" ]; then
local -r kernel_version_major=$(echo "${DRIVER_KERNEL_RELEASE}" | cut -d. -f1)
local -r kernel_version=$(echo "${DRIVER_KERNEL_RELEASE}" | cut -d- -f1)
KERNEL_EXTRA_VERSION="-$(echo "${DRIVER_KERNEL_RELEASE}" | cut -d- -f2)"
echo "* Using downloaded kernel sources for kernel version ${kernel_version}..."
BPF_KERNEL_SOURCES_URL="http://mirrors.edge.kernel.org/pub/linux/kernel/v${kernel_version_major}.x/linux-${kernel_version}.tar.gz"
fi
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
get_kernel_config
echo "* Downloading ${BPF_KERNEL_SOURCES_URL}"
mkdir -p /tmp/kernel
cd /tmp/kernel || exit
cd "$(mktemp -d -p /tmp/kernel)" || exit
if ! curl -L -o kernel-sources.tgz --create-dirs ${FALCO_DRIVER_CURL_OPTIONS} "${BPF_KERNEL_SOURCES_URL}"; then
>&2 echo "Unable to download the kernel sources"
return
fi
echo "* Extracting kernel sources"
mkdir kernel-sources && tar xf kernel-sources.tgz -C kernel-sources --strip-components "${STRIP_COMPONENTS}"
cd kernel-sources || exit
KERNELDIR=$(pwd)
export KERNELDIR
if [[ "${KERNEL_CONFIG_PATH}" == *.gz ]]; then
zcat "${KERNEL_CONFIG_PATH}" > .config
else
cat "${KERNEL_CONFIG_PATH}" > .config
fi
echo "* Configuring kernel"
customize_kernel_build
fi
echo "* Trying to compile the eBPF probe (${BPF_PROBE_FILENAME})"
make -C "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf" > /dev/null
mkdir -p "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}"
mv "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf/probe.o" "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}"
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
rm -r /tmp/kernel
fi
}
load_bpf_probe_download() {
local URL
URL=$(echo "${1}/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" | sed s/+/%2B/g)
echo "* Trying to download a prebuilt eBPF probe from ${URL}"
if ! curl -L --create-dirs ${FALCO_DRIVER_CURL_OPTIONS} -o "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" "${URL}"; then
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} eBPF probe"
return 1
fi
return 0
}
load_bpf_probe() {
if [ ! -d /sys/kernel/debug/tracing ]; then
echo "* Mounting debugfs"
mount -t debugfs nodev /sys/kernel/debug
fi
BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"
echo "* Filename '${BPF_PROBE_FILENAME}' is composed of:"
print_filename_components
if [ -n "$ENABLE_DOWNLOAD" ]; then
if [ -f "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" ]; then
echo "* Skipping download, eBPF probe is already present in ${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}"
else
IFS=", " read -r -a urls <<< "${DRIVERS_REPO}"
for url in "${urls[@]}"; do
load_bpf_probe_download $url
if [ $? -eq 0 ]; then
break
fi
done
fi
fi
if [ -n "$ENABLE_COMPILE" ]; then
if [ -f "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" ]; then
echo "* Skipping compilation, eBPF probe is already present in ${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}"
else
load_bpf_probe_compile
fi
fi
if [ -f "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" ]; then
echo "* eBPF probe located in ${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}"
ln -sf "${HOME}/.falco/${DRIVER_VERSION}/${ARCH}/${BPF_PROBE_FILENAME}" "${HOME}/.falco/${DRIVER_NAME}-bpf.o" \
&& echo "* Success: eBPF probe symlinked to ${HOME}/.falco/${DRIVER_NAME}-bpf.o"
exit $?
else
>&2 echo "Unable to load the ${DRIVER_NAME} eBPF probe"
exit 1
fi
}
print_usage() {
echo ""
echo "Usage:"
echo " falco-driver-loader [driver] [options]"
echo ""
echo "Available drivers:"
echo " module kernel module (default)"
echo " bpf eBPF probe"
echo ""
echo "Options:"
echo " --help show brief help"
echo " --clean try to remove an already present driver installation"
echo " --compile try to compile the driver locally (default true)"
echo " --download try to download a prebuilt driver (default true)"
echo " --source-only skip execution and allow sourcing in another script using `. falco-driver-loader`"
echo " --print-env skip execution and print env variables for other tools to consume"
echo ""
echo "Environment variables:"
echo " DRIVERS_REPO specify different URL(s) where to look for prebuilt Falco drivers (comma separated)"
echo " DRIVER_NAME specify a different name for the driver"
echo " DRIVER_INSECURE_DOWNLOAD whether you want to allow insecure downloads or not"
echo " DRIVER_CURL_OPTIONS specify additional options to be passed to curl command used to download Falco drivers"
echo " DRIVER_KERNEL_RELEASE specify the kernel release for which to download/build the driver in the same format used by 'uname -r' (e.g. '6.1.0-10-cloud-amd64')"
echo " DRIVER_KERNEL_VERSION specify the kernel version for which to download/build the driver in the same format used by 'uname -v' (e.g. '#1 SMP PREEMPT_DYNAMIC Debian 6.1.38-2 (2023-07-27)')"
echo ""
echo "Versions:"
echo " Falco version ${FALCO_VERSION}"
echo " Driver version ${DRIVER_VERSION}"
echo ""
}
ARCH=$(uname -m)
DRIVER_KERNEL_RELEASE=${DRIVER_KERNEL_RELEASE:-$(uname -r)}
KERNEL_RELEASE=${DRIVER_KERNEL_RELEASE}
if ! hash sed > /dev/null 2>&1; then
>&2 echo "This program requires sed"
exit 1
fi
DRIVER_KERNEL_VERSION=${DRIVER_KERNEL_VERSION:-$(uname -v)}
KERNEL_VERSION=$(echo "${DRIVER_KERNEL_VERSION}" | sed 's/#\([[:digit:]]\+\).*/\1/')
DRIVERS_REPO=${DRIVERS_REPO:-"@DRIVERS_REPO@"}
FALCO_DRIVER_CURL_OPTIONS="-fsS --connect-timeout 5 --max-time 60 --retry 3 --retry-max-time 120"
if [ -n "$DRIVER_INSECURE_DOWNLOAD" ]
then
FALCO_DRIVER_CURL_OPTIONS+=" -k"
fi
FALCO_DRIVER_CURL_OPTIONS+=" "${DRIVER_CURL_OPTIONS}
if [[ -z "$MAX_RMMOD_WAIT" ]]; then
MAX_RMMOD_WAIT=60
fi
DRIVER_VERSION=${DRIVER_VERSION:-"@DRIVER_VERSION@"}
DRIVER_NAME=${DRIVER_NAME:-"@DRIVER_NAME@"}
FALCO_VERSION="@FALCO_VERSION@"
TARGET_ID=
get_target_id
DRIVER="module"
if [ -v FALCO_BPF_PROBE ]; then
DRIVER="bpf"
fi
TMPDIR=${TMPDIR:-"/tmp"}
ENABLE_COMPILE=
ENABLE_DOWNLOAD=
clean=
has_args=
has_opts=
print_env=
source_only=
while test $# -gt 0; do
case "$1" in
module|bpf)
if [ -n "$has_args" ]; then
>&2 echo "Only one driver per invocation"
print_usage
exit 1
else
DRIVER="$1"
has_args="true"
shift
fi
;;
-h|--help)
print_usage
exit 0
;;
--clean)
clean="true"
shift
;;
--compile)
ENABLE_COMPILE="yes"
has_opts="true"
shift
;;
--download)
ENABLE_DOWNLOAD="yes"
has_opts="true"
shift
;;
--source-only)
source_only="true"
shift
;;
--print-env)
print_env="true"
shift
;;
--*)
>&2 echo "Unknown option: $1"
print_usage
exit 1
;;
*)
>&2 echo "Unknown driver: $1"
print_usage
exit 1
;;
esac
done
if [ -z "$has_opts" ]; then
ENABLE_COMPILE="yes"
ENABLE_DOWNLOAD="yes"
fi
if [ -n "$source_only" ]; then
# Return or exit, depending if we've been sourced.
(return 0 2>/dev/null) && return || exit 0
fi
if [ -n "$print_env" ]; then
print_as_env_vars
exit 0
fi
echo "* Running falco-driver-loader for: falco version=${FALCO_VERSION}, driver version=${DRIVER_VERSION}, arch=${ARCH}, kernel release=${KERNEL_RELEASE}, kernel version=${KERNEL_VERSION}"
if [ "$(id -u)" != 0 ]; then
>&2 echo "This program must be run as root (or with sudo)"
exit 1
fi
if [ "$TARGET_ID" = "undetermined" ]; then
if [ -n "$ENABLE_COMPILE" ]; then
ENABLE_DOWNLOAD=
>&2 echo "Detected an unsupported target system, please get in touch with the Falco community. Trying to compile anyway."
else
>&2 echo "Detected an unsupported target system, please get in touch with the Falco community."
exit 1
fi
fi
if [ -n "$clean" ]; then
if [ -n "$has_opts" ]; then
>&2 echo "Cannot use --clean with other options"
exit 1
fi
echo "* Running falco-driver-loader with: driver=$DRIVER, clean=yes"
case $DRIVER in
module)
clean_kernel_module
;;
bpf)
>&2 echo "--clean not supported for driver=bpf"
exit 1
esac
else
if ! hash curl > /dev/null 2>&1; then
>&2 echo "This program requires curl"
exit 1
fi
echo "* Running falco-driver-loader with: driver=$DRIVER, compile=${ENABLE_COMPILE:-"no"}, download=${ENABLE_DOWNLOAD:-"no"}"
case $DRIVER in
module)
load_kernel_module
;;
bpf)
load_bpf_probe
;;
esac
fi

View File

@@ -1,10 +1,3 @@
driver:
type: "kmod"
name: "@DRIVER_NAME@"
repos:
- "@DRIVERS_REPO@"
version: "@DRIVER_VERSION@"
hostroot: "/"
artifact:
follow:
every: 6h0m0s

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2020 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,8 +16,6 @@
#
chosen_driver=
chosen_unit=
CHOICE=
# Every time we call this script we want to stat from a clean state.
echo "[POST-INSTALL] Disable all possible enabled 'falco' service:"
@@ -37,18 +34,7 @@ systemctl --system disable 'falcoctl-artifact-follow.service' || true
systemctl --system unmask falcoctl-artifact-follow.service || true
if [ $1 -ge 1 ]; then
case $FALCO_DRIVER_CHOICE in
kmod)
CHOICE=2
;;
ebpf)
CHOICE=3
;;
modern_ebpf)
CHOICE=4
;;
esac
if [ -z $CHOICE ] && [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
if [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
# If dialog is installed, create a dialog to let users choose the correct driver for them
CHOICE=$(dialog --clear --title "Falco drivers" --menu "Choose your preferred driver:" 12 55 4 \
1 "Manual configuration (no unit is started)" \
@@ -56,44 +42,31 @@ if [ $1 -ge 1 ]; then
3 "eBPF" \
4 "Modern eBPF" \
2>&1 >/dev/tty)
fi
case $CHOICE in
2)
chosen_driver="kmod"
chosen_unit="kmod"
;;
3)
chosen_driver="ebpf"
chosen_unit="bpf"
;;
4)
chosen_driver="modern_ebpf"
chosen_unit="modern-bpf"
;;
esac
if [ -n "$CHOICE" ]; then
echo "[POST-INSTALL] Configure falcoctl driver type:"
falcoctl driver config --type $chosen_driver
CHOICE=
case $FALCOCTL_ENABLED in
no)
CHOICE=2
;;
esac
if [ -z $CHOICE ] && [ -x /usr/bin/dialog ] && [ "${FALCO_FRONTEND}" != "noninteractive" ]; then
CHOICE=$(dialog --clear --title "Falcoctl" --menu "Do you want to follow automatic ruleset updates?" 10 40 2 \
1 "Yes" \
2 "No" \
2>&1 >/dev/tty)
fi
case $CHOICE in
2)
# we don't want falcoctl enabled, we mask it
systemctl --system mask falcoctl-artifact-follow.service || true
;;
chosen_driver="kmod"
;;
3)
chosen_driver="bpf"
;;
4)
chosen_driver="modern-bpf"
;;
esac
fi
clear
if [ -n "$chosen_driver" ]; then
CHOICE=$(dialog --clear --title "Falcoctl" --menu "Do you want to follow automatic ruleset updates?" 10 40 2 \
1 "Yes" \
2 "No" \
2>&1 >/dev/tty)
case $CHOICE in
2)
# we don't want falcoctl enabled, we mask it
systemctl --system mask falcoctl-artifact-follow.service || true
;;
esac
fi
clear
fi
fi
set -e
@@ -101,16 +74,16 @@ set -e
echo "[POST-INSTALL] Trigger deamon-reload:"
systemctl --system daemon-reload || true
# If needed, try to load/compile the driver through falcoctl
# If needed, try to load/compile the driver through falco-driver-loader
case "$chosen_driver" in
"kmod")
# Only compile for kmod, in this way we use dkms
echo "[POST-INSTALL] Call 'falcoctl driver install for kmod:"
falcoctl driver install --download=false
echo "[POST-INSTALL] Call 'falco-driver-loader --compile module':"
falco-driver-loader --compile module
;;
"ebpf")
echo "[POST-INSTALL] Call 'falcoctl driver install for ebpf':"
falcoctl driver install
"bpf")
echo "[POST-INSTALL] Call 'falco-driver-loader bpf':"
falco-driver-loader bpf
;;
esac
@@ -121,14 +94,14 @@ esac
# systemd_post macro expands to
# if postinst:
# `systemd-update-helper install-system-units <service>`
%systemd_post "falco-$chosen_unit.service"
%systemd_post "falco-$chosen_driver.service"
# post install/upgrade mirrored from .deb
if [ $1 -ge 1 ]; then
if [ -n "$chosen_unit" ]; then
echo "[POST-INSTALL] Enable 'falco-$chosen_unit.service':"
systemctl --system enable "falco-$chosen_unit.service" || true
echo "[POST-INSTALL] Start 'falco-$chosen_unit.service':"
systemctl --system start "falco-$chosen_unit.service" || true
if [ -n "$chosen_driver" ]; then
echo "[POST-INSTALL] Enable 'falco-$chosen_driver.service':"
systemctl --system enable "falco-$chosen_driver.service" || true
echo "[POST-INSTALL] Start 'falco-$chosen_driver.service':"
systemctl --system start "falco-$chosen_driver.service" || true
fi
fi

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2022 The Falco Authors.
#
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,8 +24,8 @@ systemctl --system stop 'falco-modern-bpf.service' || true
systemctl --system stop 'falco-custom.service' || true
systemctl --system stop 'falcoctl-artifact-follow.service' || true
echo "[PRE-REMOVE] Call 'falcoctl driver cleanup:'"
falcoctl driver cleanup
echo "[PRE-REMOVE] Call 'falco-driver-loader --clean:'"
falco-driver-loader --clean
# validate rpm macros by `rpm -qp --scripts <rpm>`
# RPM scriptlets: https://docs.fedoraproject.org/en-US/packaging-guidelines/Scriptlets/#_systemd

View File

@@ -7,7 +7,8 @@ Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/falco -o engine.kind=ebpf
Environment=FALCO_BPF_PROBE=
ExecStart=/usr/bin/falco
ExecReload=kill -1 $MAINPID
UMask=0077
TimeoutSec=30

View File

@@ -9,7 +9,7 @@ Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/falco -o engine.kind=kmod
ExecStart=/usr/bin/falco
ExecReload=kill -1 $MAINPID
UMask=0077
TimeoutSec=30

View File

@@ -7,7 +7,7 @@ Wants=falcoctl-artifact-follow.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/falco -o engine.kind=modern_ebpf
ExecStart=/usr/bin/falco --modern-bpf
ExecReload=kill -1 $MAINPID
UMask=0077
TimeoutSec=30

View File

@@ -1,44 +0,0 @@
# MIT License
#
# Copyright (c) 2022 raptor
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
rules:
- id: raptor-insecure-api-gets
metadata:
author: Marco Ivaldi <raptor@0xdeadbeef.info>
references:
- https://cwe.mitre.org/data/definitions/242
- https://cwe.mitre.org/data/definitions/120
confidence: HIGH
message: >-
The program calls a function that can never be guaranteed to work
safely.
Certain functions behave in dangerous ways regardless of how they are
used. Functions in this category were often implemented without
taking security concerns into account. The gets() function is unsafe
because it does not perform bounds checking on the size of its input.
An attacker can easily send arbitrarily-sized input to gets() and
overflow the destination buffer.
severity: ERROR
languages:
- c
- cpp
pattern: gets(...)

View File

@@ -1,57 +0,0 @@
# MIT License
#
# Copyright (c) 2022 raptor
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
rules:
- id: raptor-insecure-api-sprintf-vsprintf
metadata:
author: Marco Ivaldi <raptor@0xdeadbeef.info>
references:
- https://cwe.mitre.org/data/definitions/676
- https://cwe.mitre.org/data/definitions/120
- https://cwe.mitre.org/data/definitions/787
- https://g.co/kgs/PCHQjJ
confidence: HIGH
message: >-
The program invokes a potentially dangerous function that could
introduce a vulnerability if it is used incorrectly, but the function
can also be used safely.
A buffer overflow condition exists when a program attempts to put
more data in a buffer than it can hold, or when a program attempts to
put data in a memory area outside of the boundaries of a buffer. The
simplest type of error, and the most common cause of buffer
overflows, is the classic case in which the program copies the buffer
without restricting how much is copied. Other variants exist, but the
existence of a classic overflow strongly suggests that the programmer
is not considering even the most basic of security protections.
severity: ERROR
languages:
- c
- cpp
patterns:
- pattern-either:
- pattern: sprintf($BUF, $FMT, ...)
- pattern: vsprintf($BUF, $FMT, ...)
# swprintf() and vswprintf() should have a size parameter
- metavariable-regex:
metavariable: $FMT
# NOTE: some format string modifiers are not handled
regex: '(".*%l?s.*"|".*%S.*"|[a-zA-Z_][a-zA-Z0-9_]*)'

View File

@@ -1,59 +0,0 @@
# MIT License
#
# Copyright (c) 2022 raptor
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
rules:
- id: raptor-insecure-api-strcpy-stpcpy-strcat
metadata:
author: Marco Ivaldi <raptor@0xdeadbeef.info>
references:
- https://cwe.mitre.org/data/definitions/676
- https://cwe.mitre.org/data/definitions/120
- https://cwe.mitre.org/data/definitions/787
- https://g.co/kgs/PCHQjJ
confidence: HIGH
message: >-
The program invokes a potentially dangerous function that could
introduce a vulnerability if it is used incorrectly, but the function
can also be used safely.
A buffer overflow condition exists when a program attempts to put
more data in a buffer than it can hold, or when a program attempts to
put data in a memory area outside of the boundaries of a buffer. The
simplest type of error, and the most common cause of buffer
overflows, is the classic case in which the program copies the buffer
without restricting how much is copied. Other variants exist, but the
existence of a classic overflow strongly suggests that the programmer
is not considering even the most basic of security protections.
In the Falco codebase you can use the safer alternative strlcpy().
severity: ERROR
languages:
- c
- cpp
patterns:
- pattern-either:
- pattern: strcpy(...)
- pattern: stpcpy(...)
- pattern: strcat(...)
- pattern: wcscpy(...)
- pattern: wcpcpy(...)
- pattern: wcscat(...)
- pattern-not: $FUN($BUF, "...", ...)

View File

@@ -1,18 +0,0 @@
rules:
- id: falco-insecure-api-strn
metadata:
references:
- https://cwe.mitre.org/data/definitions/120
confidence: HIGH
message: >-
The libc function strncpy and strncat are not used in the Falco codebase as they are error prone.
Read more: https://www.cisa.gov/uscert/bsi/articles/knowledge/coding-practices/strncpy-and-strncat .
In the Falco codebase you can use the safer alternatives strlcpy() and strlcat().
severity: ERROR
languages:
- c
- cpp
patterns:
- pattern-either:
- pattern: strncpy(...)
- pattern: strncat(...)

View File

@@ -1,4 +1,3 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
#
@@ -27,18 +26,10 @@ FetchContent_MakeAvailable(googletest)
file(GLOB_RECURSE ENGINE_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/engine/*.cpp)
file(GLOB_RECURSE FALCO_TESTS ${CMAKE_CURRENT_SOURCE_DIR}/falco/*.cpp)
# Create a libscap_test_var.h file with some variables used by our tests
# for example the kmod path or the bpf path.
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/falco_test_var.h.in"
"${CMAKE_CURRENT_BINARY_DIR}/falco_test_var.h"
)
set(FALCO_UNIT_TESTS_SOURCES
"${ENGINE_TESTS}"
falco/test_configuration.cpp
falco/app/actions/test_select_event_sources.cpp
falco/app/actions/test_load_config.cpp
)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
@@ -53,7 +44,6 @@ set(FALCO_UNIT_TESTS_INCLUDES
${CMAKE_SOURCE_DIR}/userspace
${CMAKE_BINARY_DIR}/userspace/falco # we need it to include indirectly `config_falco.h` file
${CMAKE_SOURCE_DIR}/userspace/engine # we need it to include indirectly `falco_common.h` file
"${CMAKE_CURRENT_BINARY_DIR}" # we need it to include `falco_test_var.h`
)
set(FALCO_UNIT_TESTS_DEPENDENCIES

View File

@@ -1,89 +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.
*/
#include <gtest/gtest.h>
#include <falco_engine.h>
#include <evttype_index_ruleset.h>
static std::string syscall_source_name = "syscall";
// A variant of evttype_index_ruleset_factory that uses a singleton
// for the underlying ruleset. This allows testing of
// ruleset_for_source
namespace
{
class test_ruleset_factory : public evttype_index_ruleset_factory
{
public:
test_ruleset_factory(std::shared_ptr<gen_event_filter_factory> factory):
evttype_index_ruleset_factory(factory)
{
ruleset = evttype_index_ruleset_factory::new_ruleset();
}
virtual ~test_ruleset_factory() = default;
inline std::shared_ptr<filter_ruleset> new_ruleset() override
{
return ruleset;
}
std::shared_ptr<filter_ruleset> ruleset;
};
}; // namespace
TEST(AddSource, basic)
{
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
auto filter_factory = std::shared_ptr<gen_event_filter_factory>(
new sinsp_filter_factory(&inspector, filterchecks));
auto formatter_factory = std::shared_ptr<gen_event_formatter_factory>(
new sinsp_evt_formatter_factory(&inspector, filterchecks));
test_ruleset_factory *test_factory = new test_ruleset_factory(filter_factory);
auto ruleset_factory = std::shared_ptr<filter_ruleset_factory>(test_factory);
falco_source syscall_source;
syscall_source.name = syscall_source_name;
syscall_source.ruleset = ruleset_factory->new_ruleset();
syscall_source.ruleset_factory = ruleset_factory;
syscall_source.filter_factory = filter_factory;
syscall_source.formatter_factory = formatter_factory;
size_t source_idx = engine.add_source(syscall_source_name,
filter_factory,
formatter_factory,
ruleset_factory);
ASSERT_TRUE(engine.is_source_valid(syscall_source_name));
ASSERT_EQ(engine.filter_factory_for_source(syscall_source_name), filter_factory);
ASSERT_EQ(engine.filter_factory_for_source(source_idx), filter_factory);
ASSERT_EQ(engine.formatter_factory_for_source(syscall_source_name), formatter_factory);
ASSERT_EQ(engine.formatter_factory_for_source(source_idx), formatter_factory);
ASSERT_EQ(engine.ruleset_factory_for_source(syscall_source_name), ruleset_factory);
ASSERT_EQ(engine.ruleset_factory_for_source(source_idx), ruleset_factory);
ASSERT_EQ(engine.ruleset_for_source(syscall_source_name), test_factory->ruleset);
ASSERT_EQ(engine.ruleset_for_source(source_idx), test_factory->ruleset);
}

View File

@@ -1,251 +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.
*/
#include <string>
#include <gtest/gtest.h>
#include <sinsp.h>
#include <filter_check_list.h>
#include <filter.h>
#include <falco_engine.h>
static std::string single_rule = R"END(
- rule: test rule
desc: A test rule
condition: evt.type=execve
output: A test rule matched (evt.type=%evt.type)
priority: INFO
source: syscall
tags: [process]
- rule: disabled rule
desc: A disabled rule
condition: evt.type=execve
output: A disabled rule matched (evt.type=%evt.type)
priority: INFO
source: syscall
enabled: false
tags: [exec process]
)END";
// This must be kept in line with the (private) falco_engine::s_default_ruleset
static const std::string default_ruleset = "falco-default-ruleset";
static const std::string ruleset_1 = "ruleset-1";
static const std::string ruleset_2 = "ruleset-2";
static const std::string ruleset_3 = "ruleset-3";
static const std::string ruleset_4 = "ruleset-4";
static void load_rules(falco_engine& engine, sinsp& inspector, sinsp_filter_check_list& filterchecks)
{
std::unique_ptr<falco::load_result> res;
auto filter_factory = std::shared_ptr<gen_event_filter_factory>(
new sinsp_filter_factory(&inspector, filterchecks));
auto formatter_factory = std::shared_ptr<gen_event_formatter_factory>(
new sinsp_evt_formatter_factory(&inspector, filterchecks));
engine.add_source("syscall", filter_factory, formatter_factory);
res = engine.load_rules(single_rule, "single_rule.yaml");
EXPECT_TRUE(res->successful());
}
TEST(EnableRule, enable_rule_name)
{
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
load_rules(engine, inspector, filterchecks);
// No rules should be enabled yet for any custom rulesets
EXPECT_EQ(1, engine.num_rules_for_ruleset(default_ruleset));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
// Enable for first ruleset, only that ruleset should have an
// enabled rule afterward
engine.enable_rule("test", true, ruleset_1);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
// Enable for second ruleset
engine.enable_rule("test", true, ruleset_2);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
// When the substring is blank, all rules are enabled
// (including the disabled rule)
engine.enable_rule("", true, ruleset_3);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(2, engine.num_rules_for_ruleset(ruleset_3));
// Now disable for second ruleset
engine.enable_rule("test", false, ruleset_2);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(2, engine.num_rules_for_ruleset(ruleset_3));
}
TEST(EnableRule, enable_rule_tags)
{
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
std::set<std::string> process_tags = {"process"};
load_rules(engine, inspector, filterchecks);
// No rules should be enabled yet for any custom rulesets
EXPECT_EQ(1, engine.num_rules_for_ruleset(default_ruleset));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
// Enable for first ruleset, only that ruleset should have an
// enabled rule afterward
engine.enable_rule_by_tag(process_tags, true, ruleset_1);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
// Enable for second ruleset
engine.enable_rule_by_tag(process_tags, true, ruleset_2);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
// Now disable for second ruleset
engine.enable_rule_by_tag(process_tags, false, ruleset_2);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
}
TEST(EnableRule, enable_disabled_rule_by_tag)
{
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
std::set<std::string> exec_process_tags = {"exec process"};
load_rules(engine, inspector, filterchecks);
// Only the first rule should be enabled
EXPECT_EQ(1, engine.num_rules_for_ruleset(default_ruleset));
// Enable the disabled rule by tag
engine.enable_rule_by_tag(exec_process_tags, true);
// Both rules should be enabled now
EXPECT_EQ(2, engine.num_rules_for_ruleset(default_ruleset));
}
TEST(EnableRule, enable_rule_id)
{
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
uint16_t ruleset_1_id;
uint16_t ruleset_2_id;
uint16_t ruleset_3_id;
load_rules(engine, inspector, filterchecks);
// The cases are identical to above, just using ruleset ids
// instead of names.
ruleset_1_id = engine.find_ruleset_id(ruleset_1);
ruleset_2_id = engine.find_ruleset_id(ruleset_2);
ruleset_3_id = engine.find_ruleset_id(ruleset_3);
EXPECT_EQ(1, engine.num_rules_for_ruleset(default_ruleset));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
engine.enable_rule("test rule", true, ruleset_1_id);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
engine.enable_rule("test rule", true, ruleset_2_id);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
engine.enable_rule("", true, ruleset_3_id);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(2, engine.num_rules_for_ruleset(ruleset_3));
engine.enable_rule("test", false, ruleset_2_id);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(2, engine.num_rules_for_ruleset(ruleset_3));
}
TEST(EnableRule, enable_rule_name_exact)
{
falco_engine engine;
sinsp inspector;
sinsp_filter_check_list filterchecks;
load_rules(engine, inspector, filterchecks);
EXPECT_EQ(1, engine.num_rules_for_ruleset(default_ruleset));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_4));
engine.enable_rule_exact("test rule", true, ruleset_1);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_4));
engine.enable_rule_exact("test rule", true, ruleset_2);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_4));
// This should **not** enable as this is a substring and not
// an exact match.
engine.enable_rule_exact("test", true, ruleset_3);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_4));
engine.enable_rule_exact("", true, ruleset_4);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(2, engine.num_rules_for_ruleset(ruleset_4));
engine.enable_rule("test rule", false, ruleset_2);
EXPECT_EQ(1, engine.num_rules_for_ruleset(ruleset_1));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_2));
EXPECT_EQ(0, engine.num_rules_for_ruleset(ruleset_3));
EXPECT_EQ(2, engine.num_rules_for_ruleset(ruleset_4));
}

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -47,4 +46,4 @@ TEST(DetailsResolver, resolve_ast)
// Assert lists
ASSERT_EQ(details.lists.size(), 1);
ASSERT_NE(details.lists.find("known_procs"), details.lists.end());
}
}

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -37,17 +36,17 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST)
{
libsinsp::filter::ast::pos_info macro_pos(12, 85, 27);
std::shared_ptr<libsinsp::filter::ast::expr> macro = libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> filter_and;
filter_and.push_back(libsinsp::filter::ast::unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(libsinsp::filter::ast::not_expr::create(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos)));
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::and_expr::create(filter_and);
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::and_expr::create(filter_and));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> expected_and;
expected_and.push_back(libsinsp::filter::ast::unary_check_expr::create("evt.name", "", "exists"));
expected_and.push_back(libsinsp::filter::ast::not_expr::create(clone(macro.get())));
std::shared_ptr<libsinsp::filter::ast::expr> expected = libsinsp::filter::ast::and_expr::create(expected_and);
std::shared_ptr<libsinsp::filter::ast::expr> expected = std::move(libsinsp::filter::ast::and_expr::create(expected_and));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
@@ -71,9 +70,9 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_single_node)
{
libsinsp::filter::ast::pos_info macro_pos(12, 85, 27);
std::shared_ptr<libsinsp::filter::ast::expr> macro = libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos);
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
@@ -102,18 +101,18 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_multiple_macros)
libsinsp::filter::ast::pos_info a_macro_pos(11, 75, 43);
libsinsp::filter::ast::pos_info b_macro_pos(91, 21, 9);
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> b_macro = libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = std::move(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> b_macro = std::move(libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists"));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> filter_or;
filter_or.push_back(libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos));
filter_or.push_back(libsinsp::filter::ast::value_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::or_expr::create(filter_or);
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::or_expr::create(filter_or));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> expected_or;
expected_or.push_back(clone(a_macro.get()));
expected_or.push_back(clone(b_macro.get()));
std::shared_ptr<libsinsp::filter::ast::expr> expected_filter = libsinsp::filter::ast::or_expr::create(expected_or);
std::shared_ptr<libsinsp::filter::ast::expr> expected_filter = std::move(libsinsp::filter::ast::or_expr::create(expected_or));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_A_NAME, a_macro);
@@ -149,17 +148,17 @@ TEST(MacroResolver, should_resolve_macros_on_a_filter_AST_nested_macros)
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> a_macro_and;
a_macro_and.push_back(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(libsinsp::filter::ast::value_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = libsinsp::filter::ast::and_expr::create(a_macro_and);
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = std::move(libsinsp::filter::ast::and_expr::create(a_macro_and));
std::shared_ptr<libsinsp::filter::ast::expr> b_macro =
libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> b_macro = std::move(
libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos);
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos));
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> expected_and;
expected_and.push_back(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
expected_and.push_back(libsinsp::filter::ast::unary_check_expr::create("another.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> expected_filter = libsinsp::filter::ast::and_expr::create(expected_and);
std::shared_ptr<libsinsp::filter::ast::expr> expected_filter = std::move(libsinsp::filter::ast::and_expr::create(expected_and));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_A_NAME, a_macro);
@@ -196,7 +195,7 @@ TEST(MacroResolver, should_find_unknown_macros)
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> filter_and;
filter_and.push_back(libsinsp::filter::ast::unary_check_expr::create("evt.name", "", "exists"));
filter_and.push_back(libsinsp::filter::ast::not_expr::create(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos)));
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::and_expr::create(filter_and);
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::and_expr::create(filter_and));
filter_macro_resolver resolver;
ASSERT_FALSE(resolver.run(filter));
@@ -214,9 +213,9 @@ TEST(MacroResolver, should_find_unknown_nested_macros)
std::vector<std::unique_ptr<libsinsp::filter::ast::expr>> a_macro_and;
a_macro_and.push_back(libsinsp::filter::ast::unary_check_expr::create("one.field", "", "exists"));
a_macro_and.push_back(libsinsp::filter::ast::value_expr::create(MACRO_B_NAME, b_macro_pos));
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = libsinsp::filter::ast::and_expr::create(a_macro_and);
std::shared_ptr<libsinsp::filter::ast::expr> a_macro = std::move(libsinsp::filter::ast::and_expr::create(a_macro_and));
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos);
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_A_NAME, a_macro_pos));
auto expected_filter = clone(a_macro.get());
filter_macro_resolver resolver;
@@ -237,9 +236,9 @@ TEST(MacroResolver, should_undefine_macro)
libsinsp::filter::ast::pos_info macro_pos_1(12, 9, 3);
libsinsp::filter::ast::pos_info macro_pos_2(9, 6, 3);
std::shared_ptr<libsinsp::filter::ast::expr> macro = libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> a_filter = libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos_1);
std::shared_ptr<libsinsp::filter::ast::expr> b_filter = libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos_2);
std::shared_ptr<libsinsp::filter::ast::expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> a_filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos_1));
std::shared_ptr<libsinsp::filter::ast::expr> b_filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos_2));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);
@@ -262,8 +261,8 @@ TEST(MacroResolver, should_undefine_macro)
TEST(MacroResolver, should_clone_macro_AST)
{
libsinsp::filter::ast::pos_info macro_pos(5, 2, 8888);
std::shared_ptr<libsinsp::filter::ast::unary_check_expr> macro = libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists");
std::shared_ptr<libsinsp::filter::ast::expr> filter = libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos);
std::shared_ptr<libsinsp::filter::ast::unary_check_expr> macro = std::move(libsinsp::filter::ast::unary_check_expr::create("test.field", "", "exists"));
std::shared_ptr<libsinsp::filter::ast::expr> filter = std::move(libsinsp::filter::ast::value_expr::create(MACRO_NAME, macro_pos));
filter_macro_resolver resolver;
resolver.set_macro(MACRO_NAME, macro);

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.

View File

@@ -1,970 +0,0 @@
#include <gtest/gtest.h>
#include "falco_engine.h"
#include "rule_loader_reader.h"
#include "rule_loader_compiler.h"
#include "rule_loading_messages.h"
class engine_loader_test : public ::testing::Test {
protected:
void SetUp() override
{
m_sample_ruleset = "sample-ruleset";
m_sample_source = falco_common::syscall_source;
// create a falco engine ready to load the ruleset
m_inspector.reset(new sinsp());
m_engine.reset(new falco_engine());
m_filter_factory = std::shared_ptr<gen_event_filter_factory>(
new sinsp_filter_factory(m_inspector.get(), m_filterlist));
m_formatter_factory = std::shared_ptr<gen_event_formatter_factory>(
new sinsp_evt_formatter_factory(m_inspector.get(), m_filterlist));
m_engine->add_source(m_sample_source, m_filter_factory, m_formatter_factory);
}
void TearDown() override
{
}
bool load_rules(std::string rules_content, std::string rules_filename)
{
bool ret = false;
falco::load_result::rules_contents_t rc = {{rules_filename, rules_content}};
m_load_result = m_engine->load_rules(rules_content, rules_filename);
m_load_result_string = m_load_result->as_string(true, rc);
m_load_result_json = m_load_result->as_json(rc);
ret = m_load_result->successful();
if (ret)
{
m_engine->enable_rule("", true, m_sample_ruleset);
}
return ret;
}
// This must be kept in line with the (private) falco_engine::s_default_ruleset
uint64_t num_rules_for_ruleset(std::string ruleset = "falco-default-ruleset")
{
return m_engine->num_rules_for_ruleset(ruleset);
}
bool has_warnings()
{
return m_load_result->has_warnings();
}
bool check_warning_message(std::string warning_msg)
{
if(!m_load_result->has_warnings())
{
return false;
}
for(auto &warn : m_load_result_json["warnings"])
{
std::string msg = warn["message"];
// Debug:
// printf("msg: %s\n", msg.c_str());
if(msg.find(warning_msg) != std::string::npos)
{
return true;
}
}
return false;
}
bool check_error_message(std::string error_msg)
{
// if the loading is successful there are no errors
if(m_load_result->successful())
{
return false;
}
for(auto &err : m_load_result_json["errors"])
{
std::string msg = err["message"];
// Debug:
// printf("msg: %s\n", msg.c_str());
if(msg.find(error_msg) != std::string::npos)
{
return true;
}
}
return false;
}
std::string get_compiled_rule_condition(std::string rule_name = "")
{
auto rule_description = m_engine->describe_rule(&rule_name, {});
return rule_description["rules"][0]["details"]["condition_compiled"].template get<std::string>();
}
std::string m_sample_ruleset;
std::string m_sample_source;
sinsp_filter_check_list m_filterlist;
std::shared_ptr<gen_event_filter_factory> m_filter_factory;
std::shared_ptr<gen_event_formatter_factory> m_formatter_factory;
std::unique_ptr<falco_engine> m_engine;
std::unique_ptr<falco::load_result> m_load_result;
std::string m_load_result_string;
nlohmann::json m_load_result_json;
std::unique_ptr<sinsp> m_inspector;
};
std::string s_sample_ruleset = "sample-ruleset";
std::string s_sample_source = falco_common::syscall_source;
TEST_F(engine_loader_test, list_append)
{
std::string rules_content = R"END(
- list: shell_binaries
items: [ash, bash, csh, ksh, sh, tcsh, zsh, dash]
- rule: legit_rule
desc: legit rule description
condition: evt.type=open and proc.name in (shell_binaries)
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- list: shell_binaries
items: [pwsh]
override:
items: append
)END";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
ASSERT_EQ(get_compiled_rule_condition("legit_rule"),"(evt.type = open and proc.name in (ash, bash, csh, ksh, sh, tcsh, zsh, dash, pwsh))");
}
TEST_F(engine_loader_test, condition_append)
{
std::string rules_content = R"END(
- macro: interactive
condition: >
((proc.aname=sshd and proc.name != sshd) or
proc.name=systemd-logind or proc.name=login)
- rule: legit_rule
desc: legit rule description
condition: evt.type=open and interactive
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- macro: interactive
condition: or proc.name = ssh
override:
condition: append
)END";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
ASSERT_EQ(get_compiled_rule_condition("legit_rule"),"(evt.type = open and (((proc.aname = sshd and proc.name != sshd) or proc.name = systemd-logind or proc.name = login) or proc.name = ssh))");
}
TEST_F(engine_loader_test, rule_override_append)
{
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
condition: evt.type=open
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: legit_rule
desc: with append
condition: and proc.name = cat
output: proc=%proc.name
override:
desc: append
condition: append
output: append
)END";
std::string rule_name = "legit_rule";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
// Here we don't use the deprecated `append` flag, so we don't expect the warning.
ASSERT_FALSE(check_warning_message(WARNING_APPEND));
auto rule_description = m_engine->describe_rule(&rule_name, {});
ASSERT_EQ(rule_description["rules"][0]["info"]["condition"].template get<std::string>(),
"evt.type=open and proc.name = cat");
ASSERT_EQ(rule_description["rules"][0]["info"]["output"].template get<std::string>(),
"user=%user.name command=%proc.cmdline file=%fd.name proc=%proc.name");
ASSERT_EQ(rule_description["rules"][0]["info"]["description"].template get<std::string>(),
"legit rule description with append");
}
TEST_F(engine_loader_test, rule_append)
{
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
condition: evt.type=open
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: legit_rule
condition: and proc.name = cat
append: true
)END";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
// We should have at least one warning because the 'append' flag is deprecated.
ASSERT_TRUE(check_warning_message(WARNING_APPEND));
ASSERT_EQ(get_compiled_rule_condition("legit_rule"),"(evt.type = open and proc.name = cat)");
}
TEST_F(engine_loader_test, rule_override_replace)
{
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
condition: evt.type=open
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: legit_rule
desc: a replaced legit description
condition: evt.type = close
override:
desc: replace
condition: replace
)END";
std::string rule_name = "legit_rule";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
auto rule_description = m_engine->describe_rule(&rule_name, {});
ASSERT_EQ(rule_description["rules"][0]["info"]["condition"].template get<std::string>(),
"evt.type = close");
ASSERT_EQ(rule_description["rules"][0]["info"]["output"].template get<std::string>(),
"user=%user.name command=%proc.cmdline file=%fd.name");
ASSERT_EQ(rule_description["rules"][0]["info"]["description"].template get<std::string>(),
"a replaced legit description");
}
TEST_F(engine_loader_test, rule_override_append_replace)
{
std::string rules_content = R"END(
- rule: legit_rule
desc: legit rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: legit_rule
desc: a replaced legit description
condition: and proc.name = cat
priority: WARNING
override:
desc: replace
condition: append
priority: replace
)END";
std::string rule_name = "legit_rule";
ASSERT_TRUE(load_rules(rules_content, "legit_rules.yaml")) << m_load_result_string;
auto rule_description = m_engine->describe_rule(&rule_name, {});
ASSERT_EQ(rule_description["rules"][0]["info"]["condition"].template get<std::string>(),
"evt.type = close and proc.name = cat");
ASSERT_EQ(rule_description["rules"][0]["info"]["output"].template get<std::string>(),
"user=%user.name command=%proc.cmdline file=%fd.name");
ASSERT_EQ(rule_description["rules"][0]["info"]["description"].template get<std::string>(),
"a replaced legit description");
ASSERT_EQ(rule_description["rules"][0]["info"]["priority"].template get<std::string>(),
"Warning");
}
TEST_F(engine_loader_test, rule_incorrect_override_type)
{
std::string rules_content = R"END(
- rule: failing_rule
desc: legit rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: failing_rule
desc: an appended incorrect field
condition: and proc.name = cat
priority: WARNING
override:
desc: replace
condition: append
priority: append
)END";
std::string rule_name = "failing_rule";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message("Key 'priority' cannot be appended to, use 'replace' instead"));
ASSERT_TRUE(std::string(m_load_result_json["errors"][0]["context"]["snippet"]).find("priority: append") != std::string::npos);
}
TEST_F(engine_loader_test, rule_incorrect_append_override)
{
std::string rules_content = R"END(
- rule: failing_rule
desc: legit rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: failing_rule
desc: an appended incorrect field
condition: and proc.name = cat
append: true
override:
desc: replace
condition: append
)END";
std::string rule_name = "failing_rule";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
// We should have at least one warning because the 'append' flag is deprecated.
ASSERT_TRUE(check_warning_message(WARNING_APPEND));
ASSERT_TRUE(check_error_message(ERROR_OVERRIDE_APPEND));
}
TEST_F(engine_loader_test, macro_override_append_before_macro_definition)
{
std::string rules_content = R"END(
- macro: open_simple
condition: or evt.type = openat2
override:
condition: append
- macro: open_simple
condition: evt.type in (open,openat)
- rule: test_rule
desc: simple rule
condition: open_simple
output: command=%proc.cmdline
priority: INFO
)END";
// We cannot define a macro override before the macro definition.
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_MACRO));
}
TEST_F(engine_loader_test, macro_override_replace_before_macro_definition)
{
std::string rules_content = R"END(
- macro: open_simple
condition: or evt.type = openat2
override:
condition: replace
- macro: open_simple
condition: evt.type in (open,openat)
- rule: test_rule
desc: simple rule
condition: open_simple
output: command=%proc.cmdline
priority: INFO
)END";
// The first override defines a macro that is overridden by the second macro definition
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"evt.type in (open, openat)");
}
TEST_F(engine_loader_test, macro_append_before_macro_definition)
{
std::string rules_content = R"END(
- macro: open_simple
condition: or evt.type = openat2
append: true
- macro: open_simple
condition: evt.type in (open,openat)
- rule: test_rule
desc: simple rule
condition: open_simple
output: command=%proc.cmdline
priority: INFO
)END";
// We cannot define a macro override before the macro definition.
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_MACRO));
}
TEST_F(engine_loader_test, macro_override_append_after_macro_definition)
{
std::string rules_content = R"END(
- macro: open_simple
condition: evt.type in (open,openat)
- macro: open_simple
condition: or evt.type = openat2
override:
condition: append
- rule: test_rule
desc: simple rule
condition: open_simple
output: command=%proc.cmdline
priority: INFO
)END";
// We cannot define a macro override before the macro definition.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type in (open, openat) or evt.type = openat2)");
}
TEST_F(engine_loader_test, macro_append_after_macro_definition)
{
std::string rules_content = R"END(
- macro: open_simple
condition: evt.type in (open,openat)
- macro: open_simple
condition: or evt.type = openat2
append: true
- rule: test_rule
desc: simple rule
condition: open_simple
output: command=%proc.cmdline
priority: INFO
)END";
// We cannot define a macro override before the macro definition.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type in (open, openat) or evt.type = openat2)");
}
TEST_F(engine_loader_test, rule_override_append_before_rule_definition)
{
std::string rules_content = R"END(
- rule: test_rule
condition: and proc.name = cat
override:
condition: append
- rule: test_rule
desc: simple rule
condition: evt.type in (open,openat)
output: command=%proc.cmdline
priority: INFO
)END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_APPEND));
}
TEST_F(engine_loader_test, rule_override_replace_before_rule_definition)
{
std::string rules_content = R"END(
- rule: test_rule
condition: and proc.name = cat
override:
condition: replace
- rule: test_rule
desc: simple rule
condition: evt.type in (open,openat)
output: command=%proc.cmdline
priority: INFO
)END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_REPLACE));
}
TEST_F(engine_loader_test, rule_append_before_rule_definition)
{
std::string rules_content = R"END(
- rule: test_rule
condition: and proc.name = cat
append: true
- rule: test_rule
desc: simple rule
condition: evt.type in (open,openat)
output: command=%proc.cmdline
priority: INFO
)END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_RULE_APPEND));
}
TEST_F(engine_loader_test, rule_override_append_after_rule_definition)
{
std::string rules_content = R"END(
- rule: test_rule
desc: simple rule
condition: evt.type in (open,openat)
output: command=%proc.cmdline
priority: INFO
- rule: test_rule
condition: and proc.name = cat
override:
condition: append
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type in (open, openat) and proc.name = cat)");
}
TEST_F(engine_loader_test, rule_append_after_rule_definition)
{
std::string rules_content = R"END(
- rule: test_rule
desc: simple rule
condition: evt.type in (open,openat)
output: command=%proc.cmdline
priority: INFO
- rule: test_rule
condition: and proc.name = cat
append: true
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type in (open, openat) and proc.name = cat)");
}
TEST_F(engine_loader_test, list_override_append_wrong_key)
{
// todo: maybe we want to manage some non-existent keys
// Please note how the non-existent key 'non-existent keys' is ignored.
std::string rules_content = R"END(
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
override_written_wrong:
items: append
- list: dev_creation_binaries
items: [blkid]
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
// Since there is a wrong key in the first list definition the `override` is not
// considered. so in this situation, we are defining the list 2 times. The
// second one overrides the first one.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type = execve and proc.name in (blkid))");
}
TEST_F(engine_loader_test, list_override_append_before_list_definition)
{
std::string rules_content = R"END(
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
override:
items: append
- list: dev_creation_binaries
items: [blkid]
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
// We cannot define a list override before the list definition.
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_LIST));
}
TEST_F(engine_loader_test, list_override_replace_before_list_definition)
{
std::string rules_content = R"END(
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
override:
items: replace
- list: dev_creation_binaries
items: [blkid]
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
// With override replace we define a first list that then is overridden by the second one.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type = execve and proc.name in (blkid))");
}
TEST_F(engine_loader_test, list_append_before_list_definition)
{
std::string rules_content = R"END(
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
append: true
- list: dev_creation_binaries
items: [blkid]
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
// We cannot define a list append before the list definition.
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message(ERROR_NO_PREVIOUS_LIST));
}
TEST_F(engine_loader_test, list_override_append_after_list_definition)
{
std::string rules_content = R"END(
- list: dev_creation_binaries
items: [blkid]
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
override:
items: append
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type = execve and proc.name in (blkid, csi-provisioner, csi-attacher))");
}
TEST_F(engine_loader_test, list_append_after_list_definition)
{
std::string rules_content = R"END(
- list: dev_creation_binaries
items: [blkid]
- list: dev_creation_binaries
items: ["csi-provisioner", "csi-attacher"]
append: true
- rule: test_rule
desc: simple rule
condition: evt.type = execve and proc.name in (dev_creation_binaries)
output: command=%proc.cmdline
priority: INFO
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"(evt.type = execve and proc.name in (blkid, csi-provisioner, csi-attacher))");
}
TEST_F(engine_loader_test, rule_override_without_field)
{
std::string rules_content = R"END(
- rule: failing_rule
desc: legit rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: failing_rule
desc: an appended incorrect field
override:
desc: replace
condition: append
)END";
std::string rule_name = "failing_rule";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message("An append override for 'condition' was specified but 'condition' is not defined"));
}
TEST_F(engine_loader_test, rule_override_extra_field)
{
std::string rules_content = R"END(
- rule: failing_rule
desc: legit rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
- rule: failing_rule
desc: an appended incorrect field
condition: and proc.name = cat
priority: WARNING
override:
desc: replace
condition: append
)END";
std::string rule_name = "failing_rule";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message("Unexpected key 'priority'"));
}
TEST_F(engine_loader_test, missing_enabled_key_with_override)
{
std::string rules_content = R"END(
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
- rule: test_rule
desc: missing enabled key
condition: and proc.name = cat
override:
desc: replace
condition: append
enabled: replace
)END";
// In the rule override we miss `enabled: true`
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message("'enabled' was specified but 'enabled' is not defined"));
}
TEST_F(engine_loader_test, rule_override_with_enabled)
{
std::string rules_content = R"END(
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
- rule: test_rule
desc: correct override
condition: and proc.name = cat
enabled: true
override:
desc: replace
condition: append
enabled: replace
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_FALSE(has_warnings());
// The rule should be enabled at the end.
EXPECT_EQ(num_rules_for_ruleset(), 1);
}
TEST_F(engine_loader_test, rule_not_enabled)
{
std::string rules_content = R"END(
- rule: test_rule
desc: rule not enabled
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_FALSE(has_warnings());
EXPECT_EQ(num_rules_for_ruleset(), 0);
}
TEST_F(engine_loader_test, rule_enabled_warning)
{
std::string rules_content = R"END(
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
- rule: test_rule
enabled: true
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_warning_message(WARNING_ENABLED));
// The rule should be enabled at the end.
EXPECT_EQ(num_rules_for_ruleset(), 1);
}
// todo!: Probably we shouldn't allow this syntax
TEST_F(engine_loader_test, rule_enabled_is_ignored_by_append)
{
std::string rules_content = R"END(
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
- rule: test_rule
condition: and proc.name = cat
append: true
enabled: true
)END";
// 'enabled' is ignored by the append, this syntax is not supported
// so the rule is not enabled.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
EXPECT_EQ(num_rules_for_ruleset(), 0);
}
// todo!: Probably we shouldn't allow this syntax
TEST_F(engine_loader_test, rewrite_rule)
{
std::string rules_content = R"END(
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
- rule: test_rule
desc: redefined rule syntax
condition: proc.name = cat
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: WARNING
enabled: true
)END";
// The above syntax is not supported, we cannot override the content
// of a rule in this way.
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
// In this case the rule is completely overridden but this syntax is not supported.
EXPECT_EQ(num_rules_for_ruleset(), 1);
ASSERT_EQ(get_compiled_rule_condition("test_rule"),"proc.name = cat");
}
TEST_F(engine_loader_test, required_engine_version_semver)
{
std::string rules_content = R"END(
- required_engine_version: 0.26.0
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_FALSE(has_warnings());
}
TEST_F(engine_loader_test, required_engine_version_not_semver)
{
std::string rules_content = R"END(
- required_engine_version: 26
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_FALSE(has_warnings());
}
TEST_F(engine_loader_test, required_engine_version_invalid)
{
std::string rules_content = R"END(
- required_engine_version: seven
- rule: test_rule
desc: test rule description
condition: evt.type = close
output: user=%user.name command=%proc.cmdline file=%fd.name
priority: INFO
enabled: false
)END";
ASSERT_FALSE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(check_error_message("Unable to parse engine version"));
}
// checks for issue described in https://github.com/falcosecurity/falco/pull/3028
TEST_F(engine_loader_test, list_value_with_escaping)
{
std::string rules_content = R"END(
- list: my_list
items: [non_escaped_val, "escaped val"]
)END";
ASSERT_TRUE(load_rules(rules_content, "rules.yaml"));
ASSERT_TRUE(m_load_result->successful());
ASSERT_TRUE(m_load_result->has_warnings()); // a warning for the unused list
auto rule_description = m_engine->describe_rule(nullptr, {});
ASSERT_TRUE(m_load_result->successful());
ASSERT_EQ(rule_description["rules"].size(), 0);
ASSERT_EQ(rule_description["macros"].size(), 0);
ASSERT_EQ(rule_description["lists"].size(), 1);
// escaped values must not be interpreted as list refs by mistake
ASSERT_EQ(rule_description["lists"][0]["details"]["lists"].size(), 0);
// values should be escaped correctly
ASSERT_EQ(rule_description["lists"][0]["details"]["items_compiled"].size(), 2);
ASSERT_EQ(rule_description["lists"][0]["details"]["items_compiled"][0].template get<std::string>(), "non_escaped_val");
ASSERT_EQ(rule_description["lists"][0]["details"]["items_compiled"][1].template get<std::string>(), "escaped val");
}

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -23,9 +22,9 @@ limitations under the License.
#define RULESET_2 2
/* Helpers methods */
static std::shared_ptr<gen_event_filter_factory> create_factory(filter_check_list& list)
static std::shared_ptr<gen_event_filter_factory> create_factory()
{
std::shared_ptr<gen_event_filter_factory> ret(new sinsp_filter_factory(NULL, list));
std::shared_ptr<gen_event_filter_factory> ret(new sinsp_filter_factory(NULL));
return ret;
}
@@ -53,8 +52,7 @@ static std::shared_ptr<gen_event_filter> create_filter(
TEST(Ruleset, enable_disable_rules_using_names)
{
sinsp_filter_check_list filterlist;
auto f = create_factory(filterlist);
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto filter = create_filter(f, ast);
@@ -120,8 +118,7 @@ TEST(Ruleset, enable_disable_rules_using_names)
TEST(Ruleset, enable_disable_rules_using_tags)
{
sinsp_filter_check_list filterlist;
auto f = create_factory(filterlist);
auto f = create_factory();
auto r = create_ruleset(f);
auto ast = create_ast(f);
auto filter = create_filter(f, ast);

View File

@@ -1,23 +1,7 @@
// 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.
*/
#pragma once
#include <gtest/gtest.h>
#include <falco/app/state.h>
#include <falco/app/actions/actions.h>
#define EXPECT_ACTION_OK(r) { auto result = r; EXPECT_TRUE(result.success); EXPECT_TRUE(result.proceed); EXPECT_EQ(result.errstr, ""); }
#define EXPECT_ACTION_FAIL(r) { auto result = r; EXPECT_FALSE(result.success); EXPECT_FALSE(result.proceed); EXPECT_NE(result.errstr, ""); }
#define EXPECT_ACTION_OK(r) { EXPECT_TRUE(r.success); EXPECT_TRUE(r.proceed); EXPECT_EQ(r.errstr, ""); }
#define EXPECT_ACTION_FAIL(r) { EXPECT_FALSE(r.success); EXPECT_FALSE(r.proceed); EXPECT_NE(r.errstr, ""); }

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -77,12 +76,11 @@ static std::shared_ptr<falco_engine> mock_engine_from_filters(const strset_t& fi
}
// create a falco engine and load the ruleset
sinsp_filter_check_list filterlist;
std::shared_ptr<falco_engine> res(new falco_engine());
auto filter_factory = std::shared_ptr<gen_event_filter_factory>(
new sinsp_filter_factory(nullptr, filterlist));
new sinsp_filter_factory(nullptr));
auto formatter_factory = std::shared_ptr<gen_event_formatter_factory>(
new sinsp_evt_formatter_factory(nullptr, filterlist));
new sinsp_evt_formatter_factory(nullptr));
res->add_source(s_sample_source, filter_factory, formatter_factory);
res->load_rules(dummy_rules, "dummy_rules.yaml");
res->enable_rule("", true, s_sample_ruleset);

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -27,30 +26,30 @@ TEST(ActionConfigureSyscallBufferNum, variable_number_of_CPUs)
FAIL() << "cannot get the number of online CPUs from the system\n";
}
// not modern ebpf engine, we do nothing
// not modern bpf engine, we do nothing
{
falco::app::state s;
s.config->m_engine_mode = engine_kind_t::MODERN_EBPF;
s.options.modern_bpf = false;
EXPECT_ACTION_OK(action(s));
}
// modern ebpf engine, with an invalid number of CPUs
// modern bpf engine, with an invalid number of CPUs
// default `m_cpus_for_each_syscall_buffer` to online CPU number
{
falco::app::state s;
s.config->m_engine_mode = engine_kind_t::MODERN_EBPF;
s.config->m_modern_ebpf.m_cpus_for_each_buffer = online_cpus + 1;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus + 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, online_cpus);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus);
}
// modern ebpf engine, with a valid number of CPUs
// modern bpf engine, with an valid number of CPUs
// we don't modify `m_cpus_for_each_syscall_buffer`
{
falco::app::state s;
s.config->m_engine_mode = engine_kind_t::MODERN_EBPF;
s.config->m_modern_ebpf.m_cpus_for_each_buffer = online_cpus - 1;
s.options.modern_bpf = true;
s.config->m_cpus_for_each_syscall_buffer = online_cpus - 1;
EXPECT_ACTION_OK(action(s));
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, online_cpus - 1);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, online_cpus - 1);
}
}

View File

@@ -1,196 +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 ASSERTd by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "app_action_helpers.h"
#include "falco_test_var.h"
#ifndef __EMSCRIPTEN__
TEST(ActionLoadConfig, check_engine_config_is_correctly_parsed)
{
falco::app::state s = {};
s.options.conf_filename = NEW_ENGINE_CONFIG_CHANGED;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));
// Check that the engine is the kmod
EXPECT_TRUE(s.config->m_engine_mode == engine_kind_t::KMOD);
// Check that kmod params are the ones specified in the config
EXPECT_EQ(s.config->m_kmod.m_buf_size_preset, 2);
EXPECT_FALSE(s.config->m_kmod.m_drop_failed_exit);
// Check that all other engine params are empty
EXPECT_TRUE(s.config->m_ebpf.m_probe_path.empty());
EXPECT_EQ(s.config->m_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_ebpf.m_drop_failed_exit);
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, 0);
EXPECT_EQ(s.config->m_modern_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_modern_ebpf.m_drop_failed_exit);
EXPECT_TRUE(s.config->m_replay.m_capture_file.empty());
EXPECT_TRUE(s.config->m_gvisor.m_config.empty());
EXPECT_TRUE(s.config->m_gvisor.m_root.empty());
// Check that deprecated configs are always set since
EXPECT_EQ(s.config->m_syscall_buf_size_preset, 6);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, 7);
EXPECT_TRUE(s.config->m_syscall_drop_failed_exit);
}
// Equal to the one above but checks that the command line options are not parsed
TEST(ActionLoadConfig, check_command_line_options_are_not_used)
{
falco::app::state s;
s.options.modern_bpf = true;
s.options.conf_filename = NEW_ENGINE_CONFIG_CHANGED;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));
// Check that the engine is the kmod
EXPECT_TRUE(s.config->m_engine_mode == engine_kind_t::KMOD);
// Check that kmod params are the ones specified in the config
EXPECT_EQ(s.config->m_kmod.m_buf_size_preset, 2);
EXPECT_FALSE(s.config->m_kmod.m_drop_failed_exit);
// Check that all other engine params are empty
EXPECT_TRUE(s.config->m_ebpf.m_probe_path.empty());
EXPECT_EQ(s.config->m_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_ebpf.m_drop_failed_exit);
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, 0);
EXPECT_EQ(s.config->m_modern_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_modern_ebpf.m_drop_failed_exit);
EXPECT_TRUE(s.config->m_replay.m_capture_file.empty());
EXPECT_TRUE(s.config->m_gvisor.m_config.empty());
EXPECT_TRUE(s.config->m_gvisor.m_root.empty());
// Check that deprecated configs are always set since
EXPECT_EQ(s.config->m_syscall_buf_size_preset, 6);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, 7);
EXPECT_TRUE(s.config->m_syscall_drop_failed_exit);
}
TEST(ActionLoadConfig, check_kmod_with_syscall_configs)
{
falco::app::state s;
s.options.conf_filename = NEW_ENGINE_CONFIG_UNCHANGED;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));
// Check that the engine is the kmod
EXPECT_TRUE(s.config->m_engine_mode == engine_kind_t::KMOD);
// Kmod params should be populated with the syscall configs
// since the `engine` block is untouched.
EXPECT_EQ(s.config->m_kmod.m_buf_size_preset, 6);
EXPECT_TRUE(s.config->m_kmod.m_drop_failed_exit);
// Check that all other engine params are empty
EXPECT_TRUE(s.config->m_ebpf.m_probe_path.empty());
EXPECT_EQ(s.config->m_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_ebpf.m_drop_failed_exit);
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, 0);
EXPECT_EQ(s.config->m_modern_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_modern_ebpf.m_drop_failed_exit);
EXPECT_TRUE(s.config->m_replay.m_capture_file.empty());
EXPECT_TRUE(s.config->m_gvisor.m_config.empty());
EXPECT_TRUE(s.config->m_gvisor.m_root.empty());
// Check that deprecated configs are populated
EXPECT_EQ(s.config->m_syscall_buf_size_preset, 6);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, 3);
EXPECT_TRUE(s.config->m_syscall_drop_failed_exit);
}
TEST(ActionLoadConfig, check_override_command_line_modern)
{
falco::app::state s;
// The command line options should be correctly applied since the
// config is unchanged
s.options.modern_bpf = true;
s.options.conf_filename = NEW_ENGINE_CONFIG_UNCHANGED;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));
// Check that the engine is the kmod
EXPECT_TRUE(s.is_modern_ebpf());
// Check that the modern ebpf engine uses the default syscall configs
// and not the ones in the `engine` block
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, 3);
EXPECT_EQ(s.config->m_modern_ebpf.m_buf_size_preset, 6);
EXPECT_TRUE(s.config->m_modern_ebpf.m_drop_failed_exit);
// Kmod params should be always populated since the kmod is the default
EXPECT_EQ(s.config->m_kmod.m_buf_size_preset, 6);
EXPECT_TRUE(s.config->m_kmod.m_drop_failed_exit);
// Check that all other engine params are empty
EXPECT_TRUE(s.config->m_ebpf.m_probe_path.empty());
EXPECT_EQ(s.config->m_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_ebpf.m_drop_failed_exit);
EXPECT_TRUE(s.config->m_replay.m_capture_file.empty());
EXPECT_TRUE(s.config->m_gvisor.m_config.empty());
EXPECT_TRUE(s.config->m_gvisor.m_root.empty());
// Check that deprecated configs are populated
EXPECT_EQ(s.config->m_syscall_buf_size_preset, 6);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, 3);
EXPECT_TRUE(s.config->m_syscall_drop_failed_exit);
}
TEST(ActionLoadConfig, check_override_command_line_gvisor)
{
falco::app::state s;
// The command line options should be correctly applied since the
// config is unchanged
s.options.gvisor_config = "config";
s.options.conf_filename = NEW_ENGINE_CONFIG_UNCHANGED;
EXPECT_ACTION_OK(falco::app::actions::load_config(s));
// Check that the engine is the kmod
EXPECT_TRUE(s.is_gvisor());
EXPECT_EQ(s.config->m_gvisor.m_config, "config");
EXPECT_TRUE(s.config->m_gvisor.m_root.empty());
// Kmod params should be always populated since the kmod is the default
EXPECT_EQ(s.config->m_kmod.m_buf_size_preset, 6);
EXPECT_TRUE(s.config->m_kmod.m_drop_failed_exit);
// Check that all other engine params are empty
EXPECT_TRUE(s.config->m_ebpf.m_probe_path.empty());
EXPECT_EQ(s.config->m_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_ebpf.m_drop_failed_exit);
EXPECT_EQ(s.config->m_modern_ebpf.m_cpus_for_each_buffer, 0);
EXPECT_EQ(s.config->m_modern_ebpf.m_buf_size_preset, 0);
EXPECT_FALSE(s.config->m_modern_ebpf.m_drop_failed_exit);
EXPECT_TRUE(s.config->m_replay.m_capture_file.empty());
// Check that deprecated configs are populated
EXPECT_EQ(s.config->m_syscall_buf_size_preset, 6);
EXPECT_EQ(s.config->m_cpus_for_each_syscall_buffer, 3);
EXPECT_TRUE(s.config->m_syscall_drop_failed_exit);
}
#endif

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -30,7 +29,7 @@ TEST(ActionSelectEventSources, pre_post_conditions)
// ignore source selection in capture mode
{
falco::app::state s;
s.config->m_engine_mode = engine_kind_t::REPLAY;
s.options.trace_filename = "some_capture_file.scap";
EXPECT_TRUE(s.is_capture_mode());
EXPECT_ACTION_OK(action(s));
}

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -129,4 +128,4 @@ TEST(AtomicSignalHandler, handle_and_reset)
ASSERT_FALSE(handler.triggered());
ASSERT_FALSE(handler.handled());
ASSERT_FALSE(handler.handle(do_nothing));
}
}

View File

@@ -1,52 +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.
#
################
# Falco engine #
################
engine:
kind: kmod
kmod:
buf_size_preset: 2 # changed default value
drop_failed_exit: false
ebpf:
probe: /path/to/probe.o
buf_size_preset: 4
drop_failed_exit: false
modern_ebpf:
cpus_for_each_buffer: 2
buf_size_preset: 4
drop_failed_exit: false
replay:
capture_file: /path/to/file.scap
gvisor:
config: /path/to/gvisor_config.yaml
root: ""
#######################################
# Falco performance tuning (advanced) #
#######################################
# These configs should be ignored since we have changed the `engine` config
syscall_buf_size_preset: 6
syscall_drop_failed_exit: true
modern_bpf:
cpus_for_each_syscall_buffer: 7

View File

@@ -1,53 +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.
#
################
# Falco engine #
################
# Unchanged
engine:
kind: kmod
kmod:
buf_size_preset: 4
drop_failed_exit: false
ebpf:
probe: /path/to/probe.o
buf_size_preset: 4
drop_failed_exit: false
modern_ebpf:
cpus_for_each_buffer: 2
buf_size_preset: 4
drop_failed_exit: false
replay:
capture_file: /path/to/file.scap
gvisor:
config: /path/to/gvisor_config.yaml
root: ""
#######################################
# Falco performance tuning (advanced) #
#######################################
# The `engine` config is unchanged so these configs are used
syscall_buf_size_preset: 6
syscall_drop_failed_exit: true
modern_bpf:
cpus_for_each_syscall_buffer: 3

View File

@@ -1,4 +1,3 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
@@ -18,12 +17,6 @@ limitations under the License.
#include <gtest/gtest.h>
#include <falco/configuration.h>
#ifdef _WIN32
#define SET_ENV_VAR(env_var_name, env_var_value) _putenv_s(env_var_name, env_var_value)
#else
#define SET_ENV_VAR(env_var_name, env_var_value) setenv(env_var_name, env_var_value, 1)
#endif
static std::string sample_yaml =
"base_value:\n"
" id: 1\n"
@@ -95,269 +88,16 @@ TEST(Configuration, modify_yaml_fields)
{
std::string key = "base_value.subvalue.subvalue2.boolean";
yaml_helper conf;
/* Get original value */
conf.load_from_string(sample_yaml);
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
/* Modify the original value */
conf.set_scalar<bool>(key, false);
ASSERT_EQ(conf.get_scalar<bool>(key, true), false);
/* Modify it again */
conf.set_scalar<bool>(key, true);
ASSERT_EQ(conf.get_scalar<bool>(key, false), true);
}
TEST(Configuration, configuration_environment_variables)
{
// Set an environment variable for testing purposes
std::string env_var_value = "envVarValue";
std::string env_var_name = "ENV_VAR";
SET_ENV_VAR(env_var_name.c_str(), env_var_value.c_str());
std::string embedded_env_var_value = "${ENV_VAR}";
std::string embedded_env_var_name = "ENV_VAR_EMBEDDED";
SET_ENV_VAR(embedded_env_var_name.c_str(), embedded_env_var_value.c_str());
std::string bool_env_var_value = "true";
std::string bool_env_var_name = "ENV_VAR_BOOL";
SET_ENV_VAR(bool_env_var_name.c_str(), bool_env_var_value.c_str());
std::string int_env_var_value = "12";
std::string int_env_var_name = "ENV_VAR_INT";
SET_ENV_VAR(int_env_var_name.c_str(), int_env_var_value.c_str());
std::string empty_env_var_value = "";
std::string empty_env_var_name = "ENV_VAR_EMPTY";
SET_ENV_VAR(empty_env_var_name.c_str(), empty_env_var_value.c_str());
std::string default_value = "default";
std::string env_var_sample_yaml =
"base_value:\n"
" id: $ENV_VAR\n"
" name: '${ENV_VAR}'\n"
" string: my_string\n"
" invalid: $${ENV_VAR}\n"
" invalid_env: $$ENV_VAR\n"
" invalid_double_env: $${ENV_VAR}$${ENV_VAR}\n"
" invalid_embedded_env: $${${ENV_VAR}}\n"
" invalid_valid_env: $${ENV_VAR}${ENV_VAR}\n"
" escaped: \"${ENV_VAR}\"\n"
" subvalue:\n"
" subvalue2:\n"
" boolean: ${UNSED_XX_X_X_VAR}\n"
"base_value_2:\n"
" sample_list:\n"
" - ${ENV_VAR}\n"
" - ' ${ENV_VAR}'\n"
" - '${ENV_VAR} '\n"
" - $UNSED_XX_X_X_VAR\n"
"paths:\n"
" - ${ENV_VAR}/foo\n"
" - $ENV_VAR/foo\n"
" - /foo/${ENV_VAR}/\n"
" - /${ENV_VAR}/${ENV_VAR}${ENV_VAR}/foo\n"
" - ${ENV_VAR_EMBEDDED}/foo\n"
"is_test: ${ENV_VAR_BOOL}\n"
"num_test: ${ENV_VAR_INT}\n"
"empty_test: ${ENV_VAR_EMPTY}\n"
"plugins:\n"
" - name: k8saudit\n"
" library_path: /foo/${ENV_VAR}/libk8saudit.so\n"
" open_params: ${ENV_VAR_INT}\n";
yaml_helper conf;
conf.load_from_string(env_var_sample_yaml);
/* Check if the base values are defined */
ASSERT_TRUE(conf.is_defined("base_value"));
ASSERT_TRUE(conf.is_defined("base_value_2"));
ASSERT_TRUE(conf.is_defined("paths"));
ASSERT_FALSE(conf.is_defined("unknown_base_value"));
/* Test fetching of a regular string without any environment variable */
auto base_value_string = conf.get_scalar<std::string>("base_value.string", default_value);
ASSERT_EQ(base_value_string, "my_string");
/* Test fetching of escaped environment variable format. Should return the string as-is after stripping the leading `$` */
auto base_value_invalid = conf.get_scalar<std::string>("base_value.invalid", default_value);
ASSERT_EQ(base_value_invalid, "${ENV_VAR}");
/* Test fetching of invalid escaped environment variable format. Should return the string as-is */
auto base_value_invalid_env = conf.get_scalar<std::string>("base_value.invalid_env", default_value);
ASSERT_EQ(base_value_invalid_env, "$$ENV_VAR");
/* Test fetching of 2 escaped environment variables side by side. Should return the string as-is after stripping the leading `$` */
auto base_value_double_invalid = conf.get_scalar<std::string>("base_value.invalid_double_env", default_value);
ASSERT_EQ(base_value_double_invalid, "${ENV_VAR}${ENV_VAR}");
/*
* Test fetching of escaped environment variable format with inside an env variable.
* Should return the string as-is after stripping the leading `$` with the resolved env variable within
*/
auto base_value_embedded_invalid = conf.get_scalar<std::string>("base_value.invalid_embedded_env", default_value);
ASSERT_EQ(base_value_embedded_invalid, "${" + env_var_value + "}");
/*
* Test fetching of an escaped env variable plus an env variable side by side.
* Should return the escaped one trimming the leading `$` plus the second one resolved.
*/
auto base_value_valid_invalid = conf.get_scalar<std::string>("base_value.invalid_valid_env", default_value);
ASSERT_EQ(base_value_valid_invalid, "${ENV_VAR}" + env_var_value);
/* Test fetching of strings that contain environment variables */
auto base_value_id = conf.get_scalar<std::string>("base_value.id", default_value);
ASSERT_EQ(base_value_id, "$ENV_VAR"); // Does not follow the `${VAR}` format, so it should be treated as a regular string
auto base_value_name = conf.get_scalar<std::string>("base_value.name", default_value);
ASSERT_EQ(base_value_name, env_var_value); // Proper environment variable format
auto base_value_escaped = conf.get_scalar<std::string>("base_value.escaped", default_value);
ASSERT_EQ(base_value_escaped, env_var_value); // Environment variable within quotes
/* Test fetching of an undefined environment variable. Resolves to empty string. */
auto unknown_boolean = conf.get_scalar<std::string>("base_value.subvalue.subvalue2.boolean", default_value);
ASSERT_EQ(unknown_boolean, "");
/* Test fetching of environment variables from a list */
auto base_value_2_list_0 = conf.get_scalar<std::string>("base_value_2.sample_list[0]", default_value);
ASSERT_EQ(base_value_2_list_0, env_var_value); // Proper environment variable format
auto base_value_2_list_1 = conf.get_scalar<std::string>("base_value_2.sample_list[1]", default_value);
ASSERT_EQ(base_value_2_list_1, " " + env_var_value); // Environment variable preceded by a space, still extracted env var with leading space
auto base_value_2_list_2 = conf.get_scalar<std::string>("base_value_2.sample_list[2]", default_value);
ASSERT_EQ(base_value_2_list_2, env_var_value + " "); // Environment variable followed by a space, still extracted env var with trailing space
auto base_value_2_list_3 = conf.get_scalar<std::string>("base_value_2.sample_list[3]", default_value);
ASSERT_EQ(base_value_2_list_3, "$UNSED_XX_X_X_VAR"); // Does not follow the `${VAR}` format, so should be treated as a regular string
/* Test expansion of environment variables within strings */
auto path_list_0 = conf.get_scalar<std::string>("paths[0]", default_value);
ASSERT_EQ(path_list_0, env_var_value + "/foo"); // Even if env var is part of bigger string, it gets expanded
auto path_list_1 = conf.get_scalar<std::string>("paths[1]", default_value);
ASSERT_EQ(path_list_1, "$ENV_VAR/foo"); // Does not follow the `${VAR}` format, so should be treated as a regular string
auto path_list_2 = conf.get_scalar<std::string>("paths[2]", default_value);
ASSERT_EQ(path_list_2, "/foo/" + env_var_value + "/"); // Even when env var is in the middle of a string. it gets expanded
auto path_list_3 = conf.get_scalar<std::string>("paths[3]", default_value);
ASSERT_EQ(path_list_3, "/" + env_var_value + "/" + env_var_value + env_var_value + "/foo"); // Even when the string contains multiple env vars they are correctly expanded
auto path_list_4 = conf.get_scalar<std::string>("paths[4]", default_value);
ASSERT_EQ(path_list_4, env_var_value + "/foo"); // Even when the env var contains another env var, it gets correctly double-expanded
/* Check that variable expansion is type-aware */
auto boolean = conf.get_scalar<bool>("is_test", false);
ASSERT_EQ(boolean, true); // `true` can be parsed to bool.
auto boolean_as_str = conf.get_scalar<std::string>("is_test", "false");
ASSERT_EQ(boolean_as_str, "true"); // `true` can be parsed to string.
auto boolean_as_int = conf.get_scalar<int32_t>("is_test", 0);
ASSERT_EQ(boolean_as_int, 0); // `true` cannot be parsed to integer.
auto integer = conf.get_scalar<int32_t>("num_test", -1);
ASSERT_EQ(integer, 12);
// An env var that resolves to an empty string returns ""
auto empty_default_str = conf.get_scalar<std::string>("empty_test", default_value);
ASSERT_EQ(empty_default_str, "");
std::list<falco_configuration::plugin_config> plugins;
conf.get_sequence<std::list<falco_configuration::plugin_config>>(plugins, std::string("plugins"));
std::vector<falco_configuration::plugin_config> m_plugins{ std::make_move_iterator(std::begin(plugins)),
std::make_move_iterator(std::end(plugins)) };
ASSERT_EQ(m_plugins[0].m_name, "k8saudit");
ASSERT_EQ(m_plugins[0].m_library_path, "/foo/" + env_var_value + "/libk8saudit.so");
ASSERT_EQ(m_plugins[0].m_open_params, "12");
/* Clear the set environment variables after testing */
SET_ENV_VAR(env_var_name.c_str(), "");
SET_ENV_VAR(embedded_env_var_name.c_str(), "");
SET_ENV_VAR(bool_env_var_name.c_str(), "");
SET_ENV_VAR(int_env_var_name.c_str(), "");
SET_ENV_VAR(empty_env_var_name.c_str(), "");
}
TEST(Configuration, configuration_webserver_ip)
{
falco_configuration falco_config;
std::vector<std::string> valid_addresses = {"127.0.0.1",
"1.127.0.1",
"1.1.127.1",
"1.1.1.127",
"::",
"::1",
"1200:0000:AB00:1234:0000:2552:7777:1313",
"1200::AB00:1234:0000:2552:7777:1313",
"1200:0000:AB00:1234::2552:7777:1313",
"21DA:D3:0:2F3B:2AA:FF:FE28:9C5A",
"FE80:0000:0000:0000:0202:B3FF:FE1E:8329",
"0.0.0.0",
"9.255.255.255",
"11.0.0.0",
"126.255.255.255",
"129.0.0.0",
"169.253.255.255",
"169.255.0.0",
"172.15.255.255",
"172.32.0.0",
"191.0.1.255",
"192.88.98.255",
"192.88.100.0",
"192.167.255.255",
"192.169.0.0",
"198.17.255.255",
"223.255.255.255"};
for (const std::string &address: valid_addresses) {
std::string option = "webserver.listen_address=";
option.append(address);
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back(option);
EXPECT_NO_THROW(falco_config.init(cmdline_config_options));
ASSERT_EQ(falco_config.m_webserver_listen_address, address);
}
std::vector<std::string> invalid_addresses = {"327.0.0.1",
"1.327.0.1",
"1.1.327.1",
"1.1.1.327",
"12 7.0.0.1",
"127. 0.0.1",
"127.0. 0.1",
"127.0.0. 1",
"!27.0.0.1",
"1200: 0000:AB00:1234:0000:2552:7777:1313",
"1200:0000: AB00:1234:0000:2552:7777:1313",
"1200:0000:AB00: 1234:0000:2552:7777:1313",
"1200:0000:AB00:1234: 0000:2552:7777:1313",
"1200:0000:AB00:1234:0000: 2552:7777:1313",
"1200:0000:AB00:1234:0000:2552: 7777:1313",
"1200:0000:AB00:1234:0000:2552:7777: 1313",
"1200:0000:AB00:1234:0000:2552:7777:131G",
"1200:0000:AB00:1234:0000:2552:77Z7:1313",
"1200:0000:AB00:1234:0000:2G52:7777:1313",
"1200:0000:AB00:1234:0O00:2552:7777:1313",
"1200:0000:AB00:H234:0000:2552:7777:1313",
"1200:0000:IB00:1234:0000:2552:7777:1313",
"1200:0O00:AB00:1234:0000:2552:7777:1313",
"12O0:0000:AB00:1234:0000:2552:7777:1313",};
for (const std::string &address: invalid_addresses) {
std::string option = "webserver.listen_address=";
option.append(address);
std::vector<std::string> cmdline_config_options;
cmdline_config_options.push_back(option);
EXPECT_ANY_THROW(falco_config.init(cmdline_config_options));
}
}

View File

@@ -1,4 +0,0 @@
#pragma once
#define NEW_ENGINE_CONFIG_CHANGED "${CMAKE_SOURCE_DIR}/unit_tests/falco/test_configs/new_engine_config_changed.yaml"
#define NEW_ENGINE_CONFIG_UNCHANGED "${CMAKE_SOURCE_DIR}/unit_tests/falco/test_configs/new_engine_config_unchanged.yaml"

View File

@@ -1,6 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
#
# Copyright (C) 2023 The Falco Authors.
# Copyright (C) 2019 The Falco Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
@@ -11,11 +10,12 @@
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
add_library(falco_engine STATIC
set(FALCO_ENGINE_SOURCE_FILES
falco_common.cpp
falco_engine.cpp
falco_load_result.cpp
falco_utils.cpp
json_evt.cpp
evttype_index_ruleset.cpp
formats.cpp
filter_details_resolver.cpp
@@ -25,8 +25,9 @@ add_library(falco_engine STATIC
rule_loader.cpp
rule_loader_reader.cpp
rule_loader_collector.cpp
rule_loader_compiler.cpp
)
rule_loader_compiler.cpp)
add_library(falco_engine STATIC ${FALCO_ENGINE_SOURCE_FILES})
if (EMSCRIPTEN)
target_compile_options(falco_engine PRIVATE "-sDISABLE_EXCEPTION_CATCHING=0")
@@ -34,17 +35,26 @@ endif()
add_dependencies(falco_engine yamlcpp njson)
target_include_directories(falco_engine
PUBLIC
${LIBSCAP_INCLUDE_DIRS}
${LIBSINSP_INCLUDE_DIRS}
${PROJECT_BINARY_DIR}/userspace/engine
${nlohmann_json_INCLUDE_DIRS}
${TBB_INCLUDE_DIR}
${YAMLCPP_INCLUDE_DIR}
)
if(MINIMAL_BUILD)
target_include_directories(
falco_engine
PUBLIC
"${NJSON_INCLUDE}"
"${TBB_INCLUDE_DIR}"
"${LIBSCAP_INCLUDE_DIRS}"
"${LIBSINSP_INCLUDE_DIRS}"
"${YAMLCPP_INCLUDE_DIR}"
"${PROJECT_BINARY_DIR}/userspace/engine")
else()
target_include_directories(
falco_engine
PUBLIC
"${NJSON_INCLUDE}"
"${TBB_INCLUDE_DIR}"
"${LIBSCAP_INCLUDE_DIRS}"
"${LIBSINSP_INCLUDE_DIRS}"
"${YAMLCPP_INCLUDE_DIR}"
"${PROJECT_BINARY_DIR}/userspace/engine")
endif()
target_link_libraries(falco_engine
${FALCO_SINSP_LIBRARY}
${YAMLCPP_LIB}
)
target_link_libraries(falco_engine "${FALCO_SINSP_LIBRARY}" "${YAMLCPP_LIB}")

47
userspace/engine/banned.h Normal file
View File

@@ -0,0 +1,47 @@
/*
Copyright (C) 2023 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
// BAN macro defines `function` as an invalid token that says using
// the function is banned. This throws a compile time error when the
// function is used.
#define BAN(function) using_##function##_is_banned
// BAN_ALTERNATIVE is same as BAN but the message also provides an alternative
// function that the user could use instead of the banned function.
#define BAN_ALTERNATIVE(function, alternative) using_##function##_is_banned__use_##alternative##_instead
#undef strcpy
#define strcpy(a, b) BAN(strcpy)
#undef vsprintf
#define vsprintf(a, b, c) BAN_ALTERNATIVE(vsprintf, vsnprintf)
#undef sprintf
#define sprintf(a, b, ...) BAN_ALTERNATIVE(sprintf, snprintf)
#undef strcat
#define strcat(a, b) BAN(strcat)
#undef strncpy
#define strncpy(a, b, c) BAN(strncpy)
#undef swprintf
#define swprintf(a, b, c, ...) BAN_ALTERNATIVE(swprintf, snprintf)
#undef vswprintf
#define vswprintf(a, b, c, d) BAN_ALTERNATIVE(vswprintf, vsnprintf)

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2019 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,6 +15,7 @@ limitations under the License.
*/
#include "evttype_index_ruleset.h"
#include "banned.h" // This raises a compilation error when certain functions are used
#include <algorithm>

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2019 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -98,4 +97,4 @@ bool falco_common::parse_rule_matching(std::string v, rule_matching& out)
}
}
return false;
}
}

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2022 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -22,12 +21,6 @@ limitations under the License.
#include <mutex>
#include <sinsp.h>
//
// equivalent to an "unbounded queue" in TBB terms or largest long value
// https://github.com/oneapi-src/oneTBB/blob/b2474bfc636937052d05daf8b3f4d6b76e20273a/include/oneapi/tbb/concurrent_queue.h#L554
//
#define DEFAULT_OUTPUTS_QUEUE_CAPACITY_UNBOUNDED_MAX_LONG_VALUE std::ptrdiff_t(~size_t(0) / 2)
//
// Most falco_* classes can throw exceptions. Unless directly related
// to low-level failures like inability to open file, etc, they will
@@ -59,7 +52,6 @@ struct falco_exception : std::exception
namespace falco_common
{
const std::string syscall_source = sinsp_syscall_event_source_name;
// Same as numbers/indices into the above vector

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2019 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -44,7 +43,9 @@ limitations under the License.
#include "formats.h"
#include "utils.h"
#include "banned.h" // This raises a compilation error when certain functions are used
#include "evttype_index_ruleset.h"
#include "filter_details_resolver.h"
const std::string falco_engine::s_default_ruleset = "falco-default-ruleset";
@@ -74,9 +75,29 @@ falco_engine::~falco_engine()
m_sources.clear();
}
sinsp_version falco_engine::engine_version()
uint32_t falco_engine::engine_version()
{
return sinsp_version(FALCO_ENGINE_VERSION);
return (uint32_t) FALCO_ENGINE_VERSION;
}
const falco_source* falco_engine::find_source(const std::string& name) const
{
auto ret = m_sources.at(name);
if(!ret)
{
throw falco_exception("Unknown event source " + name);
}
return ret;
}
const falco_source* falco_engine::find_source(std::size_t index) const
{
auto ret = m_sources.at(index);
if(!ret)
{
throw falco_exception("Unknown event source index " + std::to_string(index));
}
return ret;
}
// Return a key that uniquely represents a field class.
@@ -157,68 +178,34 @@ void falco_engine::list_fields(std::string &source, bool verbose, bool names_onl
}
}
void falco_engine::load_rules(const std::string &rules_content, bool verbose, bool all_events)
{
static const std::string no_name = "N/A";
std::unique_ptr<load_result> res = load_rules(rules_content, no_name);
interpret_load_result(res, no_name, rules_content, verbose);
}
std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_content, const std::string &name)
{
rule_loader::configuration cfg(rules_content, m_sources, name);
cfg.min_priority = m_min_priority;
cfg.output_extra = m_extra;
cfg.replace_output_container_info = m_replace_container_info;
cfg.default_ruleset_id = m_default_ruleset_id;
// read rules YAML file and collect its definitions
rule_loader::reader reader;
if (reader.read(cfg, m_rule_collector))
{
// compile the definitions (resolve macro/list refs, exceptions, ...)
m_last_compile_output = std::make_unique<rule_loader::compiler::compile_output>();
rule_loader::compiler().compile(cfg, m_rule_collector, *m_last_compile_output.get());
// clear the rules known by the engine and each ruleset
m_rules.clear();
for (auto &src : m_sources)
// add rules to each ruleset
{
src.ruleset = src.ruleset_factory->new_ruleset();
}
// add rules to the engine and the rulesets
for (const auto& rule : m_last_compile_output->rules)
{
auto info = m_rule_collector.rules().at(rule.name);
if (!info)
{
// this is just defensive, it should never happen
throw falco_exception("can't find internal rule info at name: " + name);
}
// the rule is ok, we can add it to the engine and the rulesets
// note: the compiler should guarantee that the rule's condition
// is a valid sinsp filter
auto source = find_source(rule.source);
std::shared_ptr<gen_event_filter> filter(
sinsp_filter_compiler(source->filter_factory, rule.condition.get()).compile());
auto rule_id = m_rules.insert(rule, rule.name);
if (rule_id != rule.id)
{
throw falco_exception("Incompatible ID for rule: " + rule.name +
" | compiled ID: " + std::to_string(rule.id) +
" | stats_mgr ID: " + std::to_string(rule_id));
}
source->ruleset->add(rule, filter, rule.condition);
// By default rules are enabled/disabled for the default ruleset
// skip the rule if below the minimum priority
if (rule.priority > m_min_priority)
{
continue;
}
if(info->enabled)
{
source->ruleset->enable(rule.name, true, m_default_ruleset_id);
}
else
{
source->ruleset->disable(rule.name, true, m_default_ruleset_id);
}
}
rule_loader::compiler compiler;
m_rules.clear();
compiler.compile(cfg, m_rule_collector, m_rules);
}
if (cfg.res->successful())
@@ -233,15 +220,47 @@ std::unique_ptr<load_result> falco_engine::load_rules(const std::string &rules_c
return std::move(cfg.res);
}
void falco_engine::load_rules_file(const std::string &rules_filename, bool verbose, bool all_events)
{
std::string rules_content;
read_file(rules_filename, rules_content);
std::unique_ptr<load_result> res = load_rules(rules_content, rules_filename);
interpret_load_result(res, rules_filename, rules_content, verbose);
}
std::unique_ptr<load_result> falco_engine::load_rules_file(const std::string &rules_filename)
{
std::string rules_content;
try {
read_file(rules_filename, rules_content);
}
catch (falco_exception &e)
{
rule_loader::context ctx(rules_filename);
std::unique_ptr<rule_loader::result> res(new rule_loader::result(rules_filename));
res->add_error(load_result::LOAD_ERR_FILE_READ, e.what(), ctx);
// Old gcc versions (e.g. 4.8.3) won't allow move elision but newer versions
// (e.g. 10.2.1) would complain about the redundant move.
#if __GNUC__ > 4
return res;
#else
return std::move(res);
#endif
}
return load_rules(rules_content, rules_filename);
}
void falco_engine::enable_rule(const std::string &substring, bool enabled, const std::string &ruleset)
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
enable_rule(substring, enabled, ruleset_id);
}
void falco_engine::enable_rule(const std::string &substring, bool enabled, const uint16_t ruleset_id)
{
bool match_exact = false;
for(const auto &it : m_sources)
@@ -260,12 +279,6 @@ void falco_engine::enable_rule(const std::string &substring, bool enabled, const
void falco_engine::enable_rule_exact(const std::string &rule_name, bool enabled, const std::string &ruleset)
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
enable_rule_exact(rule_name, enabled, ruleset_id);
}
void falco_engine::enable_rule_exact(const std::string &rule_name, bool enabled, const uint16_t ruleset_id)
{
bool match_exact = true;
for(const auto &it : m_sources)
@@ -285,11 +298,6 @@ void falco_engine::enable_rule_by_tag(const std::set<std::string> &tags, bool en
{
uint16_t ruleset_id = find_ruleset_id(ruleset);
enable_rule_by_tag(tags, enabled, ruleset_id);
}
void falco_engine::enable_rule_by_tag(const std::set<std::string> &tags, bool enabled, const uint16_t ruleset_id)
{
for(const auto &it : m_sources)
{
if(enabled)
@@ -339,7 +347,7 @@ libsinsp::events::set<ppm_sc_code> falco_engine::sc_codes_for_ruleset(const std:
{
return find_source(source)->ruleset->enabled_sc_codes(find_ruleset_id(ruleset));
}
libsinsp::events::set<ppm_event_code> falco_engine::event_codes_for_ruleset(const std::string &source, const std::string &ruleset)
{
return find_source(source)->ruleset->enabled_event_codes(find_ruleset_id(ruleset));
@@ -360,7 +368,21 @@ std::unique_ptr<std::vector<falco_engine::rule_result>> falco_engine::process_ev
// source_idx, which means that at any time each filter_ruleset will only
// be accessed by a single thread.
const falco_source *source = find_source(source_idx);
const falco_source *source;
if(source_idx == m_syscall_source_idx)
{
if(m_syscall_source == NULL)
{
m_syscall_source = find_source(m_syscall_source_idx);
}
source = m_syscall_source;
}
else
{
source = find_source(source_idx);
}
if(should_drop_evt() || !source)
{
@@ -446,88 +468,106 @@ std::size_t falco_engine::add_source(const std::string &source,
return m_sources.insert(src, source);
}
template <typename T> inline nlohmann::json sequence_to_json_array(const T& seq)
void falco_engine::describe_rule(std::string *rule, bool json) const
{
nlohmann::json ret = nlohmann::json::array();
for (const auto& v : seq)
if(!json)
{
ret.push_back(v);
}
return ret;
}
static const char *rule_fmt = "%-50s %s\n";
fprintf(stdout, rule_fmt, "Rule", "Description");
fprintf(stdout, rule_fmt, "----", "-----------");
if(!rule)
{
for(auto &r : m_rules)
{
auto str = falco::utils::wrap_text(r.description, 51, 110) + "\n";
fprintf(stdout, rule_fmt, r.name.c_str(), str.c_str());
}
}
else
{
auto r = m_rules.at(*rule);
if(r == nullptr)
{
return;
}
auto str = falco::utils::wrap_text(r->description, 51, 110) + "\n";
fprintf(stdout, rule_fmt, r->name.c_str(), str.c_str());
}
nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const
{
// use previously-loaded collector definitions and the compiled
// output of rules, macros, and lists.
if (m_last_compile_output == nullptr)
{
throw falco_exception("rules must be loaded before describing them");
return;
}
// use collected and compiled info to print a json output
nlohmann::json output;
std::unique_ptr<sinsp> insp(new sinsp());
Json::FastWriter writer;
std::string json_str;
if(!rule)
{
// In this case we build json information about
// all rules, macros and lists
Json::Value output;
// Store required engine version
auto required_engine_version = m_rule_collector.required_engine_version();
output["required_engine_version"] = required_engine_version.version.as_string();
output["required_engine_version"] = std::to_string(required_engine_version.version);
// Store required plugin versions
nlohmann::json plugin_versions = nlohmann::json::array();
Json::Value plugin_versions = Json::arrayValue;
auto required_plugin_versions = m_rule_collector.required_plugin_versions();
for(const auto& req : required_plugin_versions)
{
nlohmann::json r;
Json::Value r;
r["name"] = req.at(0).name;
r["version"] = req.at(0).version;
nlohmann::json alternatives = nlohmann::json::array();
Json::Value alternatives = Json::arrayValue;
for(size_t i = 1; i < req.size(); i++)
{
nlohmann::json alternative;
Json::Value alternative;
alternative["name"] = req[i].name;
alternative["version"] = req[i].version;
alternatives.push_back(std::move(alternative));
alternatives.append(alternative);
}
r["alternatives"] = std::move(alternatives);
plugin_versions.push_back(std::move(r));
r["alternatives"] = alternatives;
plugin_versions.append(r);
}
output["required_plugin_versions"] = std::move(plugin_versions);
output["required_plugin_versions"] = plugin_versions;
// Store information about rules
nlohmann::json rules_array = nlohmann::json::array();
for(const auto& r : m_last_compile_output->rules)
Json::Value rules_array = Json::arrayValue;
for(const auto& r : m_rules)
{
auto info = m_rule_collector.rules().at(r.name);
nlohmann::json rule;
get_json_details(rule, r, *info, plugins);
rules_array.push_back(std::move(rule));
}
output["rules"] = std::move(rules_array);
auto ri = m_rule_collector.rules().at(r.name);
Json::Value rule;
get_json_details(r, *ri, insp.get(), rule);
// Append to rule array
rules_array.append(rule);
}
output["rules"] = rules_array;
// Store information about macros
nlohmann::json macros_array = nlohmann::json::array();
for(const auto &m : m_last_compile_output->macros)
Json::Value macros_array;
for(const auto &m : m_rule_collector.macros())
{
auto info = m_rule_collector.macros().at(m.name);
nlohmann::json macro;
get_json_details(macro, m, *info, plugins);
macros_array.push_back(std::move(macro));
Json::Value macro;
get_json_details(m, macro);
macros_array.append(macro);
}
output["macros"] = std::move(macros_array);
output["macros"] = macros_array;
// Store information about lists
nlohmann::json lists_array = nlohmann::json::array();
for(const auto &l : m_last_compile_output->lists)
// Store information about lists
Json::Value lists_array = Json::arrayValue;
for(const auto &l : m_rule_collector.lists())
{
auto info = m_rule_collector.lists().at(l.name);
nlohmann::json list;
get_json_details(list, l, *info, plugins);
lists_array.push_back(std::move(list));
Json::Value list;
get_json_details(l, list);
lists_array.append(list);
}
output["lists"] = std::move(lists_array);
output["lists"] = lists_array;
json_str = writer.write(output);
}
else
{
@@ -538,77 +578,69 @@ nlohmann::json falco_engine::describe_rule(std::string *rule, const std::vector<
throw falco_exception("Rule \"" + *rule + "\" is not loaded");
}
auto r = m_rules.at(ri->name);
nlohmann::json rule;
get_json_details(rule, *r, *ri, plugins);
nlohmann::json rules_array = nlohmann::json::array();
rules_array.push_back(std::move(rule));
output["rules"] = std::move(rules_array);
Json::Value rule;
get_json_details(*r, *ri, insp.get(), rule);
json_str = writer.write(rule);
}
return output;
fprintf(stdout, "%s", json_str.c_str());
}
void falco_engine::get_json_details(
nlohmann::json &out,
const falco_rule &r,
const rule_loader::rule_info &info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const
void falco_engine::get_json_details(const falco_rule &r,
const rule_loader::rule_info &ri,
sinsp *insp,
Json::Value &rule) const
{
nlohmann::json rule_info;
Json::Value rule_info;
// Fill general rule information
rule_info["name"] = r.name;
rule_info["condition"] = info.cond;
rule_info["condition"] = ri.cond;
rule_info["priority"] = format_priority(r.priority, false);
rule_info["output"] = info.output;
rule_info["output"] = r.output;
rule_info["description"] = r.description;
rule_info["enabled"] = info.enabled;
rule_info["enabled"] = ri.enabled;
rule_info["source"] = r.source;
rule_info["tags"] = sequence_to_json_array(info.tags);
out["info"] = std::move(rule_info);
// Parse rule condition and build the non-compiled AST
// Assumption: no error because rules have already been loaded.
auto ast = libsinsp::filter::parser(info.cond).parse();
// get details related to the condition's filter
filter_details details;
filter_details compiled_details;
nlohmann::json json_details;
for(const auto &m : m_rule_collector.macros())
Json::Value tags = Json::arrayValue;
for(const auto &t : ri.tags)
{
details.known_macros.insert(m.name);
compiled_details.known_macros.insert(m.name);
tags.append(t);
}
for(const auto &l : m_rule_collector.lists())
{
details.known_lists.insert(l.name);
compiled_details.known_lists.insert(l.name);
}
filter_details_resolver().run(ast.get(), details);
filter_details_resolver().run(r.condition.get(), compiled_details);
rule_info["tags"] = tags;
rule["info"] = rule_info;
out["details"]["macros"] = sequence_to_json_array(details.macros);
out["details"]["lists"] = sequence_to_json_array(details.lists);
out["details"]["condition_operators"] = sequence_to_json_array(compiled_details.operators);
out["details"]["condition_fields"] = sequence_to_json_array(compiled_details.fields);
// Parse rule condition and build the AST
// Assumption: no exception because rules have already been loaded.
auto ast = libsinsp::filter::parser(ri.cond).parse();
Json::Value json_details;
get_json_details(ast.get(), json_details);
rule["details"] = json_details;
// Get fields from output string
auto fmt = create_formatter(r.source, r.output);
std::vector<std::string> out_fields;
fmt->get_field_names(out_fields);
out["details"]["output_fields"] = sequence_to_json_array(out_fields);
Json::Value outputFields = Json::arrayValue;
for(const auto &of : out_fields)
{
outputFields.append(of);
}
rule["details"]["output_fields"] = outputFields;
// Get fields from exceptions
out["details"]["exception_fields"] = sequence_to_json_array(r.exception_fields);
Json::Value exception_fields = Json::arrayValue;
for(const auto &f : r.exception_fields)
{
exception_fields.append(f);
}
rule["details"]["exception_fields"] = exception_fields;
// Get names and operators from exceptions
std::unordered_set<std::string> exception_names;
std::unordered_set<std::string> exception_operators;
for(const auto &e : info.exceptions)
Json::Value exception_names = Json::arrayValue;
Json::Value exception_operators = Json::arrayValue;
for(const auto &e : ri.exceptions)
{
exception_names.insert(e.name);
exception_names.append(e.name);
if(e.comps.is_list)
{
for(const auto& c : e.comps.items)
@@ -618,239 +650,140 @@ void falco_engine::get_json_details(
// considering max two levels of lists
for(const auto& i : c.items)
{
exception_operators.insert(i.item);
exception_operators.append(i.item);
}
}
else
{
exception_operators.insert(c.item);
exception_operators.append(c.item);
}
}
}
else
{
exception_operators.insert(e.comps.item);
}
exception_operators.append(e.comps.item);
}
}
out["details"]["exception_names"] = sequence_to_json_array(exception_names);
out["details"]["exception_operators"] = sequence_to_json_array(exception_operators);
rule["details"]["exceptions"] = exception_names;
rule["details"]["exception_operators"] = exception_operators;
// Store event types
nlohmann::json events;
get_json_evt_types(events, info.source, r.condition.get());
out["details"]["events"] = std::move(events);
// Store compiled condition and output
out["details"]["condition_compiled"] = libsinsp::filter::ast::as_string(r.condition.get());
out["details"]["output_compiled"] = r.output;
// Compute the plugins that are actually used by this rule. This is involves:
// - The rule's event source, that can be implemented by a plugin
// - The fields used in the rule's condition, output, and exceptions
// - The evt types used in the rule's condition checks, that can potentially
// match plugin-provided async events
nlohmann::json used_plugins;
// note: making a union of conditions's and output's fields
// note: the condition's AST accounts for all the resolved refs and exceptions
compiled_details.fields.insert(out_fields.begin(), out_fields.end());
get_json_used_plugins(used_plugins, info.source, compiled_details.evtnames, compiled_details.fields, plugins);
out["details"]["plugins"] = std::move(used_plugins);
if(ri.source == falco_common::syscall_source)
{
// Store event types
Json::Value events;
get_json_evt_types(ast.get(), events);
rule["details"]["events"] = events;
}
}
void falco_engine::get_json_details(
nlohmann::json& out,
const falco_macro& m,
const rule_loader::macro_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const
void falco_engine::get_json_details(const rule_loader::macro_info& m,
Json::Value& macro) const
{
nlohmann::json macro_info;
Json::Value macro_info;
macro_info["name"] = m.name;
macro_info["condition"] = info.cond;
out["info"] = std::move(macro_info);
macro_info["condition"] = m.cond;
macro["info"] = macro_info;
// Parse the macro condition and build the non-compiled AST
// Assumption: no exception because rules have already been loaded.
auto ast = libsinsp::filter::parser(info.cond).parse();
auto ast = libsinsp::filter::parser(m.cond).parse();
// get details related to the condition's filter
Json::Value json_details;
get_json_details(ast.get(), json_details);
macro["details"] = json_details;
// Store event types
Json::Value events;
get_json_evt_types(ast.get(), events);
macro["details"]["events"] = events;
}
void falco_engine::get_json_details(const rule_loader::list_info& l,
Json::Value& list) const
{
Json::Value list_info;
list_info["name"] = l.name;
Json::Value items = Json::arrayValue;
Json::Value lists = Json::arrayValue;
for(const auto &i : l.items)
{
if(m_rule_collector.lists().at(i) != nullptr)
{
lists.append(i);
continue;
}
items.append(i);
}
list_info["items"] = items;
list["info"] = list_info;
list["details"]["lists"] = lists;
}
void falco_engine::get_json_details(libsinsp::filter::ast::expr* ast,
Json::Value& output) const
{
filter_details details;
filter_details compiled_details;
nlohmann::json json_details;
for(const auto &m : m_rule_collector.macros())
{
details.known_macros.insert(m.name);
compiled_details.known_macros.insert(m.name);
}
for(const auto &l : m_rule_collector.lists())
{
details.known_lists.insert(l.name);
compiled_details.known_lists.insert(l.name);
}
filter_details_resolver().run(ast.get(), details);
filter_details_resolver().run(m.condition.get(), compiled_details);
out["details"]["used"] = m.used;
out["details"]["macros"] = sequence_to_json_array(details.macros);
out["details"]["lists"] = sequence_to_json_array(details.lists);
out["details"]["condition_operators"] = sequence_to_json_array(compiled_details.operators);
out["details"]["condition_fields"] = sequence_to_json_array(compiled_details.fields);
// Resolve the AST details
filter_details_resolver resolver;
resolver.run(ast, details);
// Store event types
nlohmann::json events;
get_json_evt_types(events, "", m.condition.get());
out["details"]["events"] = std::move(events);
Json::Value macros = Json::arrayValue;
for(const auto &m : details.macros)
{
macros.append(m);
}
output["macros"] = macros;
// Store compiled condition
out["details"]["condition_compiled"] = libsinsp::filter::ast::as_string(m.condition.get());
Json::Value operators = Json::arrayValue;
for(const auto &o : details.operators)
{
operators.append(o);
}
output["operators"] = operators;
// Compute the plugins that are actually used by this macro.
// Note: macros have no specific source, we need to set an empty list of used
// plugins because we can't be certain about their actual usage. For example,
// if a macro uses a plugin's field, we can't be sure which plugin actually
// is used until we resolve the macro ref in a rule providing a source for
// disambiguation.
out["details"]["plugins"] = nlohmann::json::array();
Json::Value condition_fields = Json::arrayValue;
for(const auto &f : details.fields)
{
condition_fields.append(f);
}
output["condition_fields"] = condition_fields;
Json::Value lists = Json::arrayValue;
for(const auto &l : details.lists)
{
lists.append(l);
}
output["lists"] = lists;
details.reset();
}
void falco_engine::get_json_details(
nlohmann::json& out,
const falco_list& l,
const rule_loader::list_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const
void falco_engine::get_json_evt_types(libsinsp::filter::ast::expr* ast,
Json::Value& output) const
{
nlohmann::json list_info;
list_info["name"] = l.name;
// note: the syntactic definitions still has the list refs unresolved
nlohmann::json items = nlohmann::json::array();
std::unordered_set<std::string> lists;
for(const auto &i : info.items)
output = Json::arrayValue;
auto evtcodes = libsinsp::filter::ast::ppm_event_codes(ast);
auto syscodes = libsinsp::filter::ast::ppm_sc_codes(ast);
auto syscodes_to_evt_names = libsinsp::events::sc_set_to_event_names(syscodes);
auto evtcodes_to_evt_names = libsinsp::events::event_set_to_names(evtcodes, false);
for (const auto& n : unordered_set_union(syscodes_to_evt_names, evtcodes_to_evt_names))
{
// if an item is present in the syntactic def of a list, but not
// on the compiled_items of the same list, then we can assume it
// being a resolved list ref
if(std::find(l.items.begin(), l.items.end(), i) == l.items.end())
{
lists.insert(i);
continue;
}
items.push_back(std::move(i));
}
list_info["items"] = std::move(items);
out["info"] = std::move(list_info);
out["details"]["used"] = l.used;
out["details"]["lists"] = sequence_to_json_array(lists);
out["details"]["items_compiled"] = sequence_to_json_array(l.items);
out["details"]["plugins"] = nlohmann::json::array(); // always empty
}
void falco_engine::get_json_evt_types(
nlohmann::json& out,
const std::string& source,
libsinsp::filter::ast::expr* ast) const
{
// note: this duplicates part of the logic of evttype_index_ruleset,
// not good but it's our best option for now
if (source.empty() || source == falco_common::syscall_source)
{
auto evtcodes = libsinsp::filter::ast::ppm_event_codes(ast);
evtcodes.insert(ppm_event_code::PPME_ASYNCEVENT_E);
auto syscodes = libsinsp::filter::ast::ppm_sc_codes(ast);
auto syscodes_to_evt_names = libsinsp::events::sc_set_to_event_names(syscodes);
auto evtcodes_to_evt_names = libsinsp::events::event_set_to_names(evtcodes, false);
out = sequence_to_json_array(unordered_set_union(syscodes_to_evt_names, evtcodes_to_evt_names));
}
else
{
out = sequence_to_json_array(libsinsp::events::event_set_to_names(
{ppm_event_code::PPME_PLUGINEVENT_E, ppm_event_code::PPME_ASYNCEVENT_E}));
output.append(n);
}
}
void falco_engine::get_json_used_plugins(
nlohmann::json& out,
const std::string& source,
const std::unordered_set<std::string>& evtnames,
const std::unordered_set<std::string>& fields,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const
{
// note: condition and output fields may have an argument, so
// we need to isolate the field names
std::unordered_set<std::string> fieldnames;
for (const auto &f: fields)
{
auto argpos = f.find('[');
if (argpos != std::string::npos)
{
fieldnames.insert(f.substr(0, argpos));
}
else
{
fieldnames.insert(f);
}
}
std::unordered_set<std::string> used_plugins;
for (const auto& p : plugins)
{
bool used = false;
if (p->caps() & CAP_SOURCING)
{
// The rule's source is implemented by a plugin with event
// sourcing capability.
// Note: if Falco loads two plugins implementing the same source,
// they will both be included in the list.
if (!used && p->event_source() == source)
{
used_plugins.insert(p->name());
used = true;
}
}
if (!used && p->caps() & CAP_EXTRACTION)
{
// The rule uses a field implemented by a plugin with field
// extraction capability that is compatible with the rule's source.
// Note: here we're assuming that Falco will prevent loading
// plugins implementing fields with the same name for the same
// event source (implemented in init_inspectors app action).
if (sinsp_plugin::is_source_compatible(p->extract_event_sources(), source))
{
for (const auto &f : p->fields())
{
if (!used && fieldnames.find(f.m_name) != fieldnames.end())
{
used_plugins.insert(p->name());
used = true;
break;
}
}
}
}
if (!used && p->caps() & CAP_ASYNC)
{
// The rule matches an event type implemented by a plugin with
// async events capability that is compatible with the rule's source.
// Note: if Falco loads two plugins implementing async events with
// the same name, they will both be included in the list.
if (sinsp_plugin::is_source_compatible(p->async_event_sources(), source))
{
for (const auto &n : p->async_event_names())
{
if (!used && evtnames.find(n) != evtnames.end())
{
used_plugins.insert(p->name());
used = true;
break;
}
}
}
}
}
out = sequence_to_json_array(used_plugins);
}
void falco_engine::print_stats() const
{
@@ -865,50 +798,6 @@ bool falco_engine::is_source_valid(const std::string &source) const
return m_sources.at(source) != nullptr;
}
std::shared_ptr<gen_event_filter_factory> falco_engine::filter_factory_for_source(const std::string& source)
{
return find_source(source)->filter_factory;
}
std::shared_ptr<gen_event_filter_factory> falco_engine::filter_factory_for_source(std::size_t source_idx)
{
return find_source(source_idx)->filter_factory;
}
std::shared_ptr<gen_event_formatter_factory> falco_engine::formatter_factory_for_source(const std::string& source)
{
return find_source(source)->formatter_factory;
}
std::shared_ptr<gen_event_formatter_factory> falco_engine::formatter_factory_for_source(std::size_t source_idx)
{
return find_source(source_idx)->formatter_factory;
}
std::shared_ptr<filter_ruleset_factory> falco_engine::ruleset_factory_for_source(const std::string& source)
{
return find_source(source)->ruleset_factory;
}
std::shared_ptr<filter_ruleset_factory> falco_engine::ruleset_factory_for_source(std::size_t source_idx)
{
return find_source(source_idx)->ruleset_factory;
}
std::shared_ptr<filter_ruleset> falco_engine::ruleset_for_source(const std::string& source_name)
{
const falco_source *source = find_source(source_name);
return source->ruleset;
}
std::shared_ptr<filter_ruleset> falco_engine::ruleset_for_source(std::size_t source_idx)
{
const falco_source *source = find_source(source_idx);
return source->ruleset;
}
void falco_engine::read_file(const std::string& filename, std::string& contents)
{
std::ifstream is;
@@ -923,6 +812,29 @@ void falco_engine::read_file(const std::string& filename, std::string& contents)
std::istreambuf_iterator<char>());
}
void falco_engine::interpret_load_result(std::unique_ptr<load_result>& res,
const std::string& rules_filename,
const std::string& rules_content,
bool verbose)
{
falco::load_result::rules_contents_t rc = {{rules_filename, rules_content}};
if(!res->successful())
{
// The output here is always the full e.g. "verbose" output.
throw falco_exception(res->as_string(true, rc).c_str());
}
if(verbose && res->has_warnings())
{
// Here, verbose controls whether to additionally
// "log" e.g. print to stderr. What's logged is always
// non-verbose so it fits on a single line.
// todo(jasondellaluce): introduce a logging callback in Falco
fprintf(stderr, "%s\n", res->as_string(false, rc).c_str());
}
}
static bool check_plugin_requirement_alternatives(
const std::vector<falco_engine::plugin_version_requirement>& plugins,
const rule_loader::plugin_version_info::requirement_alternatives& alternatives,
@@ -936,14 +848,14 @@ static bool check_plugin_requirement_alternatives(
{
sinsp_version req_version(req.version);
sinsp_version plugin_version(plugin.version);
if(!plugin_version.is_valid())
if(!plugin_version.m_valid)
{
err = "Plugin '" + plugin.name
+ "' has invalid version string '"
+ plugin.version + "'";
return false;
}
if (!plugin_version.compatible_with(req_version))
if (!plugin_version.check(req_version))
{
err = "Plugin '" + plugin.name
+ "' version '" + plugin.version

View File

@@ -1,6 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
/*
Copyright (C) 2023 The Falco Authors.
Copyright (C) 2019 The Falco Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -39,8 +38,6 @@ limitations under the License.
#include "falco_source.h"
#include "falco_load_result.h"
#include "filter_details_resolver.h"
#include "rule_loader_reader.h"
#include "rule_loader_compiler.h"
//
// This class acts as the primary interface between a program and the
@@ -58,24 +55,22 @@ public:
// and rules file format it supports. This version will change
// any time the code that handles rules files, expression
// fields, etc, changes.
static sinsp_version engine_version();
// Engine version used to be represented as a simple progressive
// number. With the new semver schema, the number now represents
// the semver minor number. This function converts the legacy version
// number to the new semver schema.
static inline sinsp_version get_implicit_version(uint32_t minor)
{
return rule_loader::reader::get_implicit_engine_version(minor);
}
static uint32_t engine_version();
// Print to stdout (using printf) a description of each field supported by this engine.
// If source is non-empty, only fields for the provided source are printed.
void list_fields(std::string &source, bool verbose, bool names_only, bool markdown) const;
//
// Load rules and returns a result object.
// Load rules either directly or from a filename.
//
void load_rules_file(const std::string &rules_filename, bool verbose, bool all_events);
void load_rules(const std::string &rules_content, bool verbose, bool all_events);
//
// Identical to above, but returns a result object instead of
// throwing exceptions on error.
std::unique_ptr<falco::load_result> load_rules_file(const std::string &rules_filename);
std::unique_ptr<falco::load_result> load_rules(const std::string &rules_content, const std::string &name);
//
@@ -89,23 +84,15 @@ public:
//
void enable_rule(const std::string &substring, bool enabled, const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule(const std::string &substring, bool enabled, const uint16_t ruleset_id);
// Like enable_rule, but the rule name must be an exact match.
void enable_rule_exact(const std::string &rule_name, bool enabled, const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule_exact(const std::string &rule_name, bool enabled, const uint16_t ruleset_id);
//
// Enable/Disable any rules with any of the provided tags (set, exact matches only)
//
void enable_rule_by_tag(const std::set<std::string> &tags, bool enabled, const std::string &ruleset = s_default_ruleset);
// Same as above but providing a ruleset id instead
void enable_rule_by_tag(const std::set<std::string> &tags, bool enabled, const uint16_t ruleset_id);
//
// Must be called after the engine has been configured and all rulesets
// have been loaded and enabled/disabled.
@@ -137,7 +124,7 @@ public:
// Print details on the given rule. If rule is NULL, print
// details on all rules.
//
nlohmann::json describe_rule(std::string *rule, const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void describe_rule(std::string *rule, bool json) const;
//
// Print statistics on how many events matched each rule.
@@ -235,31 +222,6 @@ public:
// factory for this source.
bool is_source_valid(const std::string &source) const;
//
// Given a source, return a formatter factory that can create
// filters for events of that source.
//
std::shared_ptr<gen_event_filter_factory> filter_factory_for_source(const std::string& source);
std::shared_ptr<gen_event_filter_factory> filter_factory_for_source(std::size_t source_idx);
//
// Given a source, return a formatter factory that can create
// formatters for an event.
//
std::shared_ptr<gen_event_formatter_factory> formatter_factory_for_source(const std::string& source);
std::shared_ptr<gen_event_formatter_factory> formatter_factory_for_source(std::size_t source_idx);
//
// Given a source, return a ruleset factory that can create
// rulesets for that source.
//
std::shared_ptr<filter_ruleset_factory> ruleset_factory_for_source(const std::string& source);
std::shared_ptr<filter_ruleset_factory> ruleset_factory_for_source(std::size_t source_idx);
// Return the filter_ruleset used for a given source.
std::shared_ptr<filter_ruleset> ruleset_for_source(const std::string& source);
std::shared_ptr<filter_ruleset> ruleset_for_source(std::size_t source_idx);
//
// Given an event source and ruleset, fill in a bitset
// containing the event types for which this ruleset can run.
@@ -314,46 +276,17 @@ private:
// Throws falco_exception if the file can not be read
void read_file(const std::string& filename, std::string& contents);
// For load_rules methods that throw exceptions on error,
// interpret a load_result and throw an exception if needed.
void interpret_load_result(std::unique_ptr<falco::load_result>& res,
const std::string& rules_filename,
const std::string& rules_content,
bool verbose);
indexed_vector<falco_source> m_sources;
inline const falco_source* find_source(std::size_t index)
{
const falco_source *source;
if(index == m_syscall_source_idx)
{
if(m_syscall_source == NULL)
{
m_syscall_source = m_sources.at(m_syscall_source_idx);
if(!m_syscall_source)
{
throw falco_exception("Unknown event source index " + std::to_string(index));
}
}
source = m_syscall_source;
}
else
{
source = m_sources.at(index);
if(!source)
{
throw falco_exception("Unknown event source index " + std::to_string(index));
}
}
return source;
}
inline const falco_source* find_source(const std::string& name) const
{
auto ret = m_sources.at(name);
if(!ret)
{
throw falco_exception("Unknown event source " + name);
}
return ret;
}
const falco_source* find_source(std::size_t index) const;
const falco_source* find_source(const std::string& name) const;
// To allow the engine to be extremely fast for syscalls (can
// be > 1M events/sec), we save the syscall source/source_idx
@@ -369,31 +302,18 @@ private:
inline bool should_drop_evt() const;
// Retrieve json details from rules, macros, lists
void get_json_details(
nlohmann::json& out,
const falco_rule& r,
const rule_loader::rule_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_details(
nlohmann::json& out,
const falco_macro& m,
const rule_loader::macro_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_details(
nlohmann::json& out,
const falco_list& l,
const rule_loader::list_info& info,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_evt_types(
nlohmann::json& out,
const std::string& source,
libsinsp::filter::ast::expr* ast) const;
void get_json_used_plugins(
nlohmann::json& out,
const std::string& source,
const std::unordered_set<std::string>& evttypes,
const std::unordered_set<std::string>& fields,
const std::vector<std::shared_ptr<sinsp_plugin>>& plugins) const;
void get_json_details(const falco_rule& r,
const rule_loader::rule_info& ri,
sinsp* insp,
Json::Value& rule) const;
void get_json_details(const rule_loader::macro_info& m,
Json::Value& macro) const;
void get_json_details(const rule_loader::list_info& l,
Json::Value& list) const;
void get_json_details(libsinsp::filter::ast::expr* ast,
Json::Value& output) const;
void get_json_evt_types(libsinsp::filter::ast::expr* ast,
Json::Value& output) const;
rule_loader::collector m_rule_collector;
indexed_vector<falco_rule> m_rules;
@@ -403,8 +323,6 @@ private:
std::map<std::string, uint16_t> m_known_rulesets;
falco_common::priority_type m_min_priority;
std::unique_ptr<rule_loader::compiler::compile_output> m_last_compile_output;
//
// Here's how the sampling ratio and multiplier influence
// whether or not an event is dropped in
@@ -434,3 +352,4 @@ private:
std::string m_extra;
bool m_replace_container_info;
};

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