From ac18312b036f004ad5f91e3193739f8e273ffccb Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Jul 2026 19:26:45 +0530 Subject: [PATCH] kernel: Test to validates the kernel module signing and out-of-tree modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This test validates the kernel module signing and out-of-tree modules on Qualcomm platforms with Yocto builds. Sample Logs: [INFO] 2026-07-16 04:34:32 - ------------------------------------------------- [INFO] 2026-07-16 04:34:32 - ----------- Starting Kernel_Module_Signing Test ------------- [INFO] 2026-07-16 04:34:32 - --- Checking CONFIG_MODULE_SIG kernel config --- [PASS] 2026-07-16 04:34:32 - Kernel config CONFIG_MODULE_SIG is enabled [PASS] 2026-07-16 04:34:32 - CONFIG_MODULE_SIG is enabled in kernel config. [INFO] 2026-07-16 04:34:32 - CONFIG_MODULE_SIG_FORCE is enabled (unsigned modules will be rejected). [INFO] 2026-07-16 04:34:32 - --- Checking module signature via modinfo --- [INFO] 2026-07-16 04:34:33 - Inspecting module: /usr/lib/modules/6.8.0-117-generic/updates/dkms/zfs.ko [PASS] 2026-07-16 04:34:33 - Module '/usr/lib/modules/6.8.0-117-generic/updates/dkms/zfs.ko' contains a signature field — module signing is active. [INFO] 2026-07-16 04:34:33 - sig_id : PKCS#7 [INFO] 2026-07-16 04:34:33 - signer : las-colo41-d19-18 Secure Boot Module Signature key [INFO] 2026-07-16 04:34:33 - sig_hashalgo: sha512 [INFO] 2026-07-16 04:34:33 - --- Checking for out-of-tree kernel modules --- [INFO] 2026-07-16 04:34:33 - Scanning dmesg for out-of-tree module taints... [INFO] 2026-07-16 04:34:33 - Out-of-tree modules detected in dmesg: [INFO] 2026-07-16 04:34:33 - [65034.832869] tc956x_pcie_eth: loading out-of-tree module taints kernel. [INFO] 2026-07-16 04:34:33 - Scanning /sys/module/*/taint for out-of-tree flags... [INFO] 2026-07-16 04:34:40 - Out-of-tree module (taint=O): openafs [INFO] 2026-07-16 04:34:43 - Out-of-tree module (taint=O): spl [INFO] 2026-07-16 04:34:45 - Out-of-tree module (taint=O): zfs [INFO] 2026-07-16 04:34:45 - --- Locating out-of-tree .ko files outside kernel/ subdirectory --- dir: /usr/lib/modules/6.8.0-117-generic [INFO] 2026-07-16 04:34:45 - Potential out-of-tree .ko files found (outside kernel/ tree): [INFO] 2026-07-16 04:34:45 - /usr/lib/modules/6.8.0-117-generic/updates/dkms/zfs.ko [INFO] 2026-07-16 04:34:45 - /usr/lib/modules/6.8.0-117-generic/updates/dkms/spl.ko [INFO] 2026-07-16 04:34:46 - /usr/lib/modules/6.8.0-117-generic/updates/dkms/openafs.ko.zst [INFO] 2026-07-16 04:34:46 - --- Verifying signatures on out-of-tree modules --- [PASS] 2026-07-16 04:34:46 - SIGNED : /usr/lib/modules/6.8.0-117-generic/updates/dkms/zfs.ko [PASS] 2026-07-16 04:34:46 - SIGNED : /usr/lib/modules/6.8.0-117-generic/updates/dkms/spl.ko [PASS] 2026-07-16 04:34:46 - SIGNED : /usr/lib/modules/6.8.0-117-generic/updates/dkms/openafs.ko.zst [INFO] 2026-07-16 04:34:46 - --- Final Output --- [INFO] 2026-07-16 04:34:46 - CONFIG_MODULE_SIG enabled : YES [INFO] 2026-07-16 04:34:46 - In-tree module signed : YES [INFO] 2026-07-16 04:34:46 - Out-of-tree modules found : YES [PASS] 2026-07-16 04:34:46 - Kernel_Module_Signing PASSED — Module signing is active and kernel config is valid. Signed-off-by: Manjeet Pawar --- .../Kernel_Module_Sign_OOT_check.yaml | 16 ++ .../suites/Kernel/kmodule_sign_OOT/README.md | 36 ++++ Runner/suites/Kernel/kmodule_sign_OOT/run.sh | 198 ++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 Runner/suites/Kernel/kmodule_sign_OOT/Kernel_Module_Sign_OOT_check.yaml create mode 100644 Runner/suites/Kernel/kmodule_sign_OOT/README.md create mode 100755 Runner/suites/Kernel/kmodule_sign_OOT/run.sh diff --git a/Runner/suites/Kernel/kmodule_sign_OOT/Kernel_Module_Sign_OOT_check.yaml b/Runner/suites/Kernel/kmodule_sign_OOT/Kernel_Module_Sign_OOT_check.yaml new file mode 100644 index 00000000..9359032c --- /dev/null +++ b/Runner/suites/Kernel/kmodule_sign_OOT/Kernel_Module_Sign_OOT_check.yaml @@ -0,0 +1,16 @@ +metadata: + name: Kernel_Module_Sign_OOT_check + format: "Lava-Test Test Definition 1.0" + description: "This test validates the kernel module signing and out-of-tree modules on Qualcomm platforms with Yocto builds." + os: + - linux + scope: + - functional + +run: + steps: + - REPO_PATH=$PWD + - cd Runner/suites/Kernel/kmodule_sign_OOT + - ./run.sh || true + - $REPO_PATH/Runner/utils/send-to-lava.sh Kernel_Module_Sign_OOT_check.res || true + diff --git a/Runner/suites/Kernel/kmodule_sign_OOT/README.md b/Runner/suites/Kernel/kmodule_sign_OOT/README.md new file mode 100644 index 00000000..0a800d64 --- /dev/null +++ b/Runner/suites/Kernel/kmodule_sign_OOT/README.md @@ -0,0 +1,36 @@ +# kernel module signing & Out-of-tree module validation Test + +This test validates the kernel module signing and out-of-tree modules on Qualcomm platforms with Yocto builds. + +## Overview + +The test script performs these functional checks: + +1. **Kernel Configuration**: + - Validates presence of `CONFIG_MODULE_SIG` and `CONFIG_MODULE_SIG_FORCE` entries in `/proc/config.gz`. + +2. **Runtime Verification**: + - Checks kernel modules are signed or not. Also checks if there is Out-of-tree module taints the kernel and if that Out-of-tree module is signed or not. + +## How to Run + +```sh +source init_env +cd suites/Kernel/kmodule_sign_OOT +./run.sh +``` + +## Prerequisites + +- `zcat`, `grep`, `modinfo`, `dmesg`, `find` must be available +- Root access may be required for complete validation + +## Result Format + +Test result will be saved in `Kernel_Module_Sign_OOT_check.res` as: +- `Kernel_Module_Sign_Check_OOT_check PASSED` – if all validations pass +- `Kernel_Module_Sign_OOT_check FAIL` – if any check fails + +## License + +SPDX-License-Identifier: BSD-3-Clause(C) Qualcomm Technologies, Inc. and/or its subsidiaries. diff --git a/Runner/suites/Kernel/kmodule_sign_OOT/run.sh b/Runner/suites/Kernel/kmodule_sign_OOT/run.sh new file mode 100755 index 00000000..961ab212 --- /dev/null +++ b/Runner/suites/Kernel/kmodule_sign_OOT/run.sh @@ -0,0 +1,198 @@ +#!/bin/sh +# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. +# SPDX-License-Identifier: BSD-3-Clause + +# Robustly find and source init_env +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +INIT_ENV="" +SEARCH="$SCRIPT_DIR" +while [ "$SEARCH" != "/" ]; do + if [ -f "$SEARCH/init_env" ]; then + INIT_ENV="$SEARCH/init_env" + break + fi + SEARCH=$(dirname "$SEARCH") +done + +if [ -z "$INIT_ENV" ]; then + echo "[ERROR] Could not find init_env (starting at $SCRIPT_DIR)" >&2 + exit 1 +fi + +# Only source if not already loaded (idempotent) +if [ -z "$__INIT_ENV_LOADED" ]; then + # shellcheck disable=SC1090 + . "$INIT_ENV" +fi + +# Always source functestlib.sh, using $TOOLS exported by init_env +# shellcheck disable=SC1090,SC1091 +. "$TOOLS/functestlib.sh" + +TESTNAME="Kernel_Module_Sign_OOT_check" +test_path=$(find_test_case_by_name "$TESTNAME") +cd "$test_path" || exit 1 +# shellcheck disable=SC2034 +res_file="./$TESTNAME.res" + +log_info "-------------------------------------------------" +log_info "----------- Starting $TESTNAME Test -------------" + +# --------------------------------------------------------------- +# Dependency check +# --------------------------------------------------------------- +check_dependencies zcat grep modinfo dmesg find + +# --------------------------------------------------------------- +# PART 1: Check CONFIG_MODULE_SIG in /proc/config.gz +# --------------------------------------------------------------- +log_info "--- Checking CONFIG_MODULE_SIG kernel config ---" + +check_kernel_config "CONFIG_MODULE_SIG" || { + log_fail "CONFIG_MODULE_SIG is not enabled in kernel config." + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +} +log_pass "CONFIG_MODULE_SIG is enabled in kernel config." + +# Also check CONFIG_MODULE_SIG_FORCE as informational +if zcat /home/manjeet/config.gz 2>/dev/null | grep -q "^CONFIG_MODULE_SIG_FORCE=y"; then + log_info "CONFIG_MODULE_SIG_FORCE is enabled (unsigned modules will be rejected)." +else + log_info "CONFIG_MODULE_SIG_FORCE is NOT enabled (unsigned modules are permitted but may taint kernel)." +fi +# --------------------------------------------------------------- +# PART 2: Check signature field in modinfo for a kernel module +# --------------------------------------------------------------- +log_info "--- Checking module signature via modinfo ---" + +# Dynamically locate a .ko or .ko.zst to inspect (prefer an in-tree module) +KVER=$(uname -r) +MODULE_PATH="/usr/lib/modules/${KVER}" + +if [ ! -d "${MODULE_PATH}" ]; then + echo "[ERROR] Module path not found: ${MODULE_PATH}" > "$res_file" + exit 1 +fi + +TOP_MODULE=$(find "${MODULE_PATH}" -type f -name "*.ko" -exec du -k {} + \ + | sort -rn \ + | awk 'NR==1 { print $2 }') + +if [ -z "${TOP_MODULE}" ]; then + echo "[ERROR] No .ko modules found under ${MODULE_PATH}" > "$res_file" + exit 1 +fi + +log_info "Inspecting module: $TOP_MODULE" +MODINFO_OUTPUT=$(modinfo "$TOP_MODULE" 2>/dev/null) + +if echo "$MODINFO_OUTPUT" | grep -q "^signature:"; then + log_pass "Module '$TOP_MODULE' contains a signature field — module signing is active." + # Log signature metadata + SIG_ID=$(echo "$MODINFO_OUTPUT" | grep "^sig_id:" | awk '{print $2}') + SIGNER=$(echo "$MODINFO_OUTPUT" | grep "^signer:" | cut -d: -f2- | sed 's/^ //') + SIG_ALGO=$(echo "$MODINFO_OUTPUT" | grep "^sig_hashalgo:" | awk '{print $2}') + log_info " sig_id : ${SIG_ID:-N/A}" + log_info " signer : ${SIGNER:-N/A}" + log_info " sig_hashalgo: ${SIG_ALGO:-N/A}" + SIGNING_ACTIVE=1 +else + log_info "Module '$TOP_MODULE' does NOT contain a signature field." + log_info "modinfo output:" + echo "$MODINFO_OUTPUT" | while IFS= read -r line; do log_info " $line"; done + SIGNING_ACTIVE=0 +fi +# --------------------------------------------------------------- +# PART 3: Detect out-of-tree kernel modules +# --------------------------------------------------------------- +log_info "--- Checking for out-of-tree kernel modules ---" + +# Check dmesg for out-of-tree taints +log_info "Scanning dmesg for out-of-tree module taints..." +OOT_DMESG=$(dmesg 2>/dev/null | grep -i "out-of-tree") + +if [ -n "$OOT_DMESG" ]; then + log_info "Out-of-tree modules detected in dmesg:" + echo "$OOT_DMESG" | while IFS= read -r line; do log_info " $line"; done + OOT_FOUND=1 +else + log_info "No out-of-tree module taints found in dmesg." + OOT_FOUND=0 +fi + +# Check /sys/module for taint flags as a second method +log_info "Scanning /sys/module/*/taint for out-of-tree flags..." +OOT_SYSFS="" +for taint_file in /sys/module/*/taint; do + [ -f "$taint_file" ] || continue + taint_val=$(cat "$taint_file" 2>/dev/null) + # 'O' flag in taint indicates out-of-tree + if echo "$taint_val" | grep -q "O"; then + mod_name=$(echo "$taint_file" | sed 's|/sys/module/||;s|/taint||') + log_info " Out-of-tree module (taint=O): $mod_name" + OOT_SYSFS="$OOT_SYSFS $mod_name" + OOT_FOUND=1 + fi +done + +if [ -z "$OOT_SYSFS" ]; then + log_info "No out-of-tree taint flags found in /sys/module/*/taint." +fi + +# --------------------------------------------------------------- +# PART 4: Locate out-of-tree .ko files under /usr/lib/modules +# --------------------------------------------------------------- +log_info "--- Locating out-of-tree .ko files outside kernel/ subdirectory ---" + +# Modules under /usr/lib/modules// but NOT under kernel/ are typically out-of-tree +OOT_FILES=$(find "/usr/lib/modules/${KVER}/" \ + -name "*.ko" -o -name "*.ko.zst" 2>/dev/null \ + | grep -v "/kernel/" 2>/dev/null) + +if [ -n "$OOT_FILES" ]; then + log_info "Potential out-of-tree .ko files found (outside kernel/ tree):" + echo "$OOT_FILES" | while IFS= read -r f; do log_info " $f"; done + OOT_FOUND=1 +else + log_info "No out-of-tree .ko files detected outside /kernel/ subdirectory." +fi + +# --------------------------------------------------------------- +# PART 5: For each detected out-of-tree module, check if signed +# --------------------------------------------------------------- +log_info "--- Verifying signatures on out-of-tree modules ---" + +UNSIGNED_OOT=0 + +if [ -n "$OOT_FILES" ]; then + echo "$OOT_FILES" | while IFS= read -r oot_mod; do + OOT_INFO=$(modinfo "$oot_mod" 2>/dev/null) + if echo "$OOT_INFO" | grep -q "^signature:"; then + log_pass " SIGNED : $oot_mod" + else + log_info " UNSIGNED : $oot_mod (no signature field in modinfo)" + UNSIGNED_OOT=1 + fi + done +else + log_info "No out-of-tree module files to check for signatures." +fi + +# --------------------------------------------------------------- +# Final Verdict +# --------------------------------------------------------------- +log_info "--- Final Output ---" +log_info "CONFIG_MODULE_SIG enabled : YES" +log_info "In-tree module signed : $([ "$SIGNING_ACTIVE" -eq 1 ] && echo YES || echo NO)" +log_info "Out-of-tree modules found : $([ "$OOT_FOUND" -eq 1 ] && echo YES || echo NO)" + +if [ "$SIGNING_ACTIVE" -eq 1 ]; then + log_pass "$TESTNAME PASSED — Module signing is active and kernel config is valid." + echo "$TESTNAME PASS" > "$res_file" + exit 0 +else + log_fail "$TESTNAME FAILED — Module signing is NOT active on inspected module(s)." + echo "$TESTNAME FAIL" > "$res_file" + exit 1 +fi