|
|
|
@ -1,866 +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.
|
|
|
|
|
#
|
|
|
|
|
# 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
|