]> mj.ucw.cz Git - eval.git/blobdiff - src/box.c
The first bits of the contest GUI.
[eval.git] / src / box.c
index 3dc4a199b0930908d38dde0cc4cac6280ae1e00a..095c8843ebdbe11d8b2342e45ab557339f1ab9d7 100644 (file)
--- a/src/box.c
+++ b/src/box.c
@@ -1,7 +1,7 @@
 /*
  *     A Simple Testing Sandbox
  *
 /*
  *     A Simple Testing Sandbox
  *
- *     (c) 2001 Martin Mares <mj@ucw.cz>
+ *     (c) 2001--2004 Martin Mares <mj@ucw.cz>
  */
 
 #define _LARGEFILE64_SOURCE
  */
 
 #define _LARGEFILE64_SOURCE
@@ -37,6 +37,7 @@ static int verbose;
 static int memory_limit;
 static int allow_times;
 static char *redir_stdin, *redir_stdout;
 static int memory_limit;
 static int allow_times;
 static char *redir_stdin, *redir_stdout;
+static char *set_cwd;
 
 static pid_t box_pid;
 static int is_ptraced;
 
 static pid_t box_pid;
 static int is_ptraced;
@@ -140,13 +141,15 @@ valid_filename(unsigned long addr)
     {
       if ((!strncmp(namebuf, "/etc/", 5) ||
           !strncmp(namebuf, "/lib/", 5) ||
     {
       if ((!strncmp(namebuf, "/etc/", 5) ||
           !strncmp(namebuf, "/lib/", 5) ||
-          !strncmp(namebuf, "/usr/lib/", 9))
+          !strncmp(namebuf, "/usr/lib/", 9) ||
+          !strncmp(namebuf, "/opt/lib/", 9))
          && !strstr(namebuf, ".."))
        return;
       if (!strcmp(namebuf, "/dev/null") ||
          !strcmp(namebuf, "/dev/zero") ||
          !strcmp(namebuf, "/proc/meminfo") ||
          !strcmp(namebuf, "/proc/self/stat") ||
          && !strstr(namebuf, ".."))
        return;
       if (!strcmp(namebuf, "/dev/null") ||
          !strcmp(namebuf, "/dev/zero") ||
          !strcmp(namebuf, "/proc/meminfo") ||
          !strcmp(namebuf, "/proc/self/stat") ||
+         !strcmp(namebuf, "/proc/self/exe") ||                 /* Needed by FPC 2.0.x runtime */
          !strncmp(namebuf, "/usr/share/zoneinfo/", 20))
        return;
     }
          !strncmp(namebuf, "/usr/share/zoneinfo/", 20))
        return;
     }
