sandbox.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. #include <sys/ptrace.h>
  2. #include <sys/types.h>
  3. #include <sys/wait.h>
  4. #include <sys/reg.h>
  5. #include <sys/uio.h>
  6. #include <strings.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <elf.h>
  10. #include "sandbox.h"
  11. /* DEBUG HEADER */
  12. #include <stdio.h>
  13. static inline void get_args(struct s_sandboxenv *env)
  14. {
  15. #ifdef __x86_64__
  16. REGISTER_TYPE result[] = { env->registers.rdi, env->registers.rsi,
  17. env->registers.rdx, env->registers.r10,
  18. env->registers.r8, env->registers.r9 };
  19. #else
  20. REGISTER_TYPE result[] = { env->registers.ebx, env->registers.ecx,
  21. env->registers.edx, env->registers.esi,
  22. env->registers.edi, env->registers.ebp };
  23. #endif
  24. memcpy(env->syscall_args, result, sizeof(REGISTER_TYPE) * 6);
  25. }
  26. static inline void init_syscalls(struct s_sandboxenv *env)
  27. {
  28. bzero(env->functions, sizeof(*(env->functions)) * NR_syscalls);
  29. env->functions[__NR_write] = ovr_write;
  30. env->functions[__NR_open] = ovr_open;
  31. env->functions[__NR_close] = ovr_close;
  32. }
  33. static inline int waitForSyscall(const int pid)
  34. {
  35. int status;
  36. ptrace(PTRACE_SYSCALL, pid, NULL, 0);
  37. if (waitpid(pid, &status, 0) == -1)
  38. return -1;
  39. return 0;
  40. }
  41. int manageSyscall(struct s_sandboxenv *env)
  42. {
  43. t_syscall_fnc ovr_fnc;
  44. int syscall_nr;
  45. #ifdef __x86_64__
  46. syscall_nr = env->registers.orig_rax;
  47. #else
  48. syscall_nr = env->registers.orig_eax;
  49. #endif
  50. if (env->registers.orig_rax >= NR_syscalls ||
  51. !(ovr_fnc = env->functions[(int) env->registers.orig_rax]))
  52. return 0;
  53. get_args(env);
  54. (ovr_fnc)(env);
  55. return 1;
  56. }
  57. void doTrace(int pid, const t_param *params)
  58. {
  59. int status;
  60. struct s_sandboxenv sandbox_env;
  61. struct iovec iov = { &(sandbox_env.registers), sizeof(sandbox_env.registers) };
  62. ptrace(PTRACE_ATTACH, pid, 0, 0);
  63. kill(pid, SIGTRAP);
  64. waitpid(pid, &status, 0);
  65. sandbox_env.params = params;
  66. sandbox_env.child_pid = pid;
  67. init_syscalls(&sandbox_env);
  68. while (1)
  69. {
  70. if (waitForSyscall(pid))
  71. break;
  72. ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
  73. if (manageSyscall(&sandbox_env))
  74. ptrace(PTRACE_SETREGS, pid, 0, &(sandbox_env.registers));
  75. if (waitForSyscall(pid))
  76. break;
  77. iov.iov_len = sizeof(sandbox_env.registers);
  78. ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
  79. manageSyscall(&sandbox_env);
  80. }
  81. }
  82. int launch_program(const t_param *params)
  83. {
  84. int child = fork();
  85. if (child == -1)
  86. return -1;
  87. else if (child == 0)
  88. doExec(getpid(), params);
  89. else
  90. doTrace(child, params);
  91. return 0;
  92. }