Browse Source

Bugfixes:
- Printing unsupported system calls to stdout (when DEBUG=1)
- Implementing ioctl code FIONCLEX and FIOCLEX
- Rewriting nested functions in libsysdb. GCC 5 causes segmentation fault when passing
nested functions as callbacks.
- Fixing Bash manifest template

Chia-Che Tsai 7 years ago
parent
commit
e2e01667c2

+ 173 - 2
LibOS/glibc-2.19.patch

@@ -563,7 +563,7 @@ index 0ae0b7f..f883910 100644
  static int
  check_loaded_objects (const char **loaded)
 diff --git a/elf/rtld.c b/elf/rtld.c
-index 6dcbabc..431120a 100644
+index 6dcbabc..82cfb7d 100644
 --- a/elf/rtld.c
 +++ b/elf/rtld.c
 @@ -356,6 +356,23 @@ _dl_start_final (void *arg, struct dl_start_final_info *info)
@@ -664,7 +664,149 @@ index 6dcbabc..431120a 100644
    LIBC_PROBE (init_start, 2, LM_ID_BASE, r);
  
    /* Auditing checkpoint: we are ready to signal that the initial map
-@@ -2301,7 +2350,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+@@ -1605,140 +1654,11 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
+ 	}
+     }
+ 
+-  /* We have two ways to specify objects to preload: via environment
+-     variable and via the file /etc/ld.so.preload.  The latter can also
+-     be used when security is enabled.  */
+-  assert (*first_preload == NULL);
+-  struct link_map **preloads = NULL;
+-  unsigned int npreloads = 0;
+-
+-  if (__builtin_expect (preloadlist != NULL, 0))
+-    {
+-      /* The LD_PRELOAD environment variable gives list of libraries
+-	 separated by white space or colons that are loaded before the
+-	 executable's dependencies and prepended to the global scope
+-	 list.  If the binary is running setuid all elements
+-	 containing a '/' are ignored since it is insecure.  */
+-      char *list = strdupa (preloadlist);
+-      char *p;
+-
+-      HP_TIMING_NOW (start);
+-
+-      /* Prevent optimizing strsep.  Speed is not important here.  */
+-      while ((p = (strsep) (&list, " :")) != NULL)
+-	if (p[0] != '\0'
+-	    && (__builtin_expect (! INTUSE(__libc_enable_secure), 1)
+-		|| strchr (p, '/') == NULL))
+-	  npreloads += do_preload (p, main_map, "LD_PRELOAD");
+-
+-      HP_TIMING_NOW (stop);
+-      HP_TIMING_DIFF (diff, start, stop);
+-      HP_TIMING_ACCUM_NT (load_time, diff);
+-    }
+-
+-  /* There usually is no ld.so.preload file, it should only be used
+-     for emergencies and testing.  So the open call etc should usually
+-     fail.  Using access() on a non-existing file is faster than using
+-     open().  So we do this first.  If it succeeds we do almost twice
+-     the work but this does not matter, since it is not for production
+-     use.  */
+-  static const char preload_file[] = "/etc/ld.so.preload";
+-  if (__builtin_expect (__access (preload_file, R_OK) == 0, 0))
+-    {
+-      /* Read the contents of the file.  */
+-      file = _dl_sysdep_read_whole_file (preload_file, &file_size,
+-					 PROT_READ | PROT_WRITE);
+-      if (__builtin_expect (file != MAP_FAILED, 0))
+-	{
+-	  /* Parse the file.  It contains names of libraries to be loaded,
+-	     separated by white spaces or `:'.  It may also contain
+-	     comments introduced by `#'.  */
+-	  char *problem;
+-	  char *runp;
+-	  size_t rest;
+-
+-	  /* Eliminate comments.  */
+-	  runp = file;
+-	  rest = file_size;
+-	  while (rest > 0)
+-	    {
+-	      char *comment = memchr (runp, '#', rest);
+-	      if (comment == NULL)
+-		break;
+-
+-	      rest -= comment - runp;
+-	      do
+-		*comment = ' ';
+-	      while (--rest > 0 && *++comment != '\n');
+-	    }
+-
+-	  /* We have one problematic case: if we have a name at the end of
+-	     the file without a trailing terminating characters, we cannot
+-	     place the \0.  Handle the case separately.  */
+-	  if (file[file_size - 1] != ' ' && file[file_size - 1] != '\t'
+-	      && file[file_size - 1] != '\n' && file[file_size - 1] != ':')
+-	    {
+-	      problem = &file[file_size];
+-	      while (problem > file && problem[-1] != ' '
+-		     && problem[-1] != '\t'
+-		     && problem[-1] != '\n' && problem[-1] != ':')
+-		--problem;
+-
+-	      if (problem > file)
+-		problem[-1] = '\0';
+-	    }
+-	  else
+-	    {
+-	      problem = NULL;
+-	      file[file_size - 1] = '\0';
+-	    }
+-
+-	  HP_TIMING_NOW (start);
+-
+-	  if (file != problem)
+-	    {
+-	      char *p;
+-	      runp = file;
+-	      while ((p = strsep (&runp, ": \t\n")) != NULL)
+-		if (p[0] != '\0')
+-		  npreloads += do_preload (p, main_map, preload_file);
+-	    }
+-
+-	  if (problem != NULL)
+-	    {
+-	      char *p = strndupa (problem, file_size - (problem - file));
+-
+-	      npreloads += do_preload (p, main_map, preload_file);
+-	    }
+-
+-	  HP_TIMING_NOW (stop);
+-	  HP_TIMING_DIFF (diff, start, stop);
+-	  HP_TIMING_ACCUM_NT (load_time, diff);
+-
+-	  /* We don't need the file anymore.  */
+-	  __munmap (file, file_size);
+-	}
+-    }
+-
+-  if (__builtin_expect (*first_preload != NULL, 0))
+-    {
+-      /* Set up PRELOADS with a vector of the preloaded libraries.  */
+-      struct link_map *l = *first_preload;
+-      preloads = __alloca (npreloads * sizeof preloads[0]);
+-      i = 0;
+-      do
+-	{
+-	  preloads[i++] = l;
+-	  l = l->l_next;
+-	} while (l);
+-      assert (i == npreloads);
+-    }
+-
+   /* Load all the libraries specified by DT_NEEDED entries.  If LD_PRELOAD
+      specified some libraries to load, these are inserted before the actual
+      dependencies in the executable's searchlist for symbol resolution.  */
+   HP_TIMING_NOW (start);
+-  _dl_map_object_deps (main_map, preloads, npreloads, mode == trace, 0);
++  _dl_map_object_deps (main_map, NULL, 0, mode == trace, 0);
+   HP_TIMING_NOW (stop);
+   HP_TIMING_DIFF (diff, start, stop);
+   HP_TIMING_ACCUM_NT (load_time, diff);
+@@ -2301,7 +2221,7 @@ ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
       the address since by now the variable might be in another object.  */
    r = _dl_debug_initialize (0, LM_ID_BASE);
    r->r_state = RT_CONSISTENT;