@@ -158,98 +161,115 @@ valid_syscall(struct user *u)
 {
   switch (u->regs.orig_eax)
     {
 {
   switch (u->regs.orig_eax)
     {
-    case SYS_execve:
+    case __NR_execve:
       {
        static int exec_counter;
        return !exec_counter++;
       }
       {
        static int exec_counter;
        return !exec_counter++;
       }
-    case SYS_open:
-    case SYS_creat:
-    case SYS_unlink:
-    case SYS_oldstat:
-    case SYS_access:                   
-    case SYS_oldlstat:                 
-    case SYS_truncate:
-    case SYS_stat:
-    case SYS_lstat:
-    case SYS_truncate64:
-    case SYS_stat64:
-    case SYS_lstat64:
+    case __NR_open:
+    case __NR_creat:
+    case __NR_unlink:
+    case __NR_oldstat:
+    case __NR_access:                  
+    case __NR_oldlstat:                        
+    case __NR_truncate:
+    case __NR_stat:
+    case __NR_lstat:
+    case __NR_truncate64:
+    case __NR_stat64:
+    case __NR_lstat64:
+    case __NR_readlink:
       valid_filename(u->regs.ebx);
       return 1;
       valid_filename(u->regs.ebx);
       return 1;
-    case SYS_exit:
-    case SYS_read:
-    case SYS_write:
-    case SYS_close:
-    case SYS_lseek:
-    case SYS_getpid:
-    case SYS_getuid:
-    case SYS_oldfstat:
-    case SYS_dup:
-    case SYS_brk:
-    case SYS_getgid:
-    case SYS_geteuid:
-    case SYS_getegid:
-    case SYS_dup2:
-    case SYS_ftruncate:
-    case SYS_fstat:
-    case SYS_personality:
-    case SYS__llseek:
-    case SYS_readv:
-    case SYS_writev:
-    case SYS_getresuid:
-    case SYS_pread:
-    case SYS_pwrite:
-    case SYS_ftruncate64:
-    case SYS_fstat64:
-    case SYS_fcntl:
-    case SYS_fcntl64:
-    case SYS_mmap:
-    case SYS_munmap:
-    case SYS_ioctl:
-    case SYS_uname:
-    case 252:
+    case __NR_exit:
+    case __NR_read:
+    case __NR_write:
+    case __NR_close:
+    case __NR_lseek:
+    case __NR_getpid:
+    case __NR_getuid:
+    case __NR_oldfstat:
+    case __NR_dup:
+    case __NR_brk:
+    case __NR_getgid:
+    case __NR_geteuid:
+    case __NR_getegid:
+    case __NR_dup2:
+    case __NR_ftruncate:
+    case __NR_fstat:
+    case __NR_personality:
+    case __NR__llseek:
+    case __NR_readv:
+    case __NR_writev:
+    case __NR_getresuid:
+#ifdef __NR_pread64
+    case __NR_pread64:
+    case __NR_pwrite64:
+#else
+    case __NR_pread:
+    case __NR_pwrite:
+#endif
+    case __NR_ftruncate64:
+    case __NR_fstat64:
+    case __NR_fcntl:
+    case __NR_fcntl64:
+    case __NR_mmap:
+    case __NR_munmap:
+    case __NR_ioctl:
+    case __NR_uname:
+    case __NR_gettid:
+    case __NR_set_thread_area:
+    case __NR_get_thread_area:
+    case __NR_exit_group:
       return 1;
       return 1;
-    case SYS_time:
-    case SYS_alarm:
-    case SYS_pause:
-    case SYS_signal:
-    case SYS_fchmod:
-    case SYS_sigaction:
-    case SYS_sgetmask:
-    case SYS_ssetmask:
-    case SYS_sigsuspend:
-    case SYS_sigpending:
-    case SYS_getrlimit:
-    case SYS_getrusage:
-    case SYS_gettimeofday:
-    case SYS_select:
-    case SYS_readdir:
-    case SYS_setitimer:
-    case SYS_getitimer:
-    case SYS_sigreturn:
-    case SYS_mprotect:
-    case SYS_sigprocmask:
-    case SYS_getdents:
-    case SYS_getdents64:
-    case SYS__newselect:
-    case SYS_fdatasync:
-    case SYS_mremap:
-    case SYS_poll:
-    case SYS_getcwd:
-    case SYS_nanosleep:
-    case SYS_rt_sigreturn:
-    case SYS_rt_sigaction:
-    case SYS_rt_sigprocmask:
-    case SYS_rt_sigpending:
-    case SYS_rt_sigtimedwait:
-    case SYS_rt_sigqueueinfo:
-    case SYS_rt_sigsuspend:
-    case SYS_mmap2:
-    case SYS__sysctl:
+    case __NR_time:
+    case __NR_alarm:
+    case __NR_pause:
+    case __NR_signal:
+    case __NR_fchmod:
+    case __NR_sigaction:
+    case __NR_sgetmask:
+    case __NR_ssetmask:
+    case __NR_sigsuspend:
+    case __NR_sigpending:
+    case __NR_getrlimit:
+    case __NR_getrusage:
+    case __NR_gettimeofday:
+    case __NR_select:
+    case __NR_readdir:
+    case __NR_setitimer:
+    case __NR_getitimer:
+    case __NR_sigreturn:
+    case __NR_mprotect:
+    case __NR_sigprocmask:
+    case __NR_getdents:
+    case __NR_getdents64:
+    case __NR__newselect:
+    case __NR_fdatasync:
+    case __NR_mremap:
+    case __NR_poll:
+    case __NR_getcwd:
+    case __NR_nanosleep:
+    case __NR_rt_sigreturn:
+    case __NR_rt_sigaction:
+    case __NR_rt_sigprocmask:
+    case __NR_rt_sigpending:
+    case __NR_rt_sigtimedwait:
+    case __NR_rt_sigqueueinfo:
+    case __NR_rt_sigsuspend:
+    case __NR_mmap2:
+    case __NR__sysctl:
       return (filter_syscalls == 1);
       return (filter_syscalls == 1);
-    case SYS_times:
+    case __NR_times:
       return allow_times;
       return allow_times;
+    case __NR_kill:
+      if (u->regs.ebx == box_pid)
+       die("Commited suicide by signal %d.", (int)u->regs.ecx);
+      return 0;
+    case __NR_tgkill:
+      if (u->regs.ebx == box_pid && u->regs.ecx == box_pid)
+       die("Commited suicide by signal %d.", (int)u->regs.edx);
+      return 0;
     default:
       return 0;
     }
     default:
       return 0;
     }
@@ -430,6 +450,8 @@ box_inside(int argc, char **argv)
 
   memcpy(args, argv, argc * sizeof(char *));
   args[argc] = NULL;
 
   memcpy(args, argv, argc * sizeof(char *));
   args[argc] = NULL;
+  if (set_cwd && chdir(set_cwd))
+    die("chdir: %m");
   if (redir_stdin)
     {
       close(0);
   if (redir_stdin)
     {
       close(0);
@@ -442,8 +464,7 @@ box_inside(int argc, char **argv)
       if (open(redir_stdout, O_WRONLY | O_CREAT | O_TRUNC, 0666) != 1)
        die("open(\"%s\"): %m", redir_stdout);
     }
       if (open(redir_stdout, O_WRONLY | O_CREAT | O_TRUNC, 0666) != 1)
        die("open(\"%s\"): %m", redir_stdout);
     }
-  close(2);
-  dup(1);
+  dup2(1, 2);
   setpgrp();
   if (memory_limit)
     {
   setpgrp();
   if (memory_limit)
     {
@@ -488,7 +509,6 @@ main(int argc, char **argv)
 {
   int c;
   uid_t uid;
 {
   int c;
   uid_t uid;
-  char *cwd = NULL;
 
   while ((c = getopt(argc, argv, "a:c:efi:m:o:t:Tvw")) >= 0)
     switch (c)
 
   while ((c = getopt(argc, argv, "a:c:efi:m:o:t:Tvw")) >= 0)
     switch (c)
@@ -497,7 +517,7 @@ main(int argc, char **argv)
        file_access = atol(optarg);
        break;
       case 'c':
        file_access = atol(optarg);
        break;
       case 'c':
-       cwd = optarg;
+       set_cwd = optarg;
        break;
       case 'e':
        pass_environ = 1;
        break;
       case 'e':
        pass_environ = 1;
@@ -535,8 +555,6 @@ main(int argc, char **argv)
   uid = geteuid();
   if (setreuid(uid, uid) < 0)
     die("setreuid: %m");
   uid = geteuid();
   if (setreuid(uid, uid) < 0)
     die("setreuid: %m");
-  if (cwd && chdir(cwd))
-    die("chdir: %m");
   box_pid = fork();
   if (box_pid < 0)
     die("fork: %m");
   box_pid = fork();
   if (box_pid < 0)
     die("fork: %m");