]> mj.ucw.cz Git - eval.git/blobdiff - box/box.c
MO-P: Bugfix
[eval.git] / box / box.c
index d834ffdaaa9b7dbf0b5930569618b6cb9a6a5af8..7fe08a7398d652ecde081561d78d82b1de06dddc 100644 (file)
--- a/box/box.c
+++ b/box/box.c
@@ -7,6 +7,8 @@
 #define _LARGEFILE64_SOURCE
 #define _GNU_SOURCE
 
+#include "autoconf.h"
+
 #include <errno.h>
 #include <stdio.h>
 #include <fcntl.h>
@@ -24,6 +26,7 @@
 #include <sys/signal.h>
 #include <sys/sysinfo.h>
 #include <sys/resource.h>
+#include <sys/utsname.h>
 #include <linux/ptrace.h>
 
 #if defined(CONFIG_BOX_KERNEL_AMD64) && !defined(CONFIG_BOX_USER_AMD64)
@@ -289,7 +292,9 @@ static unsigned char syscall_action[NUM_ACTIONS] = {
     S(get_thread_area) = A_YES,
     S(set_tid_address) = A_YES,
     S(exit_group) = A_YES | A_SAMPLE_MEM,
-#ifndef CONFIG_BOX_USER_AMD64
+#ifdef CONFIG_BOX_USER_AMD64
+    S(arch_prctl) = A_YES,
+#else
     S(oldfstat) = A_YES,
     S(ftruncate64) = A_YES,
     S(_llseek) = A_YES,
@@ -420,6 +425,7 @@ static struct path_rule default_path_rules[] = {
   { "/proc/meminfo", A_YES },
   { "/proc/self/stat", A_YES },
   { "/proc/self/exe", A_YES },                 // Needed by FPC 2.0.x runtime
+  { "/proc/self/maps", A_YES },                        // Needed by glibc when it reports arena corruption
 };
 
 static struct path_rule *user_path_rules;
@@ -617,21 +623,30 @@ struct syscall_args {
   struct user user;
 };
 
+static int user_mem_fd;
+
 static int read_user_mem(arg_t addr, char *buf, int len)
 {
-  static int mem_fd;
-
-  if (!mem_fd)
+  if (!user_mem_fd)
     {
       char memname[64];
       sprintf(memname, "/proc/%d/mem", (int) box_pid);
-      mem_fd = open(memname, O_RDONLY);
-      if (mem_fd < 0)
+      user_mem_fd = open(memname, O_RDONLY);
+      if (user_mem_fd < 0)
        die("open(%s): %m", memname);
     }
-  if (lseek64(mem_fd, addr, SEEK_SET) < 0)
+  if (lseek64(user_mem_fd, addr, SEEK_SET) < 0)
     die("lseek64(mem): %m");
-  return read(mem_fd, buf, len);
+  return read(user_mem_fd, buf, len);
+}
+
+static void close_user_mem(void)
+{
+  if (user_mem_fd)
+    {
+      close(user_mem_fd);
+      user_mem_fd = 0;
+    }
 }
 
 #ifdef CONFIG_BOX_KERNEL_AMD64
@@ -718,6 +733,11 @@ set_syscall_nr(struct syscall_args *a, arg_t sys)
     die("ptrace(PTRACE_SETREGS): %m");
 }
 
+static void
+sanity_check(void)
+{
+}
+
 #else
 
 static void
@@ -741,6 +761,19 @@ set_syscall_nr(struct syscall_args *a, arg_t sys)
     die("ptrace(PTRACE_SETREGS): %m");
 }
 
+static void
+sanity_check(void)
+{
+#if !defined(CONFIG_BOX_ALLOW_INSECURE)
+  struct utsname uts;
+  if (uname(&uts) < 0)
+    die("uname() failed: %m");
+
+  if (!strcmp(uts.machine, "x86_64"))
+    die("Running 32-bit sandbox on 64-bit kernels is inherently unsafe. Please get a 64-bit version.");
+#endif
+}
+
 #endif
 
 /*** Syscall checks ***/
@@ -1085,7 +1118,10 @@ boxkeeper(void)
                    {
                      msg("[master] ");
                      if (sys == NATIVE_NR_execve)
-                       exec_seen = 1;
+                       {
+                         exec_seen = 1;
+                         close_user_mem();
+                       }
                    }
                  else if ((act = valid_syscall(&a)) >= 0)
                    {
@@ -1316,6 +1352,7 @@ main(int argc, char **argv)
   if (optind >= argc)
     usage();
 
+  sanity_check();
   uid = geteuid();
   if (setreuid(uid, uid) < 0)
     die("setreuid: %m");