@@ -1902,3 +2044,32 @@ index 504c95f..dcfc259 100644
      _dl_reloc_bad_type (map, r_type, 1);
  }
  
+diff --git a/sysdeps/x86_64/hp-timing.h b/sysdeps/x86_64/hp-timing.h
+index d88206c..886c500 100644
+--- a/sysdeps/x86_64/hp-timing.h
++++ b/sysdeps/x86_64/hp-timing.h
+@@ -18,23 +18,6 @@
+ 
+ #ifndef _HP_TIMING_H
+ 
+-/* We can use some of the i686 implementation without changes.  */
+-# include <sysdeps/i386/i686/hp-timing.h>
+-
+-/* The "=A" constraint used in 32-bit mode does not work in 64-bit mode.  */
+-# undef HP_TIMING_NOW
+-# define HP_TIMING_NOW(Var) \
+-  ({ unsigned int _hi, _lo; \
+-     asm volatile ("rdtsc" : "=a" (_lo), "=d" (_hi)); \
+-     (Var) = ((unsigned long long int) _hi << 32) | _lo; })
+-
+-/* The funny business for 32-bit mode is not required here.  */
+-# undef HP_TIMING_ACCUM
+-# define HP_TIMING_ACCUM(Sum, Diff)					      \
+-  do {									      \
+-    hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead);		      \
+-    __asm__ __volatile__ ("lock; addq %1, %0"				      \
+-			  : "=m" (Sum) : "r" (__diff), "m" (Sum));	      \
+-  } while (0)
++# include <sysdeps/generic/hp-timing.h>
+ 
+ #endif /* hp-timing.h */

+ 1 - 1
LibOS/shim/include/shim_unistd.h

