#include #include #include #include #include #include #include "pipe.h" #include "../log.h" #include "../trampoline.h" #include "../memory.h" // Setup Pipes #define PIPE_READ 0 #define PIPE_WRITE 1 static int arguments_pipe[2]; static int return_value_pipe[2]; static void safe_pipe(int *out) { int ret = pipe(out); if (ret != 0) { ERR("Unable To Create Pipe: %s", strerror(errno)); } } void init_pipe_common() { safe_pipe(arguments_pipe); safe_pipe(return_value_pipe); } // Guest void init_pipe_guest() { // Close Unneeded Pipes close(arguments_pipe[PIPE_READ]); close(return_value_pipe[PIPE_WRITE]); // Setup Environment setenv(TRAMPOLINE_ARGUMENTS_PIPE_ENV, std::to_string(arguments_pipe[PIPE_WRITE]).c_str(), true); setenv(TRAMPOLINE_RETURN_VALUE_PIPE_ENV, std::to_string(return_value_pipe[PIPE_READ]).c_str(), true); } // Host void init_pipe_host(pid_t guest_pid) { // Close Unneeded Pipes close(arguments_pipe[PIPE_WRITE]); close(return_value_pipe[PIPE_READ]); // Wait For Commands trampoline_pipe_arguments cmd = {}; while (read(arguments_pipe[PIPE_READ], &cmd, sizeof(trampoline_pipe_arguments)) > 0) { static unsigned char args[MAX_TRAMPOLINE_ARGS_SIZE]; memory_reader(cmd.args_addr, args, cmd.length); uint32_t ret = 0; if (cmd.allow_early_return && cmd.length > 0) { write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t)); } ret = trampoline(cmd.id, args); if (!cmd.allow_early_return) { write(return_value_pipe[PIPE_WRITE], &ret, sizeof(uint32_t)); } } // Reap Child int status; if (waitpid(guest_pid, &status, 0) == -1) { ERR("Unable To Reap Child: %s", strerror(errno)); } // Exit if (WIFEXITED(status)) { exit(WEXITSTATUS(status)); } else { ERR("Unable To Determine Exit Code"); } }