| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- #include <sys/ptrace.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/reg.h>
- #include <sys/uio.h>
- #include <strings.h>
- #include <string.h>
- #include <elf.h>
- #include "sandbox.h"
- static inline void get_args(struct s_sandboxenv *env)
- {
- }
- int waitForSyscall(const int pid, int _status)
- {
- int status;
- static int current_status = SANDBOX_SYS_EXIT;
- if (current_status == _status || (_status != SANDBOX_SYS_ENTER && _status != SANDBOX_SYS_EXIT))
- return 0;
- ptrace(PTRACE_SYSCALL, pid, NULL, 0);
- current_status = _status;
- if (waitpid(pid, &status, 0) == -1)
- return -1;
- return 0;
- }
- int manageSyscall(struct s_sandboxenv *env)
- {
- t_syscall_fnc ovr_fnc;
- if (env->syscall_no.syscall_no >= NR_syscalls ||
- !(ovr_fnc = env->functions[env->syscall_no.syscall_no]))
- {
- /* Unrecognized syscall */
- return 0;
- }
- return (ovr_fnc)(env);
- }
- void read_registers(struct s_sandboxenv *env)
- {
- struct iovec iov = { &(env->registers), sizeof(env->registers) };
- ptrace(PTRACE_GETREGSET, env->child_pid, NT_PRSTATUS, &iov);
- #ifdef __x86_64__
- env->syscall_no.syscall_no = (unsigned int) env->registers.orig_rax;
- env->syscall_no.syscall_return = (unsigned int) env->registers.rax;
- REGISTER_TYPE result[] = { env->registers.rdi, env->registers.rsi,
- env->registers.rdx, env->registers.r10,
- env->registers.r8, env->registers.r9 };
- #else
- env->syscall_no.syscall_no = (unsigned int) env->registers.orig_eax;
- env->syscall_no.syscall_return = (unsigned int) env->registers.eax;
- REGISTER_TYPE result[] = { env->registers.ebx, env->registers.ecx,
- env->registers.edx, env->registers.esi,
- env->registers.edi, env->registers.ebp };
- #endif
- memcpy(env->syscall_args, result, sizeof(REGISTER_TYPE) * 6);
- }
- void doTrace(int pid, const t_param *params)
- {
- int status;
- struct s_sandboxenv sandbox_env;
- ptrace(PTRACE_ATTACH, pid, 0, 0);
- kill(pid, SIGTRAP);
- waitpid(pid, &status, 0);
- sandbox_env.params = params;
- sandbox_env.child_pid = pid;
- //TODO get error output from command-line
- sandbox_env.errorOutput = stderr;
- sandbox_env.filetable = sllist_create();
- init_syscalls(&sandbox_env);
- while (1)
- {
- if (waitForSyscall(pid, SANDBOX_SYS_ENTER))
- break;
- read_registers(&sandbox_env);
- if (manageSyscall(&sandbox_env))
- ptrace(PTRACE_SETREGS, pid, 0, &(sandbox_env.registers));
- if (waitForSyscall(pid, SANDBOX_SYS_EXIT))
- break;
- }
- prompt_sandbox(&sandbox_env);
- sllist_destroy(sandbox_env.filetable);
- }
- int launch_program(const t_param *params)
- {
- int child = fork();
- if (child == -1)
- return -1;
- else if (child == 0)
- doExec(getpid(), params);
- else
- doTrace(child, params);
- return 0;
- }
|