]> mj.ucw.cz Git - moe.git/blobdiff - src/box.c
Log a different message when a fatal signal has been delivered before
[moe.git] / src / box.c
index b72c0595b01309efd0eaa6c5d865d48c2388f3ce..126452adbe176f9f511e38a47bef1e7f32cc1124 100644 (file)
--- a/src/box.c
+++ b/src/box.c
@@ -44,6 +44,7 @@ static int is_ptraced;
 static volatile int timer_tick;
 static struct timeval start_time;
 static int ticks_per_sec;
 static volatile int timer_tick;
 static struct timeval start_time;
 static int ticks_per_sec;
+static int exec_seen;
 
 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0
 /* glibc 2.1 or newer -> has lseek64 */
 
 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ > 0
 /* glibc 2.1 or newer -> has lseek64 */
@@ -78,7 +79,7 @@ die(char *msg, ...)
 }
 
 static void __attribute__((format(printf,1,2)))
 }
 
 static void __attribute__((format(printf,1,2)))
-log(char *msg, ...)
+msg(char *msg, ...)
 {
   va_list args;
   va_start(args, msg);
 {
   va_list args;
   va_start(args, msg);
@@ -132,7 +133,7 @@ valid_filename(unsigned long addr)
     }
   while (*p++);
 
     }
   while (*p++);
 
-  log("[%s] ", namebuf);
+  msg("[%s] ", namebuf);
   if (file_access >= 3)
     return;
   if (!strchr(namebuf, '/') && strcmp(namebuf, ".."))
   if (file_access >= 3)
     return;
   if (!strchr(namebuf, '/') && strcmp(namebuf, ".."))
@@ -161,11 +162,6 @@ valid_syscall(struct user *u)
 {
   switch (u->regs.orig_eax)
     {
 {
   switch (u->regs.orig_eax)
     {
-    case __NR_execve:
-      {
-       static int exec_counter;
-       return !exec_counter++;
-      }
     case __NR_open:
     case __NR_creat:
     case __NR_unlink:
     case __NR_open:
     case __NR_creat:
     case __NR_unlink:
@@ -264,11 +260,11 @@ valid_syscall(struct user *u)
       return allow_times;
     case __NR_kill:
       if (u->regs.ebx == box_pid)
       return allow_times;
     case __NR_kill:
       if (u->regs.ebx == box_pid)
-       die("Commited suicide by signal %d", (int)u->regs.ecx);
+       die("Committed suicide by signal %d", (int)u->regs.ecx);
       return 0;
     case __NR_tgkill:
       if (u->regs.ebx == box_pid && u->regs.ecx == box_pid)
       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);
+       die("Committed suicide by signal %d", (int)u->regs.edx);
       return 0;
     default:
       return 0;
       return 0;
     default:
       return 0;
@@ -408,7 +404,7 @@ boxkeeper(void)
       if (WIFSIGNALED(stat))
        {
          box_pid = 0;
       if (WIFSIGNALED(stat))
        {
          box_pid = 0;
-         die("Caught fatal signal %d", WTERMSIG(stat));
+         die("Caught fatal signal %d%s", WTERMSIG(stat), (syscall_count ? "" : " during startup"));
        }
       if (WIFSTOPPED(stat))
        {
        }
       if (WIFSTOPPED(stat))
        {
@@ -421,12 +417,19 @@ boxkeeper(void)
                die("ptrace(PTRACE_GETREGS): %m");
              stop_count++;
              if (!stop_count)                  /* Traceme request */
                die("ptrace(PTRACE_GETREGS): %m");
              stop_count++;
              if (!stop_count)                  /* Traceme request */
-               log(">> Traceme request caught\n");
+               msg(">> Traceme request caught\n");
              else if (stop_count & 1)          /* Syscall entry */
                {
              else if (stop_count & 1)          /* Syscall entry */
                {
-                 log(">> Syscall %3ld (%08lx,%08lx,%08lx) ", u.regs.orig_eax, u.regs.ebx, u.regs.ecx, u.regs.edx);
-                 syscall_count++;
-                 if (!valid_syscall(&u))
+                 msg(">> Syscall %3ld (%08lx,%08lx,%08lx) ", u.regs.orig_eax, u.regs.ebx, u.regs.ecx, u.regs.edx);
+                 if (!exec_seen)
+                   {
+                     msg("[master] ");
+                     if (u.regs.orig_eax == __NR_execve)
+                       exec_seen = 1;
+                   }
+                 else if (valid_syscall(&u))
+                   syscall_count++;
+                 else
                    {
                      /*
                       * Unfortunately, PTRACE_KILL kills _after_ the syscall completes,
                    {
                      /*
                       * Unfortunately, PTRACE_KILL kills _after_ the syscall completes,
@@ -441,12 +444,12 @@ boxkeeper(void)
                    }
                }
              else                                      /* Syscall return */
                    }
                }
              else                                      /* Syscall return */
-               log("= %ld\n", u.regs.eax);
+               msg("= %ld\n", u.regs.eax);
              ptrace(PTRACE_SYSCALL, box_pid, 0, 0);
            }
          else if (sig != SIGSTOP && sig != SIGXCPU && sig != SIGXFSZ)
            {
              ptrace(PTRACE_SYSCALL, box_pid, 0, 0);
            }
          else if (sig != SIGSTOP && sig != SIGXCPU && sig != SIGXFSZ)
            {
-             log(">> Signal %d\n", sig);
+             msg(">> Signal %d\n", sig);
              ptrace(PTRACE_SYSCALL, box_pid, 0, sig);
            }
          else
              ptrace(PTRACE_SYSCALL, box_pid, 0, sig);
            }
          else
@@ -462,7 +465,7 @@ box_inside(int argc, char **argv)
 {
   struct rlimit rl;
   char *args[argc+1];
 {
   struct rlimit rl;
   char *args[argc+1];
-  char *env[1] = { NULL };
+  char *env[] = { "LIBC_FATAL_STDERR_=1", NULL };
 
   memcpy(args, argv, argc * sizeof(char *));
   args[argc] = NULL;
 
   memcpy(args, argv, argc * sizeof(char *));
   args[argc] = NULL;
@@ -491,8 +494,14 @@ box_inside(int argc, char **argv)
   rl.rlim_cur = rl.rlim_max = 64;
   if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
     die("setrlimit: %m");
   rl.rlim_cur = rl.rlim_max = 64;
   if (setrlimit(RLIMIT_NOFILE, &rl) < 0)
     die("setrlimit: %m");
-  if (filter_syscalls && ptrace(PTRACE_TRACEME) < 0)
-    die("ptrace(PTRACE_TRACEME): %m");
+  if (filter_syscalls)
+    {
+      if (ptrace(PTRACE_TRACEME) < 0)
+       die("ptrace(PTRACE_TRACEME): %m");
+      /* Trick: Make sure that we are stopped until the boxkeeper wakes up. */
+      signal(SIGCHLD, SIG_IGN);
+      raise(SIGCHLD);
+    }
   execve(args[0], args, (pass_environ ? environ : env));
   die("execve(\"%s\"): %m", args[0]);
 }
   execve(args[0], args, (pass_environ ? environ : env));
   die("execve(\"%s\"): %m", args[0]);
 }