@@ -71,6 +71,6 @@ struct sigcp {
 
 #define SIGCP                   33
 
-#define SHIM_NSYSCALLS          311
+#include "shim_unistd_defs.h"
 
 #endif /* _SHIM_UNISTD_H_ */

+ 9 - 0
LibOS/shim/include/shim_unistd_defs.h

@@ -0,0 +1,9 @@
+/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
+/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
+
+#ifndef _SHIM_UNISTD_DEFS_H_
+#define _SHIM_UNISTD_DEFS_H_
+
+#define SHIM_NSYSCALLS          311
+
+#endif

File diff suppressed because it is too large
+ 0 - 0
LibOS/shim/src/.packed/shim.sha384


BIN
LibOS/shim/src/.packed/shim.tar.gz


+ 1 - 0
LibOS/shim/src/Makefile

@@ -51,6 +51,7 @@ all: $(shim_target)
 ifeq ($(DEBUG),1)
 CC += -gdwarf-2 -g3
 CFLAGS += -DDEBUG
+ASFLAGS += -DDEBUG
 endif
 export DEBUG
 

+ 2 - 0
LibOS/shim/src/bookkeep/shim_thread.c

@@ -457,6 +457,8 @@ int walk_thread_list (int (*callback) (struct shim_thread *, void *, bool *),
 relock:
     lock(thread_list_lock);
 
+    debug("walk_thread_list(callback=%p)\n", callback);
+
     list_for_each_entry_safe(tmp, n, &thread_list, list) {
         if (tmp->tid <= min_tid)
             continue;

+ 29 - 27
LibOS/shim/src/fs/proc/thread.c

@@ -618,36 +618,38 @@ static int proc_match_thread (const char * name)
     return thread ? 1 : 0;
 }
 
+struct walk_thread_arg {
+    struct shim_dirent * buf, * buf_end;
+};
+
+static int walk_cb (struct shim_thread * thread, void * arg, bool * unlocked)
+{
+    struct walk_thread_arg * args = (struct walk_thread_arg *) arg;
+    IDTYPE pid = thread->tid;
+    int p = pid, l = 0;
+    for ( ; p ; p /= 10, l++);
+
+    if ((void *) (args->buf + 1) + l + 1 > (void *) args->buf_end)
+        return -ENOBUFS;
+
+    struct shim_dirent * buf = args->buf;
+
+    buf->next = (void *) (buf + 1) + l + 1;
+    buf->ino = 1;
+    buf->type = LINUX_DT_DIR;
+    buf->name[l--] = 0;
+    for (p = pid ; p ; p /= 10)
+        buf->name[l--] = p % 10 + '0';
+
+    args->buf = buf->next;
+    return 1;
+}
+
 static int proc_list_thread (const char * name, struct shim_dirent ** buf,
                              int len)
 {
-    struct walk_thread_arg {
-        struct shim_dirent * buf, * buf_end;
-    } args = {
-        .buf = *buf, .buf_end = (void *) *buf + len,
-    };
-
-    int walk_cb (struct shim_thread * thread, void * arg, bool * unlocked) {
-        struct walk_thread_arg * args = (struct walk_thread_arg *) arg;
-        IDTYPE pid = thread->tid;
-        int p = pid, l = 0;
-        for ( ; p ; p /= 10, l++);
-
-        if ((void *) (args->buf + 1) + l + 1 > (void *) args->buf_end)
-            return -ENOBUFS;
-
-        struct shim_dirent * buf = args->buf;
-
-        buf->next = (void *) (buf + 1) + l + 1;
-        buf->ino = 1;
-        buf->type = LINUX_DT_DIR;
-        buf->name[l--] = 0;
-        for (p = pid ; p ; p /= 10)
-            buf->name[l--] = p % 10 + '0';
-
-        args->buf = buf->next;
-        return 1;
-    }
+    struct walk_thread_arg args =
+        { .buf = *buf, .buf_end = (void *) *buf + len, };
 
     int ret = walk_thread_list(&walk_cb, &args, false);
     if (ret < 0)

+ 31 - 31
LibOS/shim/src/ipc/shim_ipc_child.c

@@ -100,47 +100,47 @@ void ipc_parent_exit (struct shim_ipc_port * port, IDTYPE vmid,
         put_ipc_info(parent);
 }
 
-int remove_child_thread (IDTYPE vmid, unsigned int exitcode)
-{
-    assert(vmid != cur_process.vmid);
+struct thread_info {
+    IDTYPE vmid;
+    unsigned int exitcode;
+};
 
-    struct thread_info {
-        IDTYPE vmid;
-        unsigned int exitcode;
-    };
-
-    int child_sthread_exit (struct shim_simple_thread * thread, void * arg,
-                            bool * unlocked)
-    {
-        struct thread_info * info = (struct thread_info *) arg;
-        if (thread->vmid == info->vmid) {
-            if (thread->is_alive) {
-                thread->exit_code = -info->exitcode;
-                thread->is_alive = false;
-                DkEventSet(thread->exit_event);
-            }
-            return 1;
+static int child_sthread_exit (struct shim_simple_thread * thread, void * arg,
+                               bool * unlocked)
+{
+    struct thread_info * info = (struct thread_info *) arg;
+    if (thread->vmid == info->vmid) {
+        if (thread->is_alive) {
+            thread->exit_code = -info->exitcode;
+            thread->is_alive = false;
+            DkEventSet(thread->exit_event);
         }
-        return 0;
+        return 1;
     }
+    return 0;
+}
 
-    int child_thread_exit (struct shim_thread * thread, void * arg,
-                           bool * unlocked)
-    {
-        struct thread_info * info = (struct thread_info *) arg;
-        if (thread->vmid == info->vmid) {
-            if (thread->is_alive) {
-                thread->exit_code = -info->exitcode;
-                thread_exit(thread, false);
-            }
-            return 1;
+static int child_thread_exit (struct shim_thread * thread, void * arg,
+                              bool * unlocked)
+{
+    struct thread_info * info = (struct thread_info *) arg;
+    if (thread->vmid == info->vmid) {
+        if (thread->is_alive) {
+            thread->exit_code = -info->exitcode;
+            thread_exit(thread, false);
         }
-        return 0;
+        return 1;
     }
+    return 0;
+}
 
+int remove_child_thread (IDTYPE vmid, unsigned int exitcode)
+{
     struct thread_info info = { .vmid = vmid, .exitcode = exitcode };
     int nkilled = 0, ret;
 
+    assert(vmid != cur_process.vmid);
+
     if ((ret = walk_thread_list(&child_thread_exit, &info, false)) > 0)
         nkilled += ret;
 

+ 13 - 13
LibOS/shim/src/ipc/shim_ipc_pid.c

@@ -42,6 +42,19 @@
 
 #include "shim_ipc_nsimpl.h"
 
+static int thread_add_subrange (struct shim_thread * thread, void * arg,
+                                bool * unlocked)
+{
+    if (!thread->in_vm)
+        return 0;
+
+    struct shim_ipc_info * info = (struct shim_ipc_info *) arg;
+
+    add_pid_subrange(thread->tid, info->vmid,
+                     qstrgetstr(&info->uri), &thread->tid_lease);
+    return 0;
+}
+
 int init_ns_pid (void)
 {
     struct shim_ipc_info * info;
@@ -52,19 +65,6 @@ int init_ns_pid (void)
     if ((ret = create_ipc_location(&info)) < 0)
         return ret;
 
-    int thread_add_subrange (struct shim_thread * thread, void * arg,
-                             bool * unlocked)
-    {
-        if (!thread->in_vm)
-            return 0;
-
-        struct shim_ipc_info * info = (struct shim_ipc_info *) arg;
-
-        add_pid_subrange(thread->tid, info->vmid,
-                         qstrgetstr(&info->uri), &thread->tid_lease);
-        return 0;
-    }
-
     walk_thread_list(&thread_add_subrange, info, false);
     return 0;
 }

+ 5 - 0
LibOS/shim/src/shim_table.c

@@ -24,6 +24,11 @@
  */
 
 #include <shim_table.h>
+#include <shim_internal.h>
+
+void debug_unsupp (int num){
+    debug ("Unsupported system call %d\n", num);
+}
 
 shim_fp shim_table [SHIM_NSYSCALLS] = {
     (shim_fp) __shim_read,

+ 9 - 9
LibOS/shim/src/sys/shim_exec.c

@@ -41,18 +41,18 @@
 #include <sys/mman.h>
 #include <asm/prctl.h>
 
-static int close_cloexec_handle (struct shim_handle_map * map)
+static int close_on_exec (struct shim_fd_handle * fd_hdl,
+                          struct shim_handle_map * map, void * arg)
 {
-    auto int close_on_exec (struct shim_fd_handle * fd_hdl,
-                           struct shim_handle_map * map, void * arg)
-    {
-        if (fd_hdl->flags & FD_CLOEXEC) {
-            struct shim_handle * hdl = __detach_fd_handle(fd_hdl, NULL, map);
-            close_handle(hdl);
-        }
-        return 0;
+    if (fd_hdl->flags & FD_CLOEXEC) {
+        struct shim_handle * hdl = __detach_fd_handle(fd_hdl, NULL, map);
+        close_handle(hdl);
     }
+    return 0;
+}
 
+static int close_cloexec_handle (struct shim_handle_map * map)
+{
     return walk_handle_map(&close_on_exec, map, NULL);
 }
 

+ 8 - 4
LibOS/shim/src/sys/shim_ioctl.c

@@ -142,10 +142,6 @@ static int ioctl_termios (struct shim_handle * hdl, unsigned int cmd,
         case TIOCGETD:
         /* 0x00005425 TCSBRKP int */
         case TCSBRKP:
-        /* 0x00005450 FIONCLEX void */
-        case FIONCLEX:
-        /* 0x00005451 FIOCLEX void */
-        case FIOCLEX:
         /* 0x00005452 FIOASYNC const int * */
         case FIOASYNC:
         /* 0x00005453 TIOCSERCONFIG void */
@@ -343,8 +339,16 @@ int shim_do_ioctl (int fd, int cmd, unsigned long arg)
         case TIOCSETD:
         case TIOCGETD:
         case TCSBRKP:
+            ret = ioctl_termios(hdl, cmd, arg);
+            break;
         case FIONCLEX:
+            hdl->flags &= ~FD_CLOEXEC;
+            ret = 0;
+            break;
         case FIOCLEX:
+            hdl->flags |= FD_CLOEXEC;
+            ret = 0;
+            break;
         case FIOASYNC:
         case TIOCSERCONFIG:
         case TIOCSERGWILD:

+ 10 - 2
LibOS/shim/src/syscallas.S

@@ -21,11 +21,12 @@
  */
 
 #include <shim_tls.h>
+#include <shim_unistd_defs.h>
 
-.text
         .global syscalldb
         .type syscalldb, @function
-        .extern shim_table
+        .extern shim_table, debug_unsupp
+
 
 syscalldb:
         .cfi_startproc
@@ -43,6 +44,9 @@ syscalldb:
 
         pushq %rbx
 
+        cmp $SHIM_NSYSCALLS, %rax
+        jge isundef
+
         leaq shim_table(%rip), %rbx
         movq (%rbx,%rax,8), %rbx
         cmp $0, (%rbx)
@@ -88,6 +92,10 @@ isdef:
         jmp ret
 
 isundef:
+#ifdef DEBUG
+        mov %rax, %rdi
+        call debug_unsupp
+#endif
         movq $-38, %rax
 
 ret:

+ 3 - 4
LibOS/shim/test/apps/bash/bash.manifest.template

@@ -5,9 +5,8 @@ loader.exec = file:/bin/bash
 loader.execname = /bin/bash
 loader.env.LD_LIBRARY_PATH = /lib:/lib/x86_64-linux-gnu:/usr/lib:/usr/lib/x86_64-linux-gnu
 loader.env.PATH = /bin:/usr/bin
-loader.env.USERNAME =
-loader.env.HOME =
-loader.env.PWD =
+loader.env.USERNAME = root
+loader.env.HOME = /
 loader.debug_type = none
 
 fs.mount.lib1.type = chroot
@@ -34,7 +33,7 @@ sgx.trusted_files.libm = file:$(LIBCDIR)/libm.so.6
 sgx.trusted_files.libpthread = file:$(LIBCDIR)/libpthread.so.0
 sgx.trusted_files.libtinfo = file:/lib/x86_64-linux-gnu/libtinfo.so.5
 sgx.trusted_files.ls = file:/bin/ls
-sgx.trusted_files.rm = file:/bin/cp
+sgx.trusted_files.cp = file:/bin/cp
 sgx.trusted_files.rm = file:/bin/rm
 
 sgx.trusted_children.ls = file:ls.sig

+ 1 - 1
Pal/test/.packed/test.sha384

@@ -1 +1 @@
-Broadcast Cpuid Event Exception Failure File Fork HandleSend HelloWorld Ipc Memory Pie Pipe Process Segment Select Server Sleep Tcp Thread Udp Wait Yield 54958e0184a7f70462d402afb1e8f8b5f39f605c23cf7173d8671dec97796850511e827ec7146413ed02541988d2f2dd
+Broadcast Cpuid Event Exception Failure File Fork HandleSend HelloWorld Ipc Memory Pie Pipe Process Segment Select Server Sleep Tcp Thread Udp Wait Yield d9b49db793cf2dd0e277b6ce39c29f2251780b358b4aa5a968e7e55b22ed5ae4822eb705c9f44f6b39ebf5b1a800e382

BIN
Pal/test/.packed/test.tar.gz


Some files were not shown because too many files changed in this diff