From 54b79db457fcd69323e83f784d7150e064ac8a1a Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Sat, 8 Jun 2024 04:46:07 -0400 Subject: [PATCH] Remove PTrace --- CMakeLists.txt | 2 + include/trampoline/types.h | 5 +- native/CMakeLists.txt | 6 +- native/src/main.cpp | 22 ++----- native/src/{pipe => }/pipe.cpp | 6 +- native/src/{pipe => }/pipe.h | 0 native/src/ptrace/init.cpp | 46 ------------- native/src/ptrace/loop.cpp | 116 --------------------------------- native/src/ptrace/ptrace.h | 10 --- native/src/signals.cpp | 4 -- qemu/CMakeLists.txt | 2 +- 11 files changed, 16 insertions(+), 203 deletions(-) rename native/src/{pipe => }/pipe.cpp (96%) rename native/src/{pipe => }/pipe.h (100%) delete mode 100644 native/src/ptrace/init.cpp delete mode 100644 native/src/ptrace/loop.cpp delete mode 100644 native/src/ptrace/ptrace.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5105c5c..f368f13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,8 @@ if(NOT TRAMPOLINE_HEADERS_ONLY) check_symbol_exists("__x86_64__" "" USE_QEMU_TRAMPOLINE) # Include Correct Sub-Project + set(TRAMPOLINE_RPATH "$ORIGIN/../lib/native") + set(TRAMPOLINE_EXTRA_LINK_FLAG "--disable-new-dtags") if(USE_NATIVE_TRAMPOLINE) add_subdirectory(native) target_compile_definitions(trampoline-headers INTERFACE MCPI_USE_NATIVE_TRAMPOLINE) diff --git a/include/trampoline/types.h b/include/trampoline/types.h index 55c1dad..6754d38 100644 --- a/include/trampoline/types.h +++ b/include/trampoline/types.h @@ -2,11 +2,10 @@ #include -// Switch Between Pipe/PTrace Mode -#define TRAMPOLINE_USE_PIPES_ENV "_MCPI_TRAMPOLINE_USE_PIPES" +// Maximum Arguments Length +#define MAX_TRAMPOLINE_ARGS_SIZE 2097152 // 2 MiB // System Call Constants -#define MAX_TRAMPOLINE_ARGS_SIZE 2097152 // 2 MiB #define TRAMPOLINE_SYSCALL 0x1337 // Pipe Constants diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt index 9d1a994..1756e0d 100644 --- a/native/CMakeLists.txt +++ b/native/CMakeLists.txt @@ -7,7 +7,7 @@ add_executable(trampoline src/trampoline.cpp src/ptrace/loop.cpp src/ptrace/init.cpp - src/pipe/pipe.cpp + src/pipe.cpp src/signals.cpp ) @@ -18,8 +18,8 @@ target_compile_options(trampoline PRIVATE -Wall -Wextra -Werror -Wpointer-arith target_link_libraries(trampoline dl rt trampoline-headers) # RPath -set_target_properties(trampoline PROPERTIES INSTALL_RPATH "$ORIGIN/../lib/native") -target_link_options(trampoline PRIVATE "LINKER:--disable-new-dtags") +set_target_properties(trampoline PROPERTIES INSTALL_RPATH "${TRAMPOLINE_RPATH}") +target_link_options(trampoline PRIVATE "LINKER:${TRAMPOLINE_EXTRA_LINK_FLAG}") # Install function(install_trampoline bin_dir) diff --git a/native/src/main.cpp b/native/src/main.cpp index 61d42b6..1b3d1b9 100644 --- a/native/src/main.cpp +++ b/native/src/main.cpp @@ -6,8 +6,7 @@ #include "log.h" #include "memory.h" #include "trampoline.h" -#include "ptrace/ptrace.h" -#include "pipe/pipe.h" +#include "pipe.h" #include "signals.h" // Main @@ -16,11 +15,8 @@ int main(__attribute__((unused)) int argc, char *argv[]) { if (argc < 2) { ERR("Invalid Arguments"); } - bool use_ptrace = getenv(TRAMPOLINE_USE_PIPES_ENV) == nullptr; // Setup - if (!use_ptrace) { - init_pipe_common(); - } + init_pipe_common(); // Fork pid_t pid = fork(); if (pid == -1) { @@ -28,11 +24,7 @@ int main(__attribute__((unused)) int argc, char *argv[]) { } else if (pid == 0) { // Setup setpgid(0, 0); - if (use_ptrace) { - init_ptrace_guest(); - } else { - init_pipe_guest(); - } + init_pipe_guest(); // Execute Program execvp(argv[1], (char *const *) &argv[1]); ERR("Unable To Execute Program: %s: %s", argv[1], strerror(errno)); @@ -44,11 +36,7 @@ int main(__attribute__((unused)) int argc, char *argv[]) { init_memory(pid); init_trampoline(); - // Start PTrace - if (use_ptrace) { - init_ptrace_host(pid); - } else { - init_pipe_host(pid); - } + // Start Pipes + init_pipe_host(pid); } } \ No newline at end of file diff --git a/native/src/pipe/pipe.cpp b/native/src/pipe.cpp similarity index 96% rename from native/src/pipe/pipe.cpp rename to native/src/pipe.cpp index f348ec6..caf47a4 100644 --- a/native/src/pipe/pipe.cpp +++ b/native/src/pipe.cpp @@ -8,9 +8,9 @@ #include "pipe.h" -#include "../log.h" -#include "../trampoline.h" -#include "../memory.h" +#include "log.h" +#include "trampoline.h" +#include "memory.h" // Setup Pipes #define PIPE_READ 0 diff --git a/native/src/pipe/pipe.h b/native/src/pipe.h similarity index 100% rename from native/src/pipe/pipe.h rename to native/src/pipe.h diff --git a/native/src/ptrace/init.cpp b/native/src/ptrace/init.cpp deleted file mode 100644 index 1628fb4..0000000 --- a/native/src/ptrace/init.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - -#include "ptrace.h" -#include "../log.h" - -// Init -void init_ptrace_host(pid_t guest_pid) { - // Wait For PTrace - safe_wait(guest_pid, nullptr); - // Configure PTrace - safe_ptrace(PTRACE_SETOPTIONS, guest_pid, nullptr, (void *) (PTRACE_O_EXITKILL | PTRACE_O_TRACESECCOMP)); - // Start Loop - loop_ptrace(guest_pid); -} -void init_ptrace_guest() { - // seccomp Filter - sock_filter filter[] = { - // Load Syscall Number To Accumulator - BPF_STMT(BPF_LD + BPF_W + BPF_ABS, offsetof(seccomp_data, nr)), - // If Syscall Does Not Match The Trampoline, Then Skip The Next Instruction - BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, TRAMPOLINE_SYSCALL, 0, 1), - // Trigger PTrace And End Filter - BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_TRACE), - // Allow Syscall And End Filter - BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW) - }; - sock_fprog prog = { - .len = (unsigned short) (sizeof(filter) / sizeof(filter[0])), - .filter = filter - }; - // Setup PTrace - safe_ptrace(PTRACE_TRACEME, 0, nullptr, nullptr); - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) { - ERR("Unable To Prepare Process For Seccomp: %s", strerror(errno)); - } - if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1) { - ERR("Unable To Set Seccomp Filter: %s", strerror(errno)); - } -} \ No newline at end of file diff --git a/native/src/ptrace/loop.cpp b/native/src/ptrace/loop.cpp deleted file mode 100644 index 5c7baf6..0000000 --- a/native/src/ptrace/loop.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include - -#ifndef __aarch64__ -#error "Unsupported Host Architecture" -#endif - -#include "ptrace.h" -#include "../log.h" -#include "../trampoline.h" -#include "../memory.h" - -// Helper Functions -void safe_ptrace(__ptrace_request request, pid_t pid, void *addr, void *data) { - if (ptrace(request, pid, addr, data) == -1) { - ERR("PTrace Error: %s", strerror(errno)); - } -} -void safe_wait(pid_t guest_pid, int *status) { - int real_status; - if (waitpid(guest_pid, &real_status, 0) == -1) { - ERR("Unable To Wait For Guest"); - } - if (WIFEXITED(real_status)) { - // Process Exited - exit(WEXITSTATUS(real_status)); - } - if (status != nullptr) { - *status = real_status; - } -} -static void ptrace_wait_syscall(pid_t guest_pid) { - while (true) { - safe_ptrace(PTRACE_CONT, guest_pid, nullptr, nullptr); - int status; - safe_wait(guest_pid, &status); - if ((status >> 8) == (SIGTRAP | (PTRACE_EVENT_SECCOMP << 8))) { - return; - } - } -} - -// Registers -struct arm32_pt_regs { - uint32_t regs[18]; -}; -static bool check_syscall(pid_t guest_pid, arm32_pt_regs *out) { - // Read Registers - arm32_pt_regs regs = {}; - iovec io = { - .iov_base = ®s, - .iov_len = sizeof(regs) - }; - safe_ptrace(PTRACE_GETREGSET, guest_pid, (void *) NT_PRSTATUS, &io); - if (io.iov_len != sizeof(regs)) { - ERR("Guest Must Be 32-Bit"); - } - // Check Syscall - if (regs.regs[7] != TRAMPOLINE_SYSCALL) { - // Not Trampoline - return false; - } - // Block Syscall - int new_syscall = -1; - iovec syscall_io = { - .iov_base = &new_syscall, - .iov_len = sizeof(int), - }; - safe_ptrace(PTRACE_SETREGSET, guest_pid, (void *) NT_ARM_SYSTEM_CALL, &syscall_io); - // Export Registers - *out = regs; - // Return - return true; -} -static void get_arguments(arm32_pt_regs *regs, uint32_t *arg1, uint32_t *arg2, uint32_t *arg3) { - *arg1 = regs->regs[0]; - *arg2 = regs->regs[1]; - *arg3 = regs->regs[2]; -} -static void set_syscall_return(pid_t guest_pid, arm32_pt_regs *regs) { - regs->regs[0] = 0; - iovec io = { - .iov_base = regs, - .iov_len = sizeof(arm32_pt_regs) - }; - safe_ptrace(PTRACE_SETREGSET, guest_pid, (void *) NT_PRSTATUS, &io); -} - -// Main Loop -void loop_ptrace(pid_t guest_pid) { - while (true) { - // Wait For Syscall - ptrace_wait_syscall(guest_pid); - - // Handle Syscall - arm32_pt_regs regs = {}; - bool is_trampoline = check_syscall(guest_pid, ®s); - if (is_trampoline) { - // Get Arguments - uint32_t id; - uint32_t length; - uint32_t args_addr; - get_arguments(®s, &id, &length, &args_addr); - unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE]; - memory_reader(args_addr, args, length); - // Run Trampoline - const uint32_t ret = trampoline(id, args); - memory_writer(args_addr, &ret, sizeof(uint32_t)); - // Set Syscall Return - set_syscall_return(guest_pid, ®s); - } - } -} \ No newline at end of file diff --git a/native/src/ptrace/ptrace.h b/native/src/ptrace/ptrace.h deleted file mode 100644 index 7163896..0000000 --- a/native/src/ptrace/ptrace.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -void safe_ptrace(__ptrace_request request, pid_t pid, void *addr, void *data); -void safe_wait(pid_t guest_pid, int *status); -void init_ptrace_host(pid_t guest_pid); -void init_ptrace_guest(); -void loop_ptrace(pid_t guest_pid); \ No newline at end of file diff --git a/native/src/signals.cpp b/native/src/signals.cpp index 1a7b508..9569aa0 100644 --- a/native/src/signals.cpp +++ b/native/src/signals.cpp @@ -2,10 +2,6 @@ #include "signals.h" -#include -#include -#include - // Signal Handlers static pid_t guest_pid = -1; static void exit_handler(__attribute__((unused)) int signal_id) { diff --git a/qemu/CMakeLists.txt b/qemu/CMakeLists.txt index 468a5c1..3ec551c 100644 --- a/qemu/CMakeLists.txt +++ b/qemu/CMakeLists.txt @@ -36,7 +36,7 @@ ExternalProject_Add(qemu "--cross-prefix=" "--cc=${CMAKE_C_COMPILER}" "--cxx=${CMAKE_CXX_COMPILER}" - "--extra-ldflags=-ldl -Wl,-rpath=$ORIGIN/../lib/native -Wl,--disable-new-dtags" + "--extra-ldflags=-ldl -Wl,-rpath=${TRAMPOLINE_RPATH} -Wl,${TRAMPOLINE_EXTRA_LINK_FLAG}" "--disable-debug-info" "--target-list=arm-linux-user" "--without-default-features"