From 1efa4d3af02734aa3478b86c0301bf50dd34afcf Mon Sep 17 00:00:00 2001 From: Lorenzo Fontana Date: Wed, 16 Sep 2020 16:14:24 +0200 Subject: [PATCH] update(scripts): driver loader cycle available gcc versions The falco-driver-loader script calls dkms to compile the kernel module using the default gcc. In some systems, and in the falcosecurity/falco container image, the defult gcc is not the right one to compile it. The script will try to compile the module by cycling trough all the available GCCs starting from the default one until the module is compiled the first time. The default gcc is the highest priority while trying. Newer GCCs have the priority over older GCCs. Co-Authored-By: Leonardo Di Donato Signed-off-by: Lorenzo Fontana --- scripts/falco-driver-loader | 54 +++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 23 deletions(-) diff --git a/scripts/falco-driver-loader b/scripts/falco-driver-loader index ede39889..be727e97 100755 --- a/scripts/falco-driver-loader +++ b/scripts/falco-driver-loader @@ -143,33 +143,41 @@ load_kernel_module_compile() { # skip dkms on UEK hosts because it will always fail if [[ $(uname -r) == *uek* ]]; then echo "* Skipping dkms install for UEK host" - else - if hash dkms &>/dev/null; then - echo "* Trying to dkms install ${DRIVER_NAME} module" - if dkms install -m "${DRIVER_NAME}" -v "${DRIVER_VERSION}" -k "${KERNEL_RELEASE}" 2>/dev/null; then - echo "* ${DRIVER_NAME} module installed in dkms, trying to insmod" - if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then - echo "* Success: ${DRIVER_NAME} module found and loaded in dkms" - exit 0 - elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then - echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)" - exit 0 - else - echo "* Unable to insmod ${DRIVER_NAME} module" - fi + return + fi + + if ! hash dkms &>/dev/null; then + echo "* Skipping dkms install (dkms not found)" + return + 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 -r); 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, trying to insmod" + if insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko" > /dev/null 2>&1; then + echo "* Success: ${DRIVER_NAME} module found and loaded in dkms" + exit 0 + elif insmod "/var/lib/dkms/${DRIVER_NAME}/${DRIVER_VERSION}/${KERNEL_RELEASE}/${ARCH}/module/${DRIVER_NAME}.ko.xz" > /dev/null 2>&1; then + echo "* Success: ${DRIVER_NAME} module found and loaded in dkms (xz)" + exit 0 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}" - cat "${DKMS_LOG}" - else - echo "* Running dkms build failed, couldn't find ${DKMS_LOG}" - fi + echo "* Unable to insmod ${DRIVER_NAME} module" fi else - echo "* Skipping dkms install (dkms not found)" + 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 - fi + done } load_kernel_module_download() {