Loading .gitlab-ci.yml +9 −1 Original line number Diff line number Diff line Loading @@ -56,9 +56,17 @@ unit-test-job: # This job runs in the test stage. image: gekkofs/deps:0.9.4-dev needs: ['build-job'] script: - ls -ltrh ${INSTALL_PATH} - ${BUILD_PATH}/opendevnull --syscall open --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall open --reps 1 --verbose - ${BUILD_PATH}/opendevnull --syscall getpid --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpid --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpid --reps 1 --verbose --always_syscall - ${BUILD_PATH}/opendevnull --syscall kill --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall kill --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall kill --reps 1 --verbose --always_syscall - ${BUILD_PATH}/opendevnull --syscall getpriority --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpriority --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpriority --reps 1 --verbose --always_syscall artifacts: expire_in: 1 week when: always Loading CMakeLists.txt +10 −11 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) message(STATUS "[${PROJECT_NAME}] Checking for syscall_intercept") find_package(Syscall_intercept REQUIRED) # Print the include directory for debugging message(STATUS "Syscall_intercept include dir: ${Syscall_intercept_INCLUDE_DIR}") set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") Loading @@ -33,23 +35,20 @@ include_directories( ${INCLUDE_DIR} ${CMAKE_BINARY_DIR}/include /usr/include ${Syscall_intercept_INCLUDE_DIR} ) add_library(eval_intercept SHARED src/eval.cpp) add_executable(opendevnull src/opendevnull.cpp) add_library(eval_intercept SHARED) add_executable(opendevnull) target_sources(eval_intercept PRIVATE src/eval.cpp ) target_sources(opendevnull # Include path from Syscall_intercept into opendevnull target_include_directories(opendevnull PRIVATE src/opendevnull.cpp ${Syscall_intercept_INCLUDE_DIR} ) # Include path from Syscall_intercept into opendevnull target_include_directories(opendevnull target_include_directories(eval_intercept PRIVATE ${Syscall_intercept_INCLUDE_DIR} ) Loading @@ -75,6 +74,6 @@ install( install( TARGETS opendevnull LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) Readme.md +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ The project includes two main components: ### Running opendevnull ```bash ./opendevnull --syscall <open|getpid> [options] ./opendevnull --syscall <open|getpid|kill|getpriority> [options] Options: --reps N Number of repetitions (default: 100M) Loading scripts/run.sh +73 −6 Original line number Diff line number Diff line NATIVE="./opendevnull --syscall getpid" INTERC="./opendevnull --syscall getpid" SC2SC="./opendevnull --syscall getpid --always_syscall" #!/bin/bash SYSCALL="getpid" BUILD=../build REPEATS=20 ARCH="X86" NATIVE="$BUILD/opendevnull --syscall $SYSCALL" INTERC="$BUILD/opendevnull --syscall $SYSCALL" SC2SC="$BUILD/opendevnull --syscall $SYSCALL --always_syscall" # Arrays to store output values native_outputs=() interc_outputs=() sc2sc_outputs=() # Function to calculate statistics calculate_stats() { local values=("$@") local sum=0 local count=${#values[@]} local min=${values[0]} local max=${values[0]} # Calculate sum, min, and max for value in "${values[@]}"; do sum=$(echo "$sum + $value" | bc) if (( $(echo "$value < $min" | bc -l) )); then min=$value fi if (( $(echo "$value > $max" | bc -l) )); then max=$value fi done # Calculate average local avg=$(echo "scale=2; $sum / $count" | bc) # Calculate standard deviation local variance=0 for value in "${values[@]}"; do variance=$(echo "$variance + ($value - $avg)^2" | bc) done local stddev=$(echo "scale=2; sqrt($variance / $count)" | bc) echo "Average: $avg, Min: $min, Max: $max, StdDev: $stddev" } for ((i=1; i<=REPEATS; i++)) do OUTPUT=$($NATIVE | cut -f4 --delim=" ") native_outputs+=("$OUTPUT") echo "Native,$ARCH,"$OUTPUT done for ((i=1; i<=REPEATS; i++)) do OUTPUT=$(LD_PRELOAD=./libeval_intercept.so $INTERC | cut -f4 --delim=" ") OUTPUT=$(LD_PRELOAD=$BUILD/libeval_intercept.so $INTERC | cut -f4 --delim=" ") interc_outputs+=("$OUTPUT") echo "Syscall,$ARCH,"$OUTPUT done for ((i=1; i<=REPEATS; i++)) do OUTPUT=$(LD_PRELOAD=./libeval_intercept.so $SC2SC | cut -f4 --delim=" ") OUTPUT=$(LD_PRELOAD=$BUILD/libeval_intercept.so $SC2SC | cut -f4 --delim=" ") sc2sc_outputs+=("$OUTPUT") echo "Syscall2S,$ARCH,"$OUTPUT done # Calculate and print statistics echo "" echo "Statistics for NATIVE mode:" calculate_stats "${native_outputs[@]}" echo "" echo "Statistics for INTERC mode:" calculate_stats "${interc_outputs[@]}" echo "" echo "Statistics for SC2SC mode:" calculate_stats "${sc2sc_outputs[@]}" # Calculate overhead native_avg=$(echo "${native_outputs[@]}" | tr ' ' '\n' | awk '{sum+=$1} END {print sum/NR}') interc_avg=$(echo "${interc_outputs[@]}" | tr ' ' '\n' | awk '{sum+=$1} END {print sum/NR}') sc2sc_avg=$(echo "${sc2sc_outputs[@]}" | tr ' ' '\n' | awk '{sum+=$1} END {print sum/NR}') overhead_interc=$(echo "scale=2; (($interc_avg - $native_avg) / $native_avg) * 100" | bc) overhead_sc2sc=$(echo "scale=2; (($sc2sc_avg - $native_avg) / $native_avg) * 100" | bc) echo "" echo "Overhead of INTERC over NATIVE: $overhead_interc%" echo "Overhead of SC2SC over NATIVE: $overhead_sc2sc%" src/eval.cpp +74 −49 Original line number Diff line number Diff line Loading @@ -2,37 +2,63 @@ #include <libsyscall_intercept_hook_point.h> #include <sys/syscall.h> #include <sys/types.h> void start_interception() __attribute__((constructor)); void stop_interception() __attribute__((destructor)); #include <sys/resource.h> int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { void start_interception() __attribute__((constructor)); void stop_interception() __attribute__((destructor)); int hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) { return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); } int hook_getpid() { int hook_getpid() { return 42; } int hook_kill(int pid, int sig) { return 42; } int hook_getpriority(int which, id_t who) { return 42; } inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long* result) { switch(syscall_number) { #ifdef SYS_open case SYS_open: *result = hook_openat(AT_FDCWD, reinterpret_cast<char*>(arg0), static_cast<int>(arg1), static_cast<mode_t>(arg2)); static_cast<int>(arg1), static_cast<mode_t>(arg2)); break; #endif case SYS_openat: *result = hook_openat(static_cast<int>(arg0), reinterpret_cast<const char *>(arg1), *result = hook_openat( static_cast<int>(arg0), reinterpret_cast<const char*>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); break; case SYS_getpid: *result = hook_getpid(); break; case SYS_kill: *result = hook_kill(static_cast<int>(arg0), static_cast<int>(arg1)); break; case SYS_getpriority: *result = hook_getpriority(static_cast<int>(arg0), static_cast<id_t>(arg1)); break; default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in Loading @@ -44,29 +70,28 @@ inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, return 0; } int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long* syscall_return_value) { int was_hooked = 1; if (syscall_number == SYS_openat) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); else if (syscall_number == SYS_getpid) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); if (syscall_number == SYS_openat || syscall_number == SYS_getpid || syscall_number == SYS_kill || syscall_number == SYS_getpriority) { was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); } return was_hooked; } void start_interception() { void start_interception() { // Set up the callback function pointer intercept_hook_point = hook_guard_wrapper; } void stop_interception() { void stop_interception() { // Reset callback function pointer intercept_hook_point = nullptr; Loading Loading
.gitlab-ci.yml +9 −1 Original line number Diff line number Diff line Loading @@ -56,9 +56,17 @@ unit-test-job: # This job runs in the test stage. image: gekkofs/deps:0.9.4-dev needs: ['build-job'] script: - ls -ltrh ${INSTALL_PATH} - ${BUILD_PATH}/opendevnull --syscall open --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall open --reps 1 --verbose - ${BUILD_PATH}/opendevnull --syscall getpid --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpid --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpid --reps 1 --verbose --always_syscall - ${BUILD_PATH}/opendevnull --syscall kill --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall kill --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall kill --reps 1 --verbose --always_syscall - ${BUILD_PATH}/opendevnull --syscall getpriority --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpriority --reps 1 --verbose - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpriority --reps 1 --verbose --always_syscall artifacts: expire_in: 1 week when: always Loading
CMakeLists.txt +10 −11 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ${CMAKE_MODULE_PATH}) message(STATUS "[${PROJECT_NAME}] Checking for syscall_intercept") find_package(Syscall_intercept REQUIRED) # Print the include directory for debugging message(STATUS "Syscall_intercept include dir: ${Syscall_intercept_INCLUDE_DIR}") set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include") Loading @@ -33,23 +35,20 @@ include_directories( ${INCLUDE_DIR} ${CMAKE_BINARY_DIR}/include /usr/include ${Syscall_intercept_INCLUDE_DIR} ) add_library(eval_intercept SHARED src/eval.cpp) add_executable(opendevnull src/opendevnull.cpp) add_library(eval_intercept SHARED) add_executable(opendevnull) target_sources(eval_intercept PRIVATE src/eval.cpp ) target_sources(opendevnull # Include path from Syscall_intercept into opendevnull target_include_directories(opendevnull PRIVATE src/opendevnull.cpp ${Syscall_intercept_INCLUDE_DIR} ) # Include path from Syscall_intercept into opendevnull target_include_directories(opendevnull target_include_directories(eval_intercept PRIVATE ${Syscall_intercept_INCLUDE_DIR} ) Loading @@ -75,6 +74,6 @@ install( install( TARGETS opendevnull LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} )
Readme.md +1 −1 Original line number Diff line number Diff line Loading @@ -31,7 +31,7 @@ The project includes two main components: ### Running opendevnull ```bash ./opendevnull --syscall <open|getpid> [options] ./opendevnull --syscall <open|getpid|kill|getpriority> [options] Options: --reps N Number of repetitions (default: 100M) Loading
scripts/run.sh +73 −6 Original line number Diff line number Diff line NATIVE="./opendevnull --syscall getpid" INTERC="./opendevnull --syscall getpid" SC2SC="./opendevnull --syscall getpid --always_syscall" #!/bin/bash SYSCALL="getpid" BUILD=../build REPEATS=20 ARCH="X86" NATIVE="$BUILD/opendevnull --syscall $SYSCALL" INTERC="$BUILD/opendevnull --syscall $SYSCALL" SC2SC="$BUILD/opendevnull --syscall $SYSCALL --always_syscall" # Arrays to store output values native_outputs=() interc_outputs=() sc2sc_outputs=() # Function to calculate statistics calculate_stats() { local values=("$@") local sum=0 local count=${#values[@]} local min=${values[0]} local max=${values[0]} # Calculate sum, min, and max for value in "${values[@]}"; do sum=$(echo "$sum + $value" | bc) if (( $(echo "$value < $min" | bc -l) )); then min=$value fi if (( $(echo "$value > $max" | bc -l) )); then max=$value fi done # Calculate average local avg=$(echo "scale=2; $sum / $count" | bc) # Calculate standard deviation local variance=0 for value in "${values[@]}"; do variance=$(echo "$variance + ($value - $avg)^2" | bc) done local stddev=$(echo "scale=2; sqrt($variance / $count)" | bc) echo "Average: $avg, Min: $min, Max: $max, StdDev: $stddev" } for ((i=1; i<=REPEATS; i++)) do OUTPUT=$($NATIVE | cut -f4 --delim=" ") native_outputs+=("$OUTPUT") echo "Native,$ARCH,"$OUTPUT done for ((i=1; i<=REPEATS; i++)) do OUTPUT=$(LD_PRELOAD=./libeval_intercept.so $INTERC | cut -f4 --delim=" ") OUTPUT=$(LD_PRELOAD=$BUILD/libeval_intercept.so $INTERC | cut -f4 --delim=" ") interc_outputs+=("$OUTPUT") echo "Syscall,$ARCH,"$OUTPUT done for ((i=1; i<=REPEATS; i++)) do OUTPUT=$(LD_PRELOAD=./libeval_intercept.so $SC2SC | cut -f4 --delim=" ") OUTPUT=$(LD_PRELOAD=$BUILD/libeval_intercept.so $SC2SC | cut -f4 --delim=" ") sc2sc_outputs+=("$OUTPUT") echo "Syscall2S,$ARCH,"$OUTPUT done # Calculate and print statistics echo "" echo "Statistics for NATIVE mode:" calculate_stats "${native_outputs[@]}" echo "" echo "Statistics for INTERC mode:" calculate_stats "${interc_outputs[@]}" echo "" echo "Statistics for SC2SC mode:" calculate_stats "${sc2sc_outputs[@]}" # Calculate overhead native_avg=$(echo "${native_outputs[@]}" | tr ' ' '\n' | awk '{sum+=$1} END {print sum/NR}') interc_avg=$(echo "${interc_outputs[@]}" | tr ' ' '\n' | awk '{sum+=$1} END {print sum/NR}') sc2sc_avg=$(echo "${sc2sc_outputs[@]}" | tr ' ' '\n' | awk '{sum+=$1} END {print sum/NR}') overhead_interc=$(echo "scale=2; (($interc_avg - $native_avg) / $native_avg) * 100" | bc) overhead_sc2sc=$(echo "scale=2; (($sc2sc_avg - $native_avg) / $native_avg) * 100" | bc) echo "" echo "Overhead of INTERC over NATIVE: $overhead_interc%" echo "Overhead of SC2SC over NATIVE: $overhead_sc2sc%"
src/eval.cpp +74 −49 Original line number Diff line number Diff line Loading @@ -2,37 +2,63 @@ #include <libsyscall_intercept_hook_point.h> #include <sys/syscall.h> #include <sys/types.h> void start_interception() __attribute__((constructor)); void stop_interception() __attribute__((destructor)); #include <sys/resource.h> int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { void start_interception() __attribute__((constructor)); void stop_interception() __attribute__((destructor)); int hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) { return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); } int hook_getpid() { int hook_getpid() { return 42; } int hook_kill(int pid, int sig) { return 42; } int hook_getpriority(int which, id_t who) { return 42; } inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long* result) { switch(syscall_number) { #ifdef SYS_open case SYS_open: *result = hook_openat(AT_FDCWD, reinterpret_cast<char*>(arg0), static_cast<int>(arg1), static_cast<mode_t>(arg2)); static_cast<int>(arg1), static_cast<mode_t>(arg2)); break; #endif case SYS_openat: *result = hook_openat(static_cast<int>(arg0), reinterpret_cast<const char *>(arg1), *result = hook_openat( static_cast<int>(arg0), reinterpret_cast<const char*>(arg1), static_cast<int>(arg2), static_cast<mode_t>(arg3)); break; case SYS_getpid: *result = hook_getpid(); break; case SYS_kill: *result = hook_kill(static_cast<int>(arg0), static_cast<int>(arg1)); break; case SYS_getpriority: *result = hook_getpriority(static_cast<int>(arg0), static_cast<id_t>(arg1)); break; default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in Loading @@ -44,29 +70,28 @@ inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, return 0; } int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long* syscall_return_value) { int was_hooked = 1; if (syscall_number == SYS_openat) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); else if (syscall_number == SYS_getpid) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); if (syscall_number == SYS_openat || syscall_number == SYS_getpid || syscall_number == SYS_kill || syscall_number == SYS_getpriority) { was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); } return was_hooked; } void start_interception() { void start_interception() { // Set up the callback function pointer intercept_hook_point = hook_guard_wrapper; } void stop_interception() { void stop_interception() { // Reset callback function pointer intercept_hook_point = nullptr; Loading