]> mj.ucw.cz Git - eval.git/blobdiff - src/box.c
Minor changes from Prerov.
[eval.git] / src / box.c
index cd5b8c4ac0c8df4b52ddb23a319bb236e753d095..3dc4a199b0930908d38dde0cc4cac6280ae1e00a 100644 (file)
--- a/src/box.c
+++ b/src/box.c
@@ -15,6 +15,7 @@
 #include <stdarg.h>
 #include <unistd.h>
 #include <getopt.h>
 #include <stdarg.h>
 #include <unistd.h>
 #include <getopt.h>
+#include <time.h>
 #include <sys/wait.h>
 #include <sys/user.h>
 #include <sys/time.h>
 #include <sys/wait.h>
 #include <sys/user.h>
 #include <sys/time.h>
@@ -34,6 +35,8 @@ static int use_wall_clock;
 static int file_access;
 static int verbose;
 static int memory_limit;
 static int file_access;
 static int verbose;
 static int memory_limit;
+static int allow_times;
+static char *redir_stdin, *redir_stdout;
 
 static pid_t box_pid;
 static int is_ptraced;
 
 static pid_t box_pid;
 static int is_ptraced;
@@ -141,7 +144,10 @@ valid_filename(unsigned long addr)
          && !strstr(namebuf, ".."))
        return;
       if (!strcmp(namebuf, "/dev/null") ||
          && !strstr(namebuf, ".."))
        return;
       if (!strcmp(namebuf, "/dev/null") ||
-         !strcmp(namebuf, "/dev/zero"))
+         !strcmp(namebuf, "/dev/zero") ||
+         !strcmp(namebuf, "/proc/meminfo") ||
+         !strcmp(namebuf, "/proc/self/stat") ||
+         !strncmp(namebuf, "/usr/share/zoneinfo/", 20))
        return;
     }
   die("Forbidden access to file `%s'.", namebuf);
        return;
     }
   die("Forbidden access to file `%s'.", namebuf);
@@ -197,9 +203,12 @@ valid_syscall(struct user *u)
     case SYS_ftruncate64:
     case SYS_fstat64:
     case SYS_fcntl:
     case SYS_ftruncate64:
     case SYS_fstat64:
     case SYS_fcntl:
+    case SYS_fcntl64:
     case SYS_mmap:
     case SYS_munmap:
     case SYS_ioctl:
     case SYS_mmap:
     case SYS_munmap:
     case SYS_ioctl:
+    case SYS_uname:
+    case 252:
       return 1;
     case SYS_time:
     case SYS_alarm:
       return 1;
     case SYS_time:
     case SYS_alarm:
@@ -222,6 +231,7 @@ valid_syscall(struct user *u)
     case SYS_mprotect:
     case SYS_sigprocmask:
     case SYS_getdents:
     case SYS_mprotect:
     case SYS_sigprocmask:
     case SYS_getdents:
+    case SYS_getdents64:
     case SYS__newselect:
     case SYS_fdatasync:
     case SYS_mremap:
     case SYS__newselect:
     case SYS_fdatasync:
     case SYS_mremap:
@@ -236,7 +246,10 @@ valid_syscall(struct user *u)
     case SYS_rt_sigqueueinfo:
     case SYS_rt_sigsuspend:
     case SYS_mmap2:
     case SYS_rt_sigqueueinfo:
     case SYS_rt_sigsuspend:
     case SYS_mmap2:
+    case SYS__sysctl:
       return (filter_syscalls == 1);
       return (filter_syscalls == 1);
+    case SYS_times:
+      return allow_times;
     default:
       return 0;
     }
     default:
       return 0;
     }
@@ -352,7 +365,7 @@ boxkeeper(void)
          timeradd(&rus.ru_utime, &rus.ru_stime, &total);
          wall = time(NULL) - start_time;
          if ((use_wall_clock ? wall : total.tv_sec) > timeout)
          timeradd(&rus.ru_utime, &rus.ru_stime, &total);
          wall = time(NULL) - start_time;
          if ((use_wall_clock ? wall : total.tv_sec) > timeout)
-           die("Timeout exceeded (after exit).");
+           die("Time limit exceeded (after exit).");
          fprintf(stderr, "OK (%d sec real, %d sec wall, %d syscalls)\n", (int) total.tv_sec, wall, syscall_count);
          exit(0);
        }
          fprintf(stderr, "OK (%d sec real, %d sec wall, %d syscalls)\n", (int) total.tv_sec, wall, syscall_count);
          exit(0);
        }
@@ -417,6 +430,18 @@ 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 (redir_stdin)
+    {
+      close(0);
+      if (open(redir_stdin, O_RDONLY) != 0)
+       die("open(\"%s\"): %m", redir_stdin);
+    }
+  if (redir_stdout)
+    {
+      close(1);
+      if (open(redir_stdout, O_WRONLY | O_CREAT | O_TRUNC, 0666) != 1)
+       die("open(\"%s\"): %m", redir_stdout);
+    }
   close(2);
   dup(1);
   setpgrp();
   close(2);
   dup(1);
   setpgrp();
@@ -444,10 +469,14 @@ Usage: box [<options>] -- <command> <arguments>\n\
 \n\
 Options:\n\
 -a <level>\tSet file access level (0=none, 1=cwd, 2=/etc,/lib,..., 3=whole fs, 9=no checks; needs -f)\n\
 \n\
 Options:\n\
 -a <level>\tSet file access level (0=none, 1=cwd, 2=/etc,/lib,..., 3=whole fs, 9=no checks; needs -f)\n\
+-c <dir>\tChange directory to <dir> first\n\
 -e\t\tPass full environment of parent process\n\
 -f\t\tFilter system calls (-ff=very restricted)\n\
 -e\t\tPass full environment of parent process\n\
 -f\t\tFilter system calls (-ff=very restricted)\n\
+-i <file>\tRedirect stdin from <file>\n\
 -m <size>\tLimit address space to <size> KB\n\
 -m <size>\tLimit address space to <size> KB\n\
+-o <file>\tRedirect stdout to <file>\n\
 -t <time>\tStop after <time> seconds\n\
 -t <time>\tStop after <time> seconds\n\
+-T\t\tAllow syscalls for measuring run time\n\
 -v\t\tBe verbose\n\
 -w\t\tMeasure wall clock time instead of run time\n\
 ");
 -v\t\tBe verbose\n\
 -w\t\tMeasure wall clock time instead of run time\n\
 ");
@@ -459,25 +488,38 @@ main(int argc, char **argv)
 {
   int c;
   uid_t uid;
 {
   int c;
   uid_t uid;
+  char *cwd = NULL;
 
 
-  while ((c = getopt(argc, argv, "a:efm:t:vw")) >= 0)
+  while ((c = getopt(argc, argv, "a:c:efi:m:o:t:Tvw")) >= 0)
     switch (c)
       {
       case 'a':
        file_access = atol(optarg);
        break;
     switch (c)
       {
       case 'a':
        file_access = atol(optarg);
        break;
+      case 'c':
+       cwd = optarg;
+       break;
       case 'e':
        pass_environ = 1;
        break;
       case 'f':
        filter_syscalls++;
        break;
       case 'e':
        pass_environ = 1;
        break;
       case 'f':
        filter_syscalls++;
        break;
+      case 'i':
+       redir_stdin = optarg;
+       break;
       case 'm':
        memory_limit = atol(optarg);
        break;
       case 'm':
        memory_limit = atol(optarg);
        break;
+      case 'o':
+       redir_stdout = optarg;
+       break;
       case 't':
        timeout = atol(optarg);
        break;
       case 't':
        timeout = atol(optarg);
        break;
+      case 'T':
+       allow_times++;
+       break;
       case 'v':
        verbose++;
        break;
       case 'v':
        verbose++;
        break;
@@ -493,6 +535,8 @@ 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");