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
This commit is contained in:
Chia-Che Tsai
2016-10-13 16:45:32 -04:00
parent c2c92723b9
commit e2e01667c2
17 changed files with 302 additions and 101 deletions
+173 -2
View File
@@ -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
View File
@@ -71,6 +71,6 @@ struct sigcp {
#define SIGCP 33
#define SHIM_NSYSCALLS 311
#include "shim_unistd_defs.h"
#endif /* _SHIM_UNISTD_H_ */
+9
View File
@@ -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
+1 -1
View File
@@ -1 +1 @@
bookkeep/shim_handle.o bookkeep/shim_signal.o bookkeep/shim_thread.o bookkeep/shim_vma.o elf/shim_rtld.o fs/chroot/fs.o fs/dev/fs.o fs/pipe/fs.o fs/proc/fs.o fs/proc/info.o fs/proc/ipc-thread.o fs/proc/thread.o fs/shim_dcache.o fs/shim_fs_hash.o fs/shim_fs.o fs/shim_namei.o fs/socket/fs.o fs/str/fs.o ipc/shim_ipc_child.o ipc/shim_ipc_helper.o ipc/shim_ipc.o ipc/shim_ipc_pid.o ipc/shim_ipc_sysv.o libsysdb.a libsysdb_debug.so libsysdb.so shim_async.o shim_checkpoint.o shim_debug.o shim_init.o shim_malloc.o shim_parser.o shim_random.o shim_syscalls.o shim_table.o start.o syscallas.o sys/shim_access.o sys/shim_alarm.o sys/shim_benchmark.o sys/shim_brk.o sys/shim_clone.o sys/shim_dup.o sys/shim_epoll.o sys/shim_exec.o sys/shim_exit.o sys/shim_fcntl.o sys/shim_fork.o sys/shim_fs.o sys/shim_futex.o sys/shim_getcwd.o sys/shim_getpid.o sys/shim_getrlimit.o sys/shim_ioctl.o sys/shim_migrate.o sys/shim_mmap.o sys/shim_msgget.o sys/shim_open.o sys/shim_pipe.o sys/shim_poll.o sys/shim_sandbox.o sys/shim_sched.o sys/shim_semget.o sys/shim_sigaction.o sys/shim_sleep.o sys/shim_socket.o sys/shim_stat.o sys/shim_time.o sys/shim_uname.o sys/shim_vfork.o sys/shim_wait.o sys/shim_wrappers.o utils/md5.o utils/printf.o utils/strobjs.o 1e360b5c25155fe56c120120f88f25eec00ff96007893eceafd124a56de5e12dcf3e63852b58221cd289daf93e8d4cd3
bookkeep/shim_handle.o bookkeep/shim_signal.o bookkeep/shim_thread.o bookkeep/shim_vma.o elf/shim_rtld.o fs/chroot/fs.o fs/dev/fs.o fs/pipe/fs.o fs/proc/fs.o fs/proc/info.o fs/proc/ipc-thread.o fs/proc/thread.o fs/shim_dcache.o fs/shim_fs_hash.o fs/shim_fs.o fs/shim_namei.o fs/socket/fs.o fs/str/fs.o ipc/shim_ipc_child.o ipc/shim_ipc_helper.o ipc/shim_ipc.o ipc/shim_ipc_pid.o ipc/shim_ipc_sysv.o libsysdb.a libsysdb_debug.so libsysdb.so shim_async.o shim_checkpoint.o shim_debug.o shim_init.o shim_malloc.o shim_parser.o shim_random.o shim_syscalls.o shim_table.o start.o syscallas.o sys/shim_access.o sys/shim_alarm.o sys/shim_benchmark.o sys/shim_brk.o sys/shim_clone.o sys/shim_dup.o sys/shim_epoll.o sys/shim_exec.o sys/shim_exit.o sys/shim_fcntl.o sys/shim_fork.o sys/shim_fs.o sys/shim_futex.o sys/shim_getcwd.o sys/shim_getpid.o sys/shim_getrlimit.o sys/shim_ioctl.o sys/shim_migrate.o sys/shim_mmap.o sys/shim_msgget.o sys/shim_open.o sys/shim_pipe.o sys/shim_poll.o sys/shim_sandbox.o sys/shim_sched.o sys/shim_semget.o sys/shim_sigaction.o sys/shim_sleep.o sys/shim_socket.o sys/shim_stat.o sys/shim_time.o sys/shim_uname.o sys/shim_vfork.o sys/shim_wait.o sys/shim_wrappers.o utils/md5.o utils/printf.o utils/strobjs.o f963ae7fe22483f709f5d91102546740ef2760008af2b7800dba463527caa301f60b48f45aba39c718db0b75a6edd71e
Binary file not shown.
+1
View File
@@ -51,6 +51,7 @@ all: $(shim_target)
ifeq ($(DEBUG),1)
CC += -gdwarf-2 -g3
CFLAGS += -DDEBUG
ASFLAGS += -DDEBUG
endif
export DEBUG
+2
View File
@@ -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
View File
@@ -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)
+36 -36
View File
@@ -100,47 +100,47 @@ void ipc_parent_exit (struct shim_ipc_port * port, IDTYPE vmid,
put_ipc_info(parent);
}
struct thread_info {
IDTYPE vmid;
unsigned int exitcode;
};
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 1;
}
return 0;
}
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 1;
}
return 0;
}
int remove_child_thread (IDTYPE vmid, unsigned int exitcode)
{
assert(vmid != cur_process.vmid);
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;
}
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;
}
return 0;
}
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
View File
@@ -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
View File
@@ -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,
+10 -10
View File
@@ -41,18 +41,18 @@
#include <sys/mman.h>
#include <asm/prctl.h>
static 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;
}
static int close_cloexec_handle (struct shim_handle_map * map)
{
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;
}
return walk_handle_map(&close_on_exec, map, NULL);
}
+8 -4
View File
@@ -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
View File
@@ -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:
@@ -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
View File
@@ -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
Binary file not shown.