Files
falco/scripts/falco-driver-loader
Jeremi Piotrowski 85f91a3ec4 update(falco_scripts): support pre-built module/probe on Flatcar
Pre-built kernel modules/eBPF probes for Flatcar use the value of the OS
VERSION_ID field as KERNEL_RELEASE in the filename. A specific kernel release
version does not uniquely identify a Flatcar configuration, because Flatcar is
image-based instead of package-based. Here's a more specific example: the same
kernel version can be part of various Flatcar releases (across channels
alpha/beta/stable) with differences in configuration. This is why we use the
VERSION_ID value during offline builds with driverkit. Flatcar version numbers
are all higher than 1500.0.0, so there is no risk of collision with kernel
version numbers.

When locally building the kernel module on the system, we have access to the
correct kernel build directory at /lib/modules/$(uname -r)/build with the right
configuration and so for that branch, we need to reset KERNEL_RELEASE=$(uname -r).

See also the driverkit PR that introduces a builder for Flatcar:
https://github.com/falcosecurity/driverkit/pull/131

Signed-off-by: Jeremi Piotrowski <jpiotrowski@microsoft.com>
2022-06-13 10:34:43 +02:00

704 lines
20 KiB
Bash
Executable File

#!/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/VERSION" ]; then
OS_ID=minikube
else
>&2 echo "Detected an unsupported target system, please get in touch with the Falco community"
exit 1
fi
case "${OS_ID}" in
("amzn")
if [[ $VERSION_ID == "2" ]]; then
TARGET_ID="amazonlinux2"
else
TARGET_ID="amazonlinux"
fi
;;
("ubuntu")
if [[ $KERNEL_RELEASE == *"aws"* ]]; then
TARGET_ID="ubuntu-aws"
else
TARGET_ID="ubuntu-generic"
fi
;;
("flatcar")
KERNEL_RELEASE="${VERSION_ID}"
TARGET_ID=$(echo "${OS_ID}" | tr '[:upper:]' '[:lower:]')
;;
(*)
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-*.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 [[ $(uname -r) == *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=$(uname -r)
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 $(which gcc) $(ls "$(dirname "$(which gcc)")"/gcc-* | grep 'gcc-[0-9]\+' | sort -n -r -k 2 -t -); do
echo "* Trying to dkms install ${DRIVER_NAME} module with GCC ${CURRENT_GCC}"
echo "#!/usr/bin/env bash" > /tmp/falco-dkms-make
echo "make CC=${CURRENT_GCC} \$@" >> /tmp/falco-dkms-make
chmod +x /tmp/falco-dkms-make
if dkms install --directive="MAKE='/tmp/falco-dkms-make'" -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then
echo "* ${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 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
else
echo "* Unable to insmod ${DRIVER_NAME} module"
fi
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() {
get_target_id
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
local URL=$(echo "${DRIVERS_REPO}/${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/${FALCO_KERNEL_MODULE_FILENAME}" "${URL}"; then
echo "* Download succeeded"
chcon -t modules_object_t "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
if insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}"; then
echo "* Success: ${DRIVER_NAME} module found and inserted"
exit 0
else
>&2 echo "Unable to insmod the prebuilt ${DRIVER_NAME} module"
fi
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
}
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})"
get_target_id
local FALCO_KERNEL_MODULE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.ko"
if [ -f "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" ]; then
echo "* Found a prebuilt ${DRIVER_NAME} module at ${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}, loading it"
chcon -t modules_object_t "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" > /dev/null 2>&1 || true
insmod "${HOME}/.falco/${FALCO_KERNEL_MODULE_FILENAME}" && echo "* Success: ${DRIVER_NAME} module found and inserted"
exit $?
fi
if [ -n "$ENABLE_DOWNLOAD" ]; then
load_kernel_module_download
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}" == "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=$(uname -r)
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=$(uname -r | cut -d. -f1)
local -r kernel_version=$(uname -r | cut -d- -f1)
KERNEL_EXTRA_VERSION="-$(uname -r | 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"
mv "/usr/src/${DRIVER_NAME}-${DRIVER_VERSION}/bpf/probe.o" "${HOME}/.falco/${BPF_PROBE_FILENAME}"
if [ -n "${BPF_KERNEL_SOURCES_URL}" ]; then
rm -r /tmp/kernel
fi
}
load_bpf_probe_download() {
local URL
URL=$(echo "${DRIVERS_REPO}/${DRIVER_VERSION}/${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/${BPF_PROBE_FILENAME}" "${URL}"; then
>&2 echo "Unable to find a prebuilt ${DRIVER_NAME} eBPF probe"
return
fi
}
load_bpf_probe() {
echo "* Mounting debugfs"
if [ ! -d /sys/kernel/debug/tracing ]; then
mount -t debugfs nodev /sys/kernel/debug
fi
get_target_id
BPF_PROBE_FILENAME="${DRIVER_NAME}_${TARGET_ID}_${KERNEL_RELEASE}_${KERNEL_VERSION}.o"
if [ -n "$ENABLE_DOWNLOAD" ]; then
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
echo "* Skipping download, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}"
else
load_bpf_probe_download
fi
fi
if [ -n "$ENABLE_COMPILE" ]; then
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
echo "* Skipping compilation, eBPF probe is already present in ${HOME}/.falco/${BPF_PROBE_FILENAME}"
else
load_bpf_probe_compile
fi
fi
if [ -f "${HOME}/.falco/${BPF_PROBE_FILENAME}" ]; then
echo "* eBPF probe located in ${HOME}/.falco/${BPF_PROBE_FILENAME}"
ln -sf "${HOME}/.falco/${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"
echo ""
echo "Environment variables:"
echo " DRIVERS_REPO specify a different URL where to look for prebuilt Falco drivers"
echo " DRIVER_NAME specify a different name for the driver"
echo " DRIVER_INSECURE_DOWNLOAD whether you want to allow insecure downloads or not"
echo ""
echo "Versions:"
echo " Falco version ${FALCO_VERSION}"
echo " Driver version ${DRIVER_VERSION}"
echo ""
}
ARCH=$(uname -m)
KERNEL_RELEASE=$(uname -r)
if ! hash sed > /dev/null 2>&1; then
>&2 echo "This program requires sed"
exit 1
fi
KERNEL_VERSION=$(uname -v | sed 's/#\([[:digit:]]\+\).*/\1/')
DRIVERS_REPO=${DRIVERS_REPO:-"@DRIVERS_REPO@"}
if [ -n "$DRIVER_INSECURE_DOWNLOAD" ]
then
FALCO_DRIVER_CURL_OPTIONS=-fsSk
else
FALCO_DRIVER_CURL_OPTIONS=-fsS
fi
if [[ -z "$MAX_RMMOD_WAIT" ]]; then
MAX_RMMOD_WAIT=60
fi
DRIVER_VERSION="@DRIVER_VERSION@"
DRIVER_NAME=${DRIVER_NAME:-"@DRIVER_NAME@"}
FALCO_VERSION="@FALCO_VERSION@"
DRIVER="module"
if [ -v FALCO_BPF_PROBE ]; then
DRIVER="bpf"
fi
ENABLE_COMPILE=
ENABLE_DOWNLOAD=
clean=
has_args=
has_opts=
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
;;
--*)
>&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 [ -z "$source_only" ]; then
echo "* Running falco-driver-loader for: falco version=${FALCO_VERSION}, driver version=${DRIVER_VERSION}"
if [ "$(id -u)" != 0 ]; then
>&2 echo "This program must be run as root (or with sudo)"
exit 1
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
fi