diff --git a/.travis.yml b/.travis.yml index c71accc4..0c9052a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,24 @@ language: c -script: make && make install + +before_install: + - sudo apt-get install python-protobuf python-crypto + - sudo apt-get install linux-headers-$(uname -r) + +before_script: + - git clone https://github.com/01org/linux-sgx-driver.git -b sgx_driver_$ISGX_DRIVER_VERSION + +script: + - make + - cd $TRAVIS_BUILD_DIR/Pal/src && make clean && make SGX=1 + - cd $TRAVIS_BUILD_DIR/Pal/src/host/Linux-SGX/sgx-driver && make + - cd $TRAVIS_BUILD_DIR/Pal/regression && make regression + - cd $TRAVIS_BUILD_DIR/LibOS/shim/test/regression && make regression + - cd $TRAVIS_BUILD_DIR/LibOS/shim/test/apps/ltp && make regression matrix: include: - os: linux dist: trusty + env: + - ISGX_DRIVER_PATH=$TRAVIS_BUILD_DIR/linux-sgx-driver + - ISGX_DRIVER_VERSION=1.9 diff --git a/LICENSE.addendum.txt b/LICENSE.addendum.txt index 651fe24a..47b6a10b 100644 --- a/LICENSE.addendum.txt +++ b/LICENSE.addendum.txt @@ -1,4 +1,22 @@ Graphene also includes the following third party sources (and licenses): mbedtls - Apache 2.0 wolfssl - GPL v2 + +RSA's MD5 algorithm (LibOS/shim/src/utils/md5.c) - RSA custom attribution license + +Linux kernel - GPL v2 + - dcache implementation + - linked list implementation + - atomic_add, cmpxchg and friends implementation + +Internet Software Consortium (permissive license): Pal/lib/network/inet_pton.c + +MIT JOS (mix of MIT and BSD licenses: +* Pal/lib/stdlib/printfmt.c + +A number of files taken from other C libraries: +* glibc - LGPL +* musl - MIT + [incomplete: more to come] + diff --git a/LibOS/glibc-2.19.patch b/LibOS/glibc-2.19.patch index 3aeec384..8fef9306 100644 --- a/LibOS/glibc-2.19.patch +++ b/LibOS/glibc-2.19.patch @@ -1804,19 +1804,17 @@ diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall.S b/sysdeps/unix/sysv/linux/ index 92c2f5b..e32ebb2 100644 --- a/sysdeps/unix/sysv/linux/x86_64/syscall.S +++ b/sysdeps/unix/sysv/linux/x86_64/syscall.S -@@ -31,10 +31,13 @@ ENTRY (syscall) +@@ -31,10 +31,12 @@ movq %rsi, %rdi /* shift arg1 - arg5. */ movq %rdx, %rsi movq %rcx, %rdx -- movq %r8, %r10 -+ /* DEP 1/28/17: This is not the Linux kernel; use user-space calling -+ * convention */ -+ /* movq %r8, %r10 */ -+ movq %r8, %rcx ++ /* DEP 8/17/17: Keep kernel calling ++ * convention and fix in libOS */ + movq %r8, %r10 movq %r9, %r8 movq 8(%rsp),%r9 /* arg6 is on the stack. */ - syscall /* Do the system call. */ -+ SYSCALLDB /* Do the system call. */ ++ SYSCALLDB /* Do the system call. */ cmpq $-4095, %rax /* Check %rax for error. */ jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */ ret /* Return to caller. */ diff --git a/LibOS/shim/include/bitop.h b/LibOS/shim/include/bitop.h deleted file mode 100644 index eb23795f..00000000 --- a/LibOS/shim/include/bitop.h +++ /dev/null @@ -1,113 +0,0 @@ -/* Copyright (C) 2014 OSCAR lab, Stony Brook University - This file is part of Graphene Library OS. - - Graphene Library OS is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - Graphene Library OS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* - * bitop.h - */ - -#ifndef _BITOP_H -#define _BITOP_H - -#define ADDR (*(volatile long *) addr) - -#define LOCK_PREFIX "" - -/** - * set_bit - Atomically set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * This function is atomic and may not be reordered. See __set_bit() - * if you do not require the atomic guarantees. - * Note that @nr may be almost arbitrarily large; this function is not - * restricted to acting on a single-word quantity. - */ -static __inline__ void set_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btsl %1,%0" - :"=m" (ADDR) - :"dIr" (nr) : "memory"); -} - -/** - * __set_bit - Set a bit in memory - * @nr: the bit to set - * @addr: the address to start counting from - * - * Unlike set_bit(), this function is non-atomic and may be reordered. - * If it's called on the same region of memory simultaneously, the effect - * may be that only one operation succeeds. - */ -static __inline__ void __set_bit(int nr, volatile void * addr) -{ - __asm__ volatile( - "btsl %1,%0" - :"=m" (ADDR) - :"dIr" (nr) : "memory"); -} - -/** - * clear_bit - Clears a bit in memory - * @nr: Bit to clear - * @addr: Address to start counting from - * - * clear_bit() is atomic and may not be reordered. However, it does - * not contain a memory barrier, so if it is used for locking purposes, - * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit() - * in order to ensure changes are visible on other processors. - */ -static __inline__ void clear_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( LOCK_PREFIX - "btrl %1,%0" - :"=m" (ADDR) - :"dIr" (nr)); -} - -static __inline__ void __clear_bit(int nr, volatile void * addr) -{ - __asm__ __volatile__( - "btrl %1,%0" - :"=m" (ADDR) - :"dIr" (nr)); -} - -static __inline__ int constant_test_bit(int nr, const volatile void * addr) -{ - return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0; -} - -static __inline__ int variable_test_bit(int nr, volatile const void * addr) -{ - int oldbit; - - __asm__ __volatile__( - "btl %2,%1\n\tsbbl %0,%0" - :"=r" (oldbit) - :"m" (ADDR),"dIr" (nr)); - return oldbit; -} - -#define test_bit(nr,addr) \ -(__builtin_constant_p(nr) ? \ - constant_test_bit((nr),(addr)) : \ - variable_test_bit((nr),(addr))) - - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -#endif diff --git a/LibOS/shim/include/shim_fs.h b/LibOS/shim/include/shim_fs.h index fa9fc764..21494e02 100644 --- a/LibOS/shim/include/shim_fs.h +++ b/LibOS/shim/include/shim_fs.h @@ -192,7 +192,10 @@ struct shim_d_ops { int (*rename) (struct shim_dentry * old, struct shim_dentry * new); /* readdir: given the path relative to the mount point, read the childs - into the the buffer */ + into the the buffer. This call always returns everything under + the directory in one big buffer; you do not need to try again + or keep a cursor in the directory. You do need to free the + returned buffer. */ int (*readdir) (struct shim_dentry * dent, struct shim_dirent ** dirent); }; diff --git a/LibOS/shim/include/shim_handle.h b/LibOS/shim/include/shim_handle.h index 54429f2c..e69f8bc3 100644 --- a/LibOS/shim/include/shim_handle.h +++ b/LibOS/shim/include/shim_handle.h @@ -78,6 +78,7 @@ struct shim_file_data { unsigned long atime; unsigned long mtime; unsigned long ctime; + unsigned long nlink; }; struct shim_file_handle { diff --git a/LibOS/shim/include/shim_internal.h b/LibOS/shim/include/shim_internal.h index f19bb9a2..bce2f5d3 100644 --- a/LibOS/shim/include/shim_internal.h +++ b/LibOS/shim/include/shim_internal.h @@ -752,7 +752,8 @@ extern const char ** initial_envp; void get_brk_region (void ** start, void ** end, void ** current); int init_randgen (void); -int init_brk (void); +int reset_brk (void); +int init_brk_region (void * brk_region); int init_heap (void); int init_internal_map (void); int init_loader (void); diff --git a/LibOS/shim/include/shim_ipc.h b/LibOS/shim/include/shim_ipc.h index 7d004719..50441989 100644 --- a/LibOS/shim/include/shim_ipc.h +++ b/LibOS/shim/include/shim_ipc.h @@ -165,12 +165,13 @@ enum { struct shim_ipc_cld_exit { IDTYPE ppid, tid; unsigned int exitcode; + unsigned int term_signal; #ifdef PROFILE unsigned long time; #endif } __attribute__((packed)); -int ipc_cld_exit_send (IDTYPE ppid, IDTYPE tid, unsigned int exitcode); +int ipc_cld_exit_send (IDTYPE ppid, IDTYPE tid, unsigned int exitcode, unsigned int term_signal); int ipc_cld_exit_callback (IPC_CALLBACK_ARGS); /* CLD_JOIN: child join the parent group */ @@ -595,9 +596,9 @@ int do_ipc_duplex (struct shim_ipc_msg_obj * msg, void * private_data); void ipc_parent_exit (struct shim_ipc_port * port, IDTYPE vmid, - unsigned int exitcode); + unsigned int exitcode, unsigned int term_signal); void ipc_child_exit (struct shim_ipc_port * port, IDTYPE vmid, - unsigned int exitcode); + unsigned int exitcode, unsigned int term_signal); int create_ipc_helper (void); int exit_with_ipc_helper (bool handover); diff --git a/LibOS/shim/include/shim_signal.h b/LibOS/shim/include/shim_signal.h index cc514707..7b007c2d 100644 --- a/LibOS/shim/include/shim_signal.h +++ b/LibOS/shim/include/shim_signal.h @@ -13,9 +13,6 @@ struct shim_signal_handle { struct __kernel_sigaction * action; }; -#define NUM_SIGS 64 -#define NUM_KNOWN_SIGS 32 - # define BITS_PER_WORD sizeof(unsigned long) /* The standard def of this macro is dumb */ #undef _SIGSET_NWORDS @@ -146,7 +143,8 @@ void append_signal (struct shim_thread * thread, int sig, siginfo_t * info, void deliver_signal (siginfo_t * info, PAL_CONTEXT * context); __sigset_t * get_sig_mask (struct shim_thread * thread); -__sigset_t * set_sig_mask (struct shim_thread * thread, __sigset_t * new_set); +__sigset_t * set_sig_mask (struct shim_thread * thread, + const __sigset_t * new_set); int do_kill_thread (IDTYPE sender, IDTYPE tgid, IDTYPE tid, int sig, bool use_ipc); diff --git a/LibOS/shim/include/shim_table.h b/LibOS/shim/include/shim_table.h index 507c9207..0e4eab93 100644 --- a/LibOS/shim/include/shim_table.h +++ b/LibOS/shim/include/shim_table.h @@ -27,7 +27,7 @@ long __shim_mmap (long, long, long, long, long, long); long __shim_mprotect (long, long, long); long __shim_munmap (long, long); long __shim_brk (long); -long __shim_rt_sigaction (long, long, long); +long __shim_rt_sigaction (long, long, long, long); long __shim_rt_sigprocmask (long, long, long); long __shim_rt_sigreturn (long); long __shim_ioctl (long, long, long); @@ -343,7 +343,7 @@ int shim_do_mprotect (void * addr, size_t len, int prot); int shim_do_munmap (void * addr, size_t len); void * shim_do_brk (void * brk); int shim_do_sigaction (int signum, const struct __kernel_sigaction * act, - struct __kernel_sigaction * oldact); + struct __kernel_sigaction * oldact, size_t sigsetsize); int shim_do_sigprocmask (int how, const __sigset_t * set, __sigset_t * oldset); int shim_do_sigreturn (int __unused); int shim_do_ioctl (int fd, int cmd, unsigned long arg); @@ -442,6 +442,7 @@ pid_t shim_do_getpgrp (void); int shim_do_setsid (void); int shim_do_getpgid (pid_t pid); int shim_do_getsid (pid_t pid); +int shim_do_sigpending (__sigset_t * set, size_t sigsetsize); int shim_do_sigaltstack (const stack_t * ss, stack_t * oss); int shim_do_sigsuspend (const __sigset_t * mask); void * shim_do_arch_prctl (int code, void * addr); @@ -525,7 +526,7 @@ int shim_mprotect (void * addr, size_t len, int prot); int shim_munmap (void * addr, size_t len); void * shim_brk (void * brk); int shim_rt_sigaction (int signum, const struct __kernel_sigaction * act, - struct __kernel_sigaction * oldact); + struct __kernel_sigaction * oldact, size_t sigsetsize); int shim_rt_sigprocmask (int how, const __sigset_t * set, __sigset_t * oldset); int shim_rt_sigreturn (int __unused); int shim_ioctl (int fd, int cmd, unsigned long arg); diff --git a/LibOS/shim/include/shim_thread.h b/LibOS/shim/include/shim_thread.h index 31521a4b..699c3e44 100644 --- a/LibOS/shim/include/shim_thread.h +++ b/LibOS/shim/include/shim_thread.h @@ -67,6 +67,8 @@ struct shim_thread { PAL_HANDLE exit_event; int exit_code; + int term_signal; // Store the terminating signal, if any; needed for + // wait() and friends bool is_alive; PAL_HANDLE child_exit_event; @@ -103,6 +105,7 @@ struct shim_simple_thread { /* exit event and status */ PAL_HANDLE exit_event; int exit_code; + int term_signal; bool is_alive; /* nodes in global handles */ @@ -292,7 +295,9 @@ void set_handle_map (struct shim_thread * thread, /* shim exit callback */ int thread_exit (struct shim_thread * self, bool send_ipc); -int try_process_exit (int error_code); +/* If the process was killed by a signal, pass it in the second + * argument, else pass zero */ +int try_process_exit (int error_code, int term_signal); /* thread cloning helpers */ struct clone_args { diff --git a/LibOS/shim/include/shim_types.h b/LibOS/shim/include/shim_types.h index 5c66729f..247e543c 100644 --- a/LibOS/shim/include/shim_types.h +++ b/LibOS/shim/include/shim_types.h @@ -156,10 +156,12 @@ struct __kernel_sigaction { /* linux/aio_abi.h (for io_setup which has no glibc wrapper) */ typedef unsigned long aio_context_t; -/* bits/sigset.h */ -# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int))) +/* asm/signal.h */ +#define NUM_SIGS 64 +#define NUM_KNOWN_SIGS 32 + typedef struct { - unsigned long int __val[_SIGSET_NWORDS]; + unsigned long __val[NUM_SIGS / (8 * sizeof(unsigned long))]; } __sigset_t; /* linux/rlimit.h */ diff --git a/LibOS/shim/src/bookkeep/shim_signal.c b/LibOS/shim/src/bookkeep/shim_signal.c index df7b2bc0..f0caa0dc 100644 --- a/LibOS/shim/src/bookkeep/shim_signal.c +++ b/LibOS/shim/src/bookkeep/shim_signal.c @@ -262,10 +262,23 @@ internal: put_vma(vma); goto internal; } - if (vma->file) { - /* XXX: need more sophisticated judgement */ - signo = SIGBUS; - code = BUS_ADRERR; + if (vma->file && vma->file->type == TYPE_FILE) { + /* DEP 3/3/17: If the mapping exceeds end of a file (but is in the VMA) + * then return a SIGBUS. */ + uint64_t eof_in_vma = (uint64_t) vma->addr + vma->offset + vma->file->info.file.size; + if (arg > eof_in_vma) { + signo = SIGBUS; + code = BUS_ADRERR; + } else if ((context->err & 4) && !(vma->flags & PROT_WRITE)) { + /* DEP 3/3/17: If the page fault gives a write error, and + * the VMA is read-only, return SIGSEGV+SEGV_ACCERR */ + signo = SIGSEGV; + code = SEGV_ACCERR; + } else { + /* XXX: need more sophisticated judgement */ + signo = SIGBUS; + code = BUS_ADRERR; + } } else { code = SEGV_ACCERR; } @@ -379,7 +392,8 @@ __sigset_t * get_sig_mask (struct shim_thread * thread) return &(thread->signal_mask); } -__sigset_t * set_sig_mask (struct shim_thread * thread, __sigset_t * set) +__sigset_t * set_sig_mask (struct shim_thread * thread, + const __sigset_t * set) { if (!thread) thread = get_cur_thread(); @@ -565,17 +579,24 @@ static void sighandler_kill (int sig, siginfo_t * info, void * ucontext) break; } - try_process_exit(0); + try_process_exit(0, sig); DkThreadExit(); } +/* We don't currently implement core dumps, but put a wrapper + * in case we do in the future */ +static void sighandler_core (int sig, siginfo_t * info, void * ucontext) +{ + sighandler_kill(sig, info, ucontext); +} + static void (*default_sighandler[NUM_SIGS]) (int, siginfo_t *, void *) = { /* SIGHUP */ &sighandler_kill, /* SIGINT */ &sighandler_kill, /* SIGQUIT */ &sighandler_kill, /* SIGILL */ &sighandler_kill, - /* SIGTRAP */ NULL, + /* SIGTRAP */ &sighandler_core, /* SIGABRT */ &sighandler_kill, /* SIGBUS */ &sighandler_kill, /* SIGFPE */ &sighandler_kill, @@ -584,7 +605,7 @@ static void (*default_sighandler[NUM_SIGS]) (int, siginfo_t *, void *) = /* SIGSEGV */ &sighandler_kill, /* SIGUSR2 */ NULL, /* SIGPIPE */ &sighandler_kill, - /* SIGALRM */ NULL, + /* SIGALRM */ &sighandler_kill, /* SIGTERM */ &sighandler_kill, /* SIGSTKFLT */ NULL, /* SIGCHLD */ NULL, diff --git a/LibOS/shim/src/bookkeep/shim_vma.c b/LibOS/shim/src/bookkeep/shim_vma.c index 9d3f6e3b..af3ef21b 100644 --- a/LibOS/shim/src/bookkeep/shim_vma.c +++ b/LibOS/shim/src/bookkeep/shim_vma.c @@ -242,6 +242,7 @@ static bool check_vma_flags (const struct shim_vma * vma, const int * flags) return true; if ((vma->flags & VMA_INTERNAL) != ((*flags) & VMA_INTERNAL)) { + debug("Check vma flag failure: vma flags %x, checked flags %x\n", vma->flags, *flags); bug(); return false; } diff --git a/LibOS/shim/src/elf/shim_rtld.c b/LibOS/shim/src/elf/shim_rtld.c index 07f09a54..2e6fc41e 100644 --- a/LibOS/shim/src/elf/shim_rtld.c +++ b/LibOS/shim/src/elf/shim_rtld.c @@ -1481,6 +1481,8 @@ int init_internal_map (void) return 0; } +int init_brk_from_executable (struct shim_handle * exec); + int init_loader (void) { struct shim_thread * cur_thread = get_cur_thread(); @@ -1507,6 +1509,8 @@ int init_loader (void) exec_map = __search_map_by_handle(exec); } + init_brk_from_executable(exec); + if (!interp_map && __need_interp(exec_map) && (ret = __load_interp_object(exec_map)) < 0) @@ -1518,6 +1522,21 @@ out: return ret; } +int init_brk_from_executable (struct shim_handle * exec) +{ + struct link_map * exec_map = __search_map_by_handle(exec); + + if (exec_map) { + /* + * Chia-Che 8/24/2017: + * initialize brk region at the end of the executable data segment. + */ + init_brk_region((void *) ALIGN_UP(exec_map->l_map_end)); + } + + return 0; +} + int register_library (const char * name, unsigned long load_address) { debug("glibc register library %s loaded at %p\n", diff --git a/LibOS/shim/src/fs/chroot/fs.c b/LibOS/shim/src/fs/chroot/fs.c index 3cc43b83..b42c50f3 100644 --- a/LibOS/shim/src/fs/chroot/fs.c +++ b/LibOS/shim/src/fs/chroot/fs.c @@ -212,9 +212,14 @@ static int create_data (struct shim_dentry * dent, const char * uri, int len) return 0; } -static int __query_attr (struct shim_file_data * data, PAL_HANDLE pal_handle) +static int chroot_readdir (struct shim_dentry * dent, + struct shim_dirent ** dirent); + +static int __query_attr (struct shim_dentry * dent, + struct shim_file_data * data, PAL_HANDLE pal_handle) { PAL_STREAM_ATTR pal_attr; + enum shim_file_type old_type = data->type; if (pal_handle ? !DkStreamAttributesQuerybyHandle(pal_handle, &pal_attr) : @@ -234,6 +239,42 @@ static int __query_attr (struct shim_file_data * data, PAL_HANDLE pal_handle) (pal_attr.runnable ? S_IXUSR : 0); atomic_set(&data->size, pal_attr.pending_size); + + if (data->type == FILE_DIR) { + int ret; + /* Move up the uri update; need to convert manifest-level file: + * directives to 'dir:' uris */ + if (old_type != FILE_DIR) { + dent->state |= DENTRY_ISDIRECTORY; + if ((ret = make_uri(dent)) < 0) { + unlock(data->lock); + return ret; + } + } + + /* DEP 3/18/17: If we have a directory, we need to find out how many + * children it has by hand. */ + /* XXX: Keep coherent with rmdir/mkdir/creat, etc */ + struct shim_dirent *d, *dbuf = NULL; + int nlink = 0; + int rv = chroot_readdir(dent, &dbuf); + if (rv != 0) + return rv; + if (dbuf) { + for (d = dbuf; d; d = d->next) + nlink++; + free(dbuf); + debug("Querying a directory; I count %d links.\n", nlink); + } else + nlink = 2; // Educated guess... + data->nlink = nlink; + } else { + /* DEP 3/18/17: Right now, we don't support hard links, + * so just return 1; + */ + data->nlink = 1; + } + data->queried = true; return 0; @@ -287,21 +328,11 @@ static int query_dentry (struct shim_dentry * dent, PAL_HANDLE pal_handle, lock(data->lock); - enum shim_file_type old_type = data->type; - - if (!data->queried && (ret = __query_attr(data, pal_handle)) < 0) { + if (!data->queried && (ret = __query_attr(dent, data, pal_handle)) < 0) { unlock(data->lock); return ret; } - if (data->type == FILE_DIR && old_type != FILE_DIR) { - dent->state |= DENTRY_ISDIRECTORY; - if ((ret = make_uri(dent)) < 0) { - unlock(data->lock); - return ret; - } - } - if (mode) *mode = data->mode; @@ -318,14 +349,23 @@ static int query_dentry (struct shim_dentry * dent, PAL_HANDLE pal_handle, stat->st_atime = (time_t) data->atime; stat->st_mtime = (time_t) data->mtime; stat->st_ctime = (time_t) data->ctime; + stat->st_nlink = data->nlink; + switch (data->type) { - case FILE_REGULAR: stat->st_mode |= S_IFREG; break; - case FILE_DIR: stat->st_mode |= S_IFDIR; break; + case FILE_REGULAR: + stat->st_mode |= S_IFREG; + break; + case FILE_DIR: + stat->st_mode |= S_IFDIR; + break; case FILE_DEV: - case FILE_TTY: stat->st_mode |= S_IFCHR; break; + case FILE_TTY: + stat->st_mode |= S_IFCHR; + break; default: break; } + debug("Stat: Returning link cound %d\n", stat->st_nlink); } unlock(data->lock); @@ -356,7 +396,8 @@ static int chroot_lookup (struct shim_dentry * dent, bool force) return query_dentry(dent, NULL, NULL, NULL); } -static int __chroot_open (const char * uri, int len, int flags, mode_t mode, +static int __chroot_open (struct shim_dentry * dent, + const char * uri, int len, int flags, mode_t mode, struct shim_handle * hdl, struct shim_file_data * data) { @@ -396,7 +437,7 @@ static int __chroot_open (const char * uri, int len, int flags, mode_t mode, if (!data->queried) { lock(data->lock); - ret = __query_attr(data, palhdl); + ret = __query_attr(dent, data, palhdl); unlock(data->lock); } @@ -422,7 +463,7 @@ static int chroot_open (struct shim_handle * hdl, struct shim_dentry * dent, if ((ret = try_create_data(dent, NULL, 0, &data)) < 0) return ret; - if ((ret = __chroot_open(NULL, 0, flags, dent->mode, hdl, data)) < 0) + if ((ret = __chroot_open(dent, NULL, 0, flags, dent->mode, hdl, data)) < 0) return ret; struct shim_file_handle * file = &hdl->info.file; @@ -448,7 +489,7 @@ static int chroot_creat (struct shim_handle * hdl, struct shim_dentry * dir, if ((ret = try_create_data(dent, NULL, 0, &data)) < 0) return ret; - if ((ret = __chroot_open(NULL, 0, flags|O_CREAT|O_EXCL, mode, hdl, + if ((ret = __chroot_open(dent, NULL, 0, flags|O_CREAT|O_EXCL, mode, hdl, data)) < 0) return ret; @@ -467,6 +508,14 @@ static int chroot_creat (struct shim_handle * hdl, struct shim_dentry * dir, hdl->acc_mode = ACC_MODE(flags & O_ACCMODE); qstrcopy(&hdl->uri, &data->host_uri); + /* Increment the parent's link count */ + struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir); + if (parent_data) { + lock(parent_data->lock); + if (parent_data->queried) + parent_data->nlink++; + unlock(parent_data->lock); + } return 0; } @@ -485,7 +534,17 @@ static int chroot_mkdir (struct shim_dentry * dir, struct shim_dentry * dent, return ret; } - return __chroot_open(NULL, 0, O_CREAT|O_EXCL, mode, NULL, data); + ret = __chroot_open(dent, NULL, 0, O_CREAT|O_EXCL, mode, NULL, data); + + /* Increment the parent's link count */ + struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir); + if (parent_data) { + lock(parent_data->lock); + if (parent_data->queried) + parent_data->nlink++; + unlock(parent_data->lock); + } + return ret; } #define NEED_RECREATE(hdl) (!FILE_HANDLE_DATA(hdl)) @@ -512,7 +571,13 @@ static int chroot_recreate (struct shim_handle * hdl) qstrsetstr(&data->host_uri, uri, len); } - return __chroot_open(uri, len, hdl->flags, 0, hdl, data); + /* + * Chia-Che Tsai 8/24/2017: + * when recreating a file handle after migration, the file should + * not be created again. + */ + return __chroot_open(hdl->dentry, uri, len, hdl->flags & ~(O_CREAT|O_EXCL), + 0, hdl, data); } static inline bool check_version (struct shim_handle * hdl) @@ -855,6 +920,9 @@ static int chroot_truncate (struct shim_handle * hdl, uint64_t len) if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0) return ret; + if (!(hdl->acc_mode & MAY_WRITE)) + return -EINVAL; + struct shim_file_handle * file = &hdl->info.file; lock(hdl->lock); @@ -1017,10 +1085,20 @@ static int chroot_checkout (struct shim_handle * hdl) hdl->info.file.data = NULL; } + if (hdl->pal_handle) { + /* + * Chia-Che 8/24/2017: + * if the file still exists in the host, no need to send + * the handle over RPC; otherwise, send it. + */ + PAL_STREAM_ATTR attr; + if (DkStreamAttributesQuery(qstrgetstr(&hdl->uri), &attr)) + hdl->pal_handle = NULL; + } + hdl->info.file.mapsize = 0; hdl->info.file.mapoffset = 0; hdl->info.file.mapbuf = NULL; - hdl->pal_handle = NULL; return 0; } @@ -1067,6 +1145,15 @@ static int chroot_unlink (struct shim_dentry * dir, struct shim_dentry * dent) atomic_inc(&data->version); atomic_set(&data->size, 0); + /* Drop the parent's link count */ + struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir); + if (parent_data) { + lock(parent_data->lock); + if (parent_data->queried) + parent_data->nlink--; + unlock(parent_data->lock); + } + return 0; } diff --git a/LibOS/shim/src/fs/shim_fs.c b/LibOS/shim/src/fs/shim_fs.c index 274c1b57..4f81a5fb 100644 --- a/LibOS/shim/src/fs/shim_fs.c +++ b/LibOS/shim/src/fs/shim_fs.c @@ -159,7 +159,7 @@ static int __mount_one_other (const char * key, int keylen) debug("mounting as %s filesystem: from %s to %s\n", t, uri, p); if ((ret = mount_fs(t, uri, p)) < 0) { - debug("mounting %s on %s (type=%s) failed (%e)\n", t, uri, p, + debug("mounting %s on %s (type=%s) failed (%e)\n", uri, p, t, -ret); return ret; } diff --git a/LibOS/shim/src/ipc/shim_ipc_child.c b/LibOS/shim/src/ipc/shim_ipc_child.c index a6520c4d..07a501e7 100644 --- a/LibOS/shim/src/ipc/shim_ipc_child.c +++ b/LibOS/shim/src/ipc/shim_ipc_child.c @@ -37,7 +37,7 @@ #include static int ipc_thread_exit (IDTYPE vmid, IDTYPE ppid, IDTYPE tid, - unsigned int exitcode, unsigned long exit_time) + unsigned int exitcode, unsigned int term_signal, unsigned long exit_time) { assert(vmid != cur_process.vmid); @@ -52,6 +52,7 @@ static int ipc_thread_exit (IDTYPE vmid, IDTYPE ppid, IDTYPE tid, int ret = 0; //assert(thread->vmid == vmid && !thread->in_vm); thread->exit_code = -exitcode; + thread->term_signal = term_signal; #ifdef PROFILE thread->exit_time = exit_time; #endif @@ -71,6 +72,7 @@ static int ipc_thread_exit (IDTYPE vmid, IDTYPE ppid, IDTYPE tid, sthread->is_alive = 0; sthread->exit_code = -exitcode; + sthread->term_signal = term_signal; #ifdef PROFILE sthread->exit_time = exit_time; #endif @@ -80,7 +82,7 @@ static int ipc_thread_exit (IDTYPE vmid, IDTYPE ppid, IDTYPE tid, } void ipc_parent_exit (struct shim_ipc_port * port, IDTYPE vmid, - unsigned int exitcode) + unsigned int exitcode, unsigned int term_signal) { debug("ipc port %p of process %u closed suggests parent exiting\n", port, vmid); @@ -103,6 +105,7 @@ void ipc_parent_exit (struct shim_ipc_port * port, IDTYPE vmid, struct thread_info { IDTYPE vmid; unsigned int exitcode; + unsigned int term_signal; }; static int child_sthread_exit (struct shim_simple_thread * thread, void * arg, @@ -112,6 +115,7 @@ static int child_sthread_exit (struct shim_simple_thread * thread, void * arg, if (thread->vmid == info->vmid) { if (thread->is_alive) { thread->exit_code = -info->exitcode; + thread->term_signal = info->term_signal; thread->is_alive = false; DkEventSet(thread->exit_event); } @@ -127,6 +131,7 @@ static int child_thread_exit (struct shim_thread * thread, void * arg, if (thread->vmid == info->vmid) { if (thread->is_alive) { thread->exit_code = -info->exitcode; + thread->term_signal = info->term_signal; thread_exit(thread, false); } return 1; @@ -134,9 +139,9 @@ static int child_thread_exit (struct shim_thread * thread, void * arg, return 0; } -int remove_child_thread (IDTYPE vmid, unsigned int exitcode) +int remove_child_thread (IDTYPE vmid, unsigned int exitcode, unsigned int term_signal) { - struct thread_info info = { .vmid = vmid, .exitcode = exitcode }; + struct thread_info info = { .vmid = vmid, .exitcode = exitcode, .term_signal = term_signal }; int nkilled = 0, ret; assert(vmid != cur_process.vmid); @@ -154,12 +159,12 @@ int remove_child_thread (IDTYPE vmid, unsigned int exitcode) } void ipc_child_exit (struct shim_ipc_port * port, IDTYPE vmid, - unsigned int exitcode) + unsigned int exitcode, unsigned int term_signal) { debug("ipc port %p of process %u closed suggests child exiting\n", port, vmid); - remove_child_thread(vmid, 0); + remove_child_thread(vmid, 0, term_signal); } static struct shim_ipc_port * get_parent_port (IDTYPE * dest) @@ -178,7 +183,7 @@ DEFINE_PROFILE_INTERVAL(ipc_cld_exit_turnaround, ipc); DEFINE_PROFILE_INTERVAL(ipc_cld_exit_send, ipc); DEFINE_PROFILE_INTERVAL(ipc_cld_exit_callback, ipc); -int ipc_cld_exit_send (IDTYPE ppid, IDTYPE tid, unsigned int exitcode) +int ipc_cld_exit_send (IDTYPE ppid, IDTYPE tid, unsigned int exitcode, unsigned int term_signal) { unsigned long send_time = GET_PROFILE_INTERVAL(); BEGIN_PROFILE_INTERVAL_SET(send_time); @@ -192,6 +197,7 @@ int ipc_cld_exit_send (IDTYPE ppid, IDTYPE tid, unsigned int exitcode) msgin->ppid = ppid; msgin->tid = tid; msgin->exitcode = exitcode; + msgin->term_signal = term_signal; #ifdef PROFILE msgin->time = send_time; #endif @@ -220,7 +226,8 @@ int ipc_cld_exit_callback (IPC_CALLBACK_ARGS) msg->src, msgin->ppid, msgin->tid, msgin->exitcode); int ret = ipc_thread_exit(msg->src, msgin->ppid, msgin->tid, - msgin->exitcode, time); + msgin->exitcode, msgin->term_signal, + time); SAVE_PROFILE_INTERVAL(ipc_cld_exit_callback); return ret; } diff --git a/LibOS/shim/src/shim_malloc.c b/LibOS/shim/src/shim_malloc.c index b3868a47..5fb0c49f 100644 --- a/LibOS/shim/src/shim_malloc.c +++ b/LibOS/shim/src/shim_malloc.c @@ -20,7 +20,27 @@ /* * shim_malloc.c * - * This file contains codes for SLAB memory allocator of library OS. + * This file implements page allocation for the library OS-internal SLAB + * memory allocator. The slab allocator is in Pal/lib/slabmgr.h. + * + * When existing slabs are not sufficient, or a large (4k or greater) + * allocation is requested, it ends up here (__system_alloc and __system_free). + * + * There are two modes this file executes in: early initialization (before + * VMAs are available), and post-initialization. + * + * Before VMAs are available, allocations are tracked in the shim_heap_areas + * array. + * + * Once VMAs initialized, the contents of shim_heap_areas are added to the VMA + * list. In order to reduce the risk of virtual address collisions, the VMA + * for the shim_heap_area is never removed, but the pages themselves are + * freed. This approach effectively reserves part of the address space for + * initialization-time bookkeeping. + * + * After initialization, all allocations and frees just call + * DkVirtualMemoryAlloc and DkVirtualMemory Free, and add/remove VMAs for the + * results. */ #include @@ -56,6 +76,8 @@ static SLAB_MGR slab_mgr = NULL; #define INIT_SHIM_HEAP 256 * allocsize +static int vmas_initialized = 0; + static struct shim_heap { void * start; void * current; @@ -126,19 +148,28 @@ static struct shim_heap * __alloc_enough_heap (size_t size) void * __system_malloc (size_t size) { size_t alloc_size = ALIGN_UP(size); - + void *addr; + lock(shim_heap_lock); - struct shim_heap * heap = __alloc_enough_heap(alloc_size); + if (vmas_initialized) { + addr = (void *) DkVirtualMemoryAlloc(NULL, alloc_size, 0, + PAL_PROT_WRITE|PAL_PROT_READ); + bkeep_mmap(addr, alloc_size, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, NULL); + } else { - if (!heap) { - unlock(shim_heap_lock); - return NULL; + struct shim_heap * heap = __alloc_enough_heap(alloc_size); + + if (!heap) { + unlock(shim_heap_lock); + return NULL; + } + + addr = heap->current; + heap->current += alloc_size; } - void * addr = heap->current; - heap->current += alloc_size; - unlock(shim_heap_lock); return addr; @@ -146,9 +177,22 @@ void * __system_malloc (size_t size) void __system_free (void * addr, size_t size) { + int in_reserved_area = 0; DkVirtualMemoryFree(addr, ALIGN_UP(size)); int flags = VMA_INTERNAL; - bkeep_munmap(addr, ALIGN_UP(size), &flags); + for (int i = 0 ; i < MAX_SHIM_HEAP_AREAS ; i++) + if (shim_heap_areas[i].start) { + /* Here we assume that any allocation from the + * shim_heap_area is a strict inclusion. Allocations + * cannot partially overlap. + */ + if (addr >= shim_heap_areas[i].start + && addr <= shim_heap_areas[i].end) + in_reserved_area = 1; + } + + if (! in_reserved_area) + bkeep_munmap(addr, ALIGN_UP(size), &flags); } int init_heap (void) @@ -172,14 +216,23 @@ int init_heap (void) int bkeep_shim_heap (void) { lock(shim_heap_lock); - + for (int i = 0 ; i < MAX_SHIM_HEAP_AREAS ; i++) - if (shim_heap_areas[i].start) + if (shim_heap_areas[i].start) { + /* Add a VMA for the active region */ bkeep_mmap(shim_heap_areas[i].start, - shim_heap_areas[i].end - shim_heap_areas[i].start, + shim_heap_areas[i].current - shim_heap_areas[i].start, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|VMA_INTERNAL, NULL, 0, NULL); - + /* Go ahead and free the reserved region */ + if (shim_heap_areas[i].current < shim_heap_areas[i].end) { + DkVirtualMemoryFree(shim_heap_areas[i].current, + ALIGN_UP(((long unsigned int) shim_heap_areas[i].end) - ((long unsigned int) shim_heap_areas[i].current))); + shim_heap_areas[i].end = shim_heap_areas[i].current; + } + } + vmas_initialized = 1; + unlock(shim_heap_lock); return 0; } diff --git a/LibOS/shim/src/shim_syscalls.c b/LibOS/shim/src/shim_syscalls.c index 5b403436..973f0798 100644 --- a/LibOS/shim/src/shim_syscalls.c +++ b/LibOS/shim/src/shim_syscalls.c @@ -197,8 +197,9 @@ void * shim_do_brk (void * brk) #endif /* rt_sigaction: sys/shim_sigaction.c */ -DEFINE_SHIM_SYSCALL (rt_sigaction, 3, shim_do_sigaction, int, int, signum, - const struct __kernel_sigaction *, act, struct __kernel_sigaction *, oldact) +DEFINE_SHIM_SYSCALL (rt_sigaction, 4, shim_do_sigaction, int, int, signum, + const struct __kernel_sigaction *, act, + struct __kernel_sigaction *, oldact, size_t, sigsetsize) /* rt_sigprocmask: sys/shim_sigaction.c */ DEFINE_SHIM_SYSCALL (rt_sigprocmask, 3, shim_do_sigprocmask, int, int, how, @@ -578,8 +579,8 @@ SHIM_SYSCALL_PASSTHROUGH (capget, 2, int, cap_user_header_t, header, SHIM_SYSCALL_PASSTHROUGH (capset, 2, int, cap_user_header_t, header, const cap_user_data_t, data) -SHIM_SYSCALL_PASSTHROUGH (rt_sigpending, 2, int, __sigset_t *, set, size_t, - sigsetsize) +DEFINE_SHIM_SYSCALL (rt_sigpending, 2, shim_do_sigpending, int, + __sigset_t *, set, size_t, sigsetsize) SHIM_SYSCALL_PASSTHROUGH (rt_sigtimedwait, 4, int, const __sigset_t *, uthese, siginfo_t *, uinfo, const struct timespec *, uts, diff --git a/LibOS/shim/src/sys/shim_brk.c b/LibOS/shim/src/sys/shim_brk.c index a3723e93..c76b29cb 100644 --- a/LibOS/shim/src/sys/shim_brk.c +++ b/LibOS/shim/src/sys/shim_brk.c @@ -59,7 +59,7 @@ void get_brk_region (void ** start, void ** end, void ** current) master_unlock(); } -int init_brk_region (void) +int init_brk_region (void * brk_region) { if (region.brk_start) return 0; @@ -73,8 +73,37 @@ int init_brk_region (void) brk_max_size = DEFAULT_BRK_MAX_SIZE; } - void * brk_region = get_unmapped_vma(brk_max_size, - MAP_PRIVATE|MAP_ANONYMOUS); + /* + * Chia-Che 8/24/2017 + * Adding an argument to specify the initial starting + * address of brk region. + * The general assumption of Linux is that the brk region + * should be within [exec-data-end, exec-data-end + 0x2000000) + */ + if (brk_region) { + while (true) { + uint32_t rand; + getrand(&rand, sizeof(rand)); + rand %= 0x2000000; + rand = ALIGN_UP(rand); + + struct shim_vma * vma; + if (lookup_overlap_vma(brk_region + rand, brk_max_size, &vma) + == -ENOENT) { + brk_region += rand; + break; + } + + brk_region = vma->addr + vma->length; + put_vma(vma); + } + } else { + brk_region = get_unmapped_vma(brk_max_size, + MAP_PRIVATE|MAP_ANONYMOUS); + if (!brk_region) + return -ENOMEM; + } + void * end_brk_region = NULL; // brk region assigned @@ -106,7 +135,7 @@ int init_brk_region (void) return 0; } -int init_brk (void) +int reset_brk (void) { master_lock(); @@ -132,7 +161,7 @@ int init_brk (void) void * shim_do_brk (void * brk) { master_lock(); - init_brk_region(); + init_brk_region(NULL); if (!brk) { unchanged: diff --git a/LibOS/shim/src/sys/shim_exec.c b/LibOS/shim/src/sys/shim_exec.c index 00247b5f..7e3d5bc6 100644 --- a/LibOS/shim/src/sys/shim_exec.c +++ b/LibOS/shim/src/sys/shim_exec.c @@ -71,6 +71,8 @@ static elf_auxv_t * new_auxp; #define REQUIRED_ELF_AUXV 6 +int init_brk_from_executable (struct shim_handle * exec); + int shim_do_execve_rtld (struct shim_handle * hdl, const char ** argv, const char ** envp) { @@ -127,13 +129,14 @@ int shim_do_execve_rtld (struct shim_handle * hdl, const char ** argv, clean_link_map_list(); SAVE_PROFILE_INTERVAL(unmap_loaded_binaries_for_exec); - init_brk(); + reset_brk(); unmap_all_vmas(); SAVE_PROFILE_INTERVAL(unmap_all_vmas_for_exec); if ((ret = load_elf_object(cur_thread->exec, NULL, 0)) < 0) shim_terminate(); + init_brk_from_executable(cur_thread->exec); load_elf_interp(cur_thread->exec); SAVE_PROFILE_INTERVAL(load_new_executable_for_exec); @@ -414,6 +417,6 @@ err: if (cur_thread->dummy) switch_dummy_thread(cur_thread); - try_process_exit(0); + try_process_exit(0, 0); return 0; } diff --git a/LibOS/shim/src/sys/shim_exit.c b/LibOS/shim/src/sys/shim_exit.c index 46eb4bbd..c886cab7 100644 --- a/LibOS/shim/src/sys/shim_exit.c +++ b/LibOS/shim/src/sys/shim_exit.c @@ -50,7 +50,7 @@ int thread_exit(struct shim_thread * self, bool send_ipc) /* Chia-Che: Broadcast exit message as early as possible, so other process can start early on responding. */ if (self->in_vm && send_ipc) - ipc_cld_exit_send(self->ppid, self->tid, self->exit_code); + ipc_cld_exit_send(self->ppid, self->tid, self->exit_code, self->term_signal); lock(self->lock); @@ -103,7 +103,7 @@ out: DkEventSet(parent->child_exit_event); } else { debug("parent not here, need to tell another process\n"); - ipc_cld_exit_send(self->ppid, self->tid, self->exit_code); + ipc_cld_exit_send(self->ppid, self->tid, self->exit_code, self->term_signal); } struct robust_list_head * robust_list = (void *) self->robust_list; @@ -127,11 +127,12 @@ out: return 0; } -int try_process_exit (int error_code) +int try_process_exit (int error_code, int term_signal) { struct shim_thread * cur_thread = get_cur_thread(); cur_thread->exit_code = -error_code; + cur_thread->term_signal = term_signal; if (cur_thread->in_vm) thread_exit(cur_thread, true); @@ -159,6 +160,7 @@ int shim_do_exit_group (int error_code) sysparser_printf("---- shim_exit_group (returning %d)\n", error_code); if (cur_thread->dummy) { + cur_thread->term_signal = 0; thread_exit(cur_thread, true); switch_dummy_thread(cur_thread); } @@ -167,7 +169,7 @@ int shim_do_exit_group (int error_code) do_kill_proc(cur_thread->tgid, cur_thread->tgid, SIGKILL, false); debug("now exit the process\n"); - try_process_exit(error_code); + try_process_exit(error_code, 0); #ifdef PROFILE if (ENTER_TIME) @@ -188,11 +190,12 @@ int shim_do_exit (int error_code) sysparser_printf("---- shim_exit (returning %d)\n", error_code); if (cur_thread->dummy) { + cur_thread->term_signal = 0; thread_exit(cur_thread, true); switch_dummy_thread(cur_thread); } - try_process_exit(error_code); + try_process_exit(error_code, 0); #ifdef PROFILE if (ENTER_TIME) diff --git a/LibOS/shim/src/sys/shim_fs.c b/LibOS/shim/src/sys/shim_fs.c index 284416bb..453dc598 100644 --- a/LibOS/shim/src/sys/shim_fs.c +++ b/LibOS/shim/src/sys/shim_fs.c @@ -58,7 +58,7 @@ int shim_do_unlink (const char * file) if (!dent->parent) return -EACCES; - if (dent->state & DENTRY_ISDIRECTORY) + if (dent->state & DENTRY_ISDIRECTORY) return -EISDIR; if (dent->fs && dent->fs->d_ops && @@ -275,9 +275,7 @@ int shim_do_chown (const char * path, uid_t uid, gid_t gid) if ((ret = path_lookupat(NULL, path, LOOKUP_OPEN, &dent)) < 0) return ret; - /* do nothing*/ - -out: + /* XXX: do nothing now */ put_dentry(dent); return ret; } @@ -300,9 +298,7 @@ int shim_do_fchownat (int dfd, const char * filename, uid_t uid, gid_t gid, if ((ret = path_lookupat(dir, filename, LOOKUP_OPEN, &dent)) < 0) goto out; - /* do nothing */ - -out_dent: + /* XXX: do nothing now */ put_dentry(dent); out: put_dentry(dir); @@ -315,14 +311,8 @@ int shim_do_fchown (int fd, uid_t uid, gid_t gid) if (!hdl) return -EBADF; - struct shim_dentry * dent = hdl->dentry; - int ret = 0; - - /* do nothing */ - -out: - put_handle(hdl); - return ret; + /* XXX: do nothing now */ + return 0; } #define MAP_SIZE (allocsize * 4) diff --git a/LibOS/shim/src/sys/shim_getrlimit.c b/LibOS/shim/src/sys/shim_getrlimit.c index 1ae8c406..aa342d46 100644 --- a/LibOS/shim/src/sys/shim_getrlimit.c +++ b/LibOS/shim/src/sys/shim_getrlimit.c @@ -55,6 +55,11 @@ int shim_do_getrlimit (int resource, struct __kernel_rlimit * rlim) rlim->rlim_max = sys_stack_size; return 0; + case RLIMIT_DATA: + rlim->rlim_cur = brk_max_size; + rlim->rlim_max = brk_max_size; + return 0; + default: return -ENOSYS; } diff --git a/LibOS/shim/src/sys/shim_open.c b/LibOS/shim/src/sys/shim_open.c index f7f29bbf..6830c564 100644 --- a/LibOS/shim/src/sys/shim_open.c +++ b/LibOS/shim/src/sys/shim_open.c @@ -321,6 +321,12 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count) goto out; } + /* DEP 3/3/17: Properly handle an unlinked directory */ + if (hdl->dentry->state & DENTRY_NEGATIVE) { + ret = -ENOENT; + goto out; + } + /* we are grabbing the lock because the handle content is actually updated */ lock(hdl->lock); @@ -370,7 +376,9 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count) while (dirhdl->ptr && *dirhdl->ptr) { dent = *dirhdl->ptr; - ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); + /* DEP 3/3/17: We need to filter negative dentries */ + if (!(dent->state & DENTRY_NEGATIVE)) + ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); put_dentry(dent); *(dirhdl->ptr++) = NULL; } @@ -380,6 +388,11 @@ size_t shim_do_getdents (int fd, struct linux_dirent * buf, size_t count) done: ret = bytes; + /* DEP 3/3/17: Properly detect EINVAL case, where buffer is too small to + * hold anything */ + if (bytes == 0 && ((dirhdl->ptr && *dirhdl->ptr) + || dirhdl->dotdot || dirhdl->dot)) + ret = -EINVAL; unlock(hdl->lock); out: put_handle(hdl); @@ -399,6 +412,12 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count) goto out; } + /* DEP 3/3/17: Properly handle an unlinked directory */ + if (hdl->dentry->state & DENTRY_NEGATIVE) { + ret = -ENOENT; + goto out; + } + lock(hdl->lock); struct shim_dir_handle * dirhdl = &hdl->info.dir; @@ -439,7 +458,9 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count) while (dirhdl->ptr && *dirhdl->ptr) { dent = *dirhdl->ptr; - ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); + /* DEP 3/3/17: We need to filter negative dentries */ + if (!(dent->state & DENTRY_NEGATIVE)) + ASSIGN_DIRENT(dent, dentry_get_name(dent), 0); put_dentry(dent); *(dirhdl->ptr++) = NULL; } @@ -449,6 +470,11 @@ size_t shim_do_getdents64 (int fd, struct linux_dirent64 * buf, size_t count) done: ret = bytes; + /* DEP 3/3/17: Properly detect EINVAL case, where buffer is too small to + * hold anything */ + if (bytes == 0 && ((dirhdl->ptr && *dirhdl->ptr) + || dirhdl->dotdot || dirhdl->dot)) + ret = -EINVAL; unlock(hdl->lock); out: put_handle(hdl); @@ -537,19 +563,15 @@ int shim_do_ftruncate (int fd, loff_t length) return -EBADF; struct shim_mount * fs = hdl->fs; - int ret = -EACCES; + int ret = -EINVAL; if (!fs || !fs->fs_ops) goto out; - if (hdl->type == TYPE_DIR) + if (hdl->type == TYPE_DIR || + !fs->fs_ops->truncate) goto out; - if (!fs->fs_ops->truncate) { - ret = -EROFS; - goto out; - } - ret = fs->fs_ops->truncate(hdl, length); out: put_handle(hdl); diff --git a/LibOS/shim/src/sys/shim_sigaction.c b/LibOS/shim/src/sys/shim_sigaction.c index aa54e6ff..9cfd8d7a 100644 --- a/LibOS/shim/src/sys/shim_sigaction.c +++ b/LibOS/shim/src/sys/shim_sigaction.c @@ -39,11 +39,12 @@ #include int shim_do_sigaction (int signum, const struct __kernel_sigaction * act, - struct __kernel_sigaction * oldact) + struct __kernel_sigaction * oldact, size_t sigsetsize) { /* SIGKILL and SIGSTOP cannot be caught or ignored */ if (signum == SIGKILL || signum == SIGSTOP || - signum <= 0 || signum > NUM_SIGS) + signum <= 0 || signum > NUM_SIGS || + sigsetsize != sizeof(__sigset_t)) return -EINVAL; struct shim_thread * cur = get_cur_thread(); @@ -145,14 +146,19 @@ int shim_do_sigaltstack (const stack_t * ss, stack_t * oss) return -EINVAL; struct shim_thread * cur = get_cur_thread(); - int err = 0; - lock(cur->lock); if (oss) *oss = cur->signal_altstack; - if (ss) + + if (ss) { + if (ss->ss_size < MINSIGSTKSZ) { + unlock(cur->lock); + return -ENOMEM; + } + cur->signal_altstack = *ss; + } unlock(cur->lock); return 0; @@ -162,7 +168,6 @@ int shim_do_sigsuspend (const __sigset_t * mask) { __sigset_t * old, tmp; struct shim_thread * cur = get_cur_thread(); - int err = 0; lock(cur->lock); @@ -174,12 +179,28 @@ int shim_do_sigsuspend (const __sigset_t * mask) cur->suspend_on_signal = true; thread_setwait(NULL, NULL); thread_sleep(NO_TIMEOUT); -out: + unlock(cur->lock); set_sig_mask(cur, old); + return -EINTR; +} - return err; +int shim_do_sigpending (__sigset_t * set, size_t sigsetsize) +{ + struct shim_thread * cur = get_cur_thread(); + __sigemptyset(set); + + if (!cur->signal_logs) + return 0; + + for (int sig = 1 ; sig <= NUM_SIGS ; sig++) { + if (atomic_read(&cur->signal_logs[sig - 1].head) != + atomic_read(&cur->signal_logs[sig - 1].tail)) + __sigaddset(set, sig); + } + + return 0; } struct walk_arg { @@ -471,7 +492,7 @@ int shim_do_kill (pid_t pid, int sig) specified by pid. */ else if (pid > 0) { ret = do_kill_proc(cur->tid, pid, sig, true); - send_to_self = (pid == cur->pgid); + send_to_self = (pid == cur->tgid); } /* If pid is less than -1, then sig is sent to every process in the diff --git a/LibOS/shim/src/sys/shim_socket.c b/LibOS/shim/src/sys/shim_socket.c index b8afeff4..ffdf8c49 100644 --- a/LibOS/shim/src/sys/shim_socket.c +++ b/LibOS/shim/src/sys/shim_socket.c @@ -951,7 +951,7 @@ int shim_do_accept (int fd, struct sockaddr * addr, socklen_t * addrlen) if (!hdl) return -EBADF; - int ret = __do_accept(hdl, flags & FD_CLOEXEC ? O_CLOEXEC : 0, + int ret = __do_accept(hdl, flags & O_CLOEXEC, addr, addrlen); put_handle(hdl); return ret; @@ -965,7 +965,7 @@ int shim_do_accept4 (int fd, struct sockaddr * addr, socklen_t * addrlen, return -EBADF; int ret = __do_accept(hdl, - (flags & SOCK_CLOEXEC ? FD_CLOEXEC : 0) | + (flags & SOCK_CLOEXEC ? O_CLOEXEC : 0) | (flags & SOCK_NONBLOCK ? O_NONBLOCK : 0), addr, addrlen); put_handle(hdl); @@ -1262,7 +1262,7 @@ int shim_do_recvmmsg (int sockfd, struct mmsghdr * msg, int vlen, int flags, struct msghdr * m = &msg[i].msg_hdr; int bytes = do_recvmsg(sockfd, m->msg_iov, m->msg_iovlen, flags, - m->msg_name, m->msg_namelen); + m->msg_name, &m->msg_namelen); if (bytes < 0) return total ? : bytes; diff --git a/LibOS/shim/src/sys/shim_wait.c b/LibOS/shim/src/sys/shim_wait.c index 49856360..35c51357 100644 --- a/LibOS/shim/src/sys/shim_wait.c +++ b/LibOS/shim/src/sys/shim_wait.c @@ -137,8 +137,12 @@ found_child: unlock(cur->lock); found: - if (status) - *status = (thread->exit_code & 0xff) << 8; + if (status) { + /* Bits 0--7 are for the signal, if any. + * Bits 8--15 are for the exit code */ + *status = thread->term_signal; + *status |= ((thread->exit_code & 0xff) << 8); + } ret = thread->tid; SAVE_PROFILE_INTERVAL_SINCE(child_exit_notification, thread->exit_time); diff --git a/LibOS/shim/test/.gitignore b/LibOS/shim/test/.gitignore new file mode 100644 index 00000000..6e6a284b --- /dev/null +++ b/LibOS/shim/test/.gitignore @@ -0,0 +1,6 @@ +*.manifest +*.manifest.sgx +*.sig +*.token +*.cached +pal_loader diff --git a/LibOS/shim/test/apps/apache/Makefile b/LibOS/shim/test/apps/apache/Makefile index dc67276e..b8dd6393 100644 --- a/LibOS/shim/test/apps/apache/Makefile +++ b/LibOS/shim/test/apps/apache/Makefile @@ -74,7 +74,7 @@ build-modules: $(INSTALL_DIR)/modules/mod_auth_basic_sandbox.so $(INSTALL_DIR)/modules/mod_auth_basic_sandbox.so: mod_auth_basic_sandbox.c $(INSTALL_DIR)/bin/apxs $(INSTALL_DIR)/bin/apxs $(APXS_FLAGS) \ -S CFLAGS="-I$(SHIMDIR)/../include" \ - -S LDFLAGS="-L$(LIBCDIR)/libos -llibos" -c -i -A $< + -S LDFLAGS="-L. -l:$(RUNTIME)/liblibos.so.1" -c -i -A $< build-conf: [ -f $(INSTALL_DIR)/conf/httpd.conf.old ] || \ diff --git a/LibOS/shim/test/apps/apache/benchmark-ab.sh b/LibOS/shim/test/apps/apache/benchmark-ab.sh new file mode 100755 index 00000000..e108bb66 --- /dev/null +++ b/LibOS/shim/test/apps/apache/benchmark-ab.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +declare -A THROUGHPUTS +declare -A LATENCIES +LOOP=5 +DOWNLOAD_HOST=$1 +DOWNLOAD_FILE=random/10K.1.html +REQUESTS=10000 +CONCURRENCY_LIST="1 2 4 8 16 32 64 128 256" +RESULT=result-$(date +%y%m%d-%H%M%S) + +touch $RESULT + +RUN=0 +while [ $RUN -lt $LOOP ] +do + for CONCURRENCY in $CONCURRENCY_LIST + do + rm -f OUTPUT + echo "ab -n $REQUESTS -c $CONCURRENCY http://$DOWNLOAD_HOST/$DOWNLOAD_FILE" + ab -n $REQUESTS -c $CONCURRENCY http://$DOWNLOAD_HOST/$DOWNLOAD_FILE > OUTPUT + + sleep 5 + + THROUGHPUT=$(grep -m1 "Requests per second:" OUTPUT | awk '{ print $4 }') + LATENCY=$(grep -m1 "Time per request:" OUTPUT | awk '{ print $4 }') + THROUGHPUTS[$CONCURRENCY]="${THROUGHPUTS[$CONCURRENCY]} $THROUGHPUT" + LATENCIES[$CONCURRENCY]="${LATENCIES[$CONCURRENCY]} $LATENCY" + echo "concurrency=$CONCURRENCY, throughput=$THROUGHPUT, latency=$LATENCY" + done + RUN=$(expr $RUN + 1) +done + +for CONCURRENCY in $CONCURRENCY_LIST +do + THROUGHPUT=$(echo ${THROUGHPUTS[$CONCURRENCY]} | tr " " "\n" | sort -n | awk '{a[NR]=$0}END{if(NR%2==1)print a[int(NR/2)+1];else print(a[NR/2-1]+a[NR/2])/2}') + LATENCY=$(echo ${LATENCIES[$CONCURRENCY]} | tr " " "\n" | sort -n | awk '{a[NR]=$0}END{if(NR%2==1)print a[int(NR/2)+1];else print(a[NR/2-1]+a[NR/2])/2}') + echo "$THROUGHPUT,$LATENCY" >> $RESULT +done + +echo "Result file: $RESULT" diff --git a/LibOS/shim/test/apps/apache/httpd.manifest.template b/LibOS/shim/test/apps/apache/httpd.manifest.template index 3a990e5f..4d5fec71 100644 --- a/LibOS/shim/test/apps/apache/httpd.manifest.template +++ b/LibOS/shim/test/apps/apache/httpd.manifest.template @@ -44,6 +44,10 @@ sgx.trusted_files.libxml2 = file:/usr/lib/x86_64-linux-gnu/libxml2.so.2 sgx.trusted_files.libz = file:/lib/x86_64-linux-gnu/libz.so.1 sgx.trusted_files.liblzma = file:/lib/x86_64-linux-gnu/liblzma.so.5 sgx.trusted_files.libnsl = file:/lib/x86_64-linux-gnu/libnsl.so.1 +sgx.trusted_files.libicuuc = file:/usr/lib/x86_64-linux-gnu/libicuuc.so.55 +sgx.trusted_files.libicudata = file:/usr/lib/x86_64-linux-gnu/libicudata.so.55 +sgx.trusted_files.libstdcpp = file:/usr/lib/x86_64-linux-gnu/libstdc++.so.6 +sgx.trusted_files.libgcc_c = file:/lib/x86_64-linux-gnu/libgcc_s.so.1 sgx.allowed_files.modules = file:obj/modules sgx.allowed_files.conf = file:obj/conf diff --git a/LibOS/shim/test/apps/gcc/Makefile b/LibOS/shim/test/apps/gcc/Makefile index 2496137c..fa2de1d0 100644 --- a/LibOS/shim/test/apps/gcc/Makefile +++ b/LibOS/shim/test/apps/gcc/Makefile @@ -90,6 +90,33 @@ obj/lib/$(MPC_OBJ): src/$(MPC_SRC) src/$(MPC_SRC): $(MPC_SRC).tar.gz src cd src && tar -xzf ../$< +regression: + @echo "\n\nBuilding GCC..." + @$(MAKE) >> /dev/null 2>&1 + + @echo "\n\nCompile hello.c:" + ./gcc.manifest test_files/helloworld.c -o hello + @chmod 755 hello + ./hello + + @echo "\n\nCompile bzip2.c:" + ./gcc.manifest test_files/bzip2.c -o bzip2 + @chmod 755 bzip2 + @[ ! -f bzip2.tmp ] || rm -f bzip2.tmp + @cp -f bzip2 bzip2.copy + ./bzip2 -z bzip2.copy && ./bzip2 -d bzip2.copy.bz2 + diff -q bzip2 bzip2.copy + @rm -f bzip2.copy + + @echo "\n\nCompile gzip.c:" + ./gcc.manifest test_files/gzip.c -o gzip + @chmod 755 gzip + @cp -f gzip gzip.copy + ./gzip gzip.copy && ./gzip -d gzip.copy.gz + diff -q gzip gzip.copy + @rm -f gzip.copy + + src: mkdir -p src diff --git a/LibOS/shim/test/apps/lmbench/Makefile b/LibOS/shim/test/apps/lmbench/Makefile index c3e08fc5..3a8607ec 100644 --- a/LibOS/shim/test/apps/lmbench/Makefile +++ b/LibOS/shim/test/apps/lmbench/Makefile @@ -66,5 +66,11 @@ test-graphene: all $(lmbench_config) env LOADER=./pal_loader OS=linux RESULTS=results/graphene \ ./results +regression: all + cp -f lmbench-regression $(LMBENCHDIR)/bin/linux + cd $(LMBENCHDIR)/bin/linux && \ + env LOADER=./pal_loader OS=linux \ + ./lmbench-regression + clean-lmbench: $(MAKE) -C $(LMBENCHDIR) clean diff --git a/LibOS/shim/test/apps/lmbench/lmbench-regression b/LibOS/shim/test/apps/lmbench/lmbench-regression new file mode 100755 index 00000000..0c0a76e7 --- /dev/null +++ b/LibOS/shim/test/apps/lmbench/lmbench-regression @@ -0,0 +1,222 @@ +#!/bin/bash + +# lmbench - run the lmbench benchmark suite. +# +# Hacked by Larry McVoy (lm@sun.com, lm@sgi.com, lm@bitmover.com). +# Copyright (c) 1994 Larry McVoy. GPLed software. +# $Id$ + +# Make sure we can find: ./cmd, df, and netstat +PATH=.:../../scripts:$PATH:/etc:/usr/etc:/sbin:/usr/sbin +export PATH + +echo PATH = $PATH +echo lat_syscall = `readlink -f lat_syscall` + +# lat_unix, lat_udp, lat_tcp only do one run!!! +# we loop to repeat the tests +N_RUNS=6 + +if [ -f $1 ] +then . $1 + echo Using config in $1 +else echo Using defaults + ENOUGH=1000000 + TIMING_O=0 + LOOP_O=0 +fi +export ENOUGH TIMING_O LOOP_O + +if [ X$FILE = X ] +then FILE=/tmp/XXX + touch $FILE || echo Can not create $FILE +fi +if [ X$MB = X ] +then MB=8 +fi +AVAILKB=`expr $MB \* 1024` + +# Figure out how big we can go for stuff that wants to use +# all and half of memory. +HALF="512 1k 2k 4k 8k 16k 32k 64k 128k 256k 512k 1m" +ALL="$HALF 2m" +i=4 +while [ $i -le $MB ] +do + ALL="$ALL ${i}m" + h=`expr $i / 2` + HALF="$HALF ${h}m" + i=`expr $i \* 2` +done + + +if [ X$FSDIR = X ] +then FSDIR=/tmp/lat_fs +fi +MP=N + +# Figure out as much stuff as we can about this system. +# Sure would be nice if everyone had SGI's "hinv". +echo \[lmbench2.0 results for `uname -a`] 1>&2 +echo \[ALL: ${ALL}] 1>&2 +echo \[DISKS: ${DISKS}] 1>&2 +echo \[DISK_DESC: ${DISK_DESC}] 1>&2 +echo \[ENOUGH: ${ENOUGH}] 1>&2 +echo \[FAST: ${FAST}] 1>&2 +echo \[FASTMEM: ${FASTMEM}] 1>&2 +echo \[FILE: ${FILE}] 1>&2 +echo \[FSDIR: ${FSDIR}] 1>&2 +echo \[HALF: ${HALF}] 1>&2 +echo \[INFO: ${INFO}] 1>&2 +echo \[LOOP_O: ${LOOP_O}] 1>&2 +echo \[MB: ${MB}] 1>&2 +echo \[MHZ: ${MHZ}] 1>&2 +echo \[MOTHERBOARD: ${MOTHERBOARD}] 1>&2 +echo \[NETrunS: ${NETrunS}] 1>&2 +echo \[PROCESSORS: ${PROCESSORS}] 1>&2 +echo \[REMOTE: ${REMOTE}] 1>&2 +echo \[SLOWFS: ${SLOWFS}] 1>&2 +echo \[OS: ${OS}] 1>&2 +echo \[TIMING_O: ${TIMING_O}] 1>&2 +echo \[LMBENCH VERSION: ${VERSION}] 1>&2 +echo \[USER: $USER] 1>&2 +echo \[HOSTNAME: `hostname`] 1>&2 +echo \[NODENAME: `uname -n`] 1>&2 +echo \[SYSNAME: `uname -s`] 1>&2 +echo \[PROCESSOR: `uname -p`] 1>&2 +echo \[MACHINE: `uname -m`] 1>&2 +echo \[RELEASE: `uname -r`] 1>&2 +echo \[VERSION: `uname -v`] 1>&2 +#if 0 +echo \[`date`] 1>&2 +echo \[`uptime`] 1>&2 +netstat -i | while read i +do echo \[net: "$i"] 1>&2 + set `echo $i` + case $1 in + *ame) ;; + *) ifconfig $1 | while read i + do echo \[if: "$i"] 1>&2 + done + ;; + esac +done + +mount | while read i +do echo \[mount: "$i"] 1>&2 +done + +STAT=$FSDIR/lmbench +mkdir $FSDIR 2>/dev/null +touch $STAT 2>/dev/null +if [ ! -f $STAT ] +then echo "Can't make a file - $STAT - in $FSDIR" + touch $STAT + exit 1 +fi + +function run { + echo "$@" + TMPOUT=/tmp/OUT + rm -rf $TMPOUT + $LOADER "$@" 2>>$TMPOUT | tee -a $TMPOUT + cat $TMPOUT 1>&2 +} + +date +echo Latency measurements +msleep 250 +run lat_syscall null +run lat_syscall read +run lat_syscall write +run lat_syscall stat $STAT +run lat_syscall fstat $STAT +run lat_syscall open $STAT + +#select file (500), select tcp (500) +run lat_select file 500 +run lat_select tcp 500 + +#sig install, sig_overhead, prot. Fault +run lat_sig install +run lat_sig catch +run lat_sig prot lat_sig + +#AF_UNIX +echo AF_UNIX socket latency +for i in $(eval echo "{1..$N_RUNS}") +do run lat_unix +done + +#forks +cp hello /tmp/hello +for i in fork dfork vfork exec dforkexec shell +do run lat_proc $i +done +rm -f /tmp/hello + +for i in $(eval echo "{1..$N_RUNS}") +do rm -f $FILE + run lmdd label="File $FILE write bandwidth:" of=$FILE move=${MB}m fsync=1 print=3 +done + +#0,4,10KB create/delete +date + echo Calculating file system latency + echo '"File system latency' 1>&2 + run lat_fs $FSDIR + echo "" 1>&2 + +date +echo Local netruning + +echo UDP socket latency +run lat_udp -s & +sleep 3 +for i in $(eval echo "{1..$N_RUNS}") +do run lat_udp 127.0.0.1 + sleep 1 +done +run lat_udp -127.0.0.1 +sleep 3 + +echo TCP socket latency +run lat_tcp -s & +sleep 3 +for i in $(eval echo "{1..$N_RUNS}") +do run lat_tcp 127.0.0.1 + sleep 1 +done +run lat_tcp -127.0.0.1 +sleep 3 + +echo TCP connect latency +run lat_connect -s & +sleep 3 +run lat_connect 127.0.0.1 +sleep 1 +run lat_connect -127.0.0.1 +sleep 3 + +echo TCP socket bandwidth +run bw_tcp -s & +sleep 3 +for i in $(eval echo "{1..$N_RUNS}") +do run bw_tcp 127.0.0.1 + sleep 1 +done +run bw_tcp -127.0.0.1 +sleep 3 + +date +echo Bandwidth measurements + +for i in $(eval echo "{1..$N_RUNS}") +do run bw_unix +done + +for i in $(eval echo "{1..$N_RUNS}") +do run bw_pipe +done + +exit 0 diff --git a/LibOS/shim/test/apps/lmbench/manifest.template b/LibOS/shim/test/apps/lmbench/manifest.template index 9b76ac65..d4556146 100644 --- a/LibOS/shim/test/apps/lmbench/manifest.template +++ b/LibOS/shim/test/apps/lmbench/manifest.template @@ -40,11 +40,5 @@ sgx.allowed_files.tmp1 = file:/tmp sgx.allowed_files.tmp2 = file:/var/tmp sgx.allowed_files.inc = file:/usr/include/x86_64-linux-gnu/sys/types.h -sgx.trusted_files.test1 = file:random.64K -sgx.trusted_files.test2 = file:random.256K -sgx.trusted_files.test3 = file:random.1M -sgx.trusted_files.test4 = file:random.4M -sgx.trusted_files.test5 = file:random.16M - sgx.trusted_children.hello = file:hello.sig sgx.trusted_children.sh = file:sh.sig diff --git a/LibOS/shim/test/apps/ltp/Makefile b/LibOS/shim/test/apps/ltp/Makefile index 1799c44a..e979cf47 100644 --- a/LibOS/shim/test/apps/ltp/Makefile +++ b/LibOS/shim/test/apps/ltp/Makefile @@ -1,4 +1,6 @@ -SRCDIR = ltp-master +SRCURL = https://github.com/linux-test-project/ltp/releases/download/ +SRCVERSION = 20170116 +SRCDIR = ltp-full-$(SRCVERSION) BUILDDIR = opt/ltp TESTCASEDIR = $(BUILDDIR)/testcases/bin @@ -10,11 +12,11 @@ clean-extra = clean-build level = ../../ include ../../Makefile -master.zip: - wget https://github.com/linux-test-project/ltp/archive/master.zip +$(SRCDIR).tar.xz: + wget $(SRCURL)/$(SRCVERSION)/$@ -$(SRCDIR)/configure: master.zip - unzip master.zip +$(SRCDIR)/configure: $(SRCDIR).tar.xz + tar -xJf $< cd $(SRCDIR) && make autotools $(BUILDDIR)/runltp: $(SRCDIR)/configure @@ -38,5 +40,12 @@ $(TESTCASEDIR)/manifest.template: manifest.template $(TESTCASEDIR)/Makefile: Makefile.testcases ln -sf ../../../../$< $@ +regression: + @echo "\n\nBuilding LTP..." + @$(MAKE) >> /dev/null 2>&1 + + @echo "\n\nLTP tests for system calls:" + ./syscalls.sh + clean-build: rm -rf $(BUILDDIR) diff --git a/LibOS/shim/test/apps/ltp/Makefile.testcases b/LibOS/shim/test/apps/ltp/Makefile.testcases index 459a2add..5c3c4d09 100644 --- a/LibOS/shim/test/apps/ltp/Makefile.testcases +++ b/LibOS/shim/test/apps/ltp/Makefile.testcases @@ -2,10 +2,18 @@ manifests = $(wildcard ../../../../*.manifest.template) manifest testcases = $(filter-out $(wildcard *.*) $(patsubst %/,%,$(wildcard */)) Makefile manifest pal_loader,$(wildcard *)) exec_target = $(testcases) -target = $(manifests) $(testcases) +target = $(manifests) $(testcases) etc/nsswitch.conf etc/passwd level = ../../../../../../ include ../../../../../../Makefile $(addsuffix .template,$(manifests)): %: ../../../../% ln -sf $< $@ + +etc/nsswitch.conf: + mkdir -p etc + echo "passwd: compat\ngroup: compat\nshadow: compat\nhosts: files" > $@ + +etc/passwd: + mkdir -p etc + echo "root:x:0:0:root:/root:/bin/bash\nnobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin" > $@ diff --git a/LibOS/shim/test/apps/ltp/PASSED b/LibOS/shim/test/apps/ltp/PASSED index 3905db95..5ce5794b 100644 --- a/LibOS/shim/test/apps/ltp/PASSED +++ b/LibOS/shim/test/apps/ltp/PASSED @@ -1,6 +1,10 @@ Test,Subtest number accept01,1 accept01,2 +accept4_01,1 +accept4_01,2 +accept4_01,3 +accept4_01,4 alarm01,1 alarm02,1 alarm02,2 @@ -11,20 +15,46 @@ asyncio02,3 asyncio02,4 asyncio02,5 asyncio02,6 +brk01,1 chmod01,1 +chmod01,2 +chmod01,3 +chmod01,4 +chmod01,5 +chmod01,6 +chmod01,7 +chmod01,8 chmod02,1 +chmod02,2 +chmod02,3 +chmod02,4 +chmod02,5 +chmod02,6 +chmod02,7 +chmod02,8 +chmod03,1 chown01,1 chroot02,1 -close01,1 -close01,2 -close08,1 +clock_getres01,3 +clock_getres01,4 +clock_getres01,5 +clock_getres01,6 +clock_getres01,8 +clock_getres01,9 +clock_getres01,10 +clock_getres01,11 +clock_getres01,12 +clock_getres01,13 +clock_nanosleep01,12 clone01,1 clone03,1 clone04,1 -clone05,1 clone06,1 clone07,1 +close01,1 +close01,2 close02,1 +close08,1 confstr01,1 confstr01,2 confstr01,3 @@ -44,6 +74,13 @@ confstr01,16 confstr01,17 confstr01,18 confstr01,19 +creat01,3 +creat01,4 +creat01,5 +creat01,6 +creat01,7 +creat01,8 +creat03,4 dup01,1 dup02,1 dup02,2 @@ -55,8 +92,23 @@ dup203,1 dup203,2 dup204,1 dup204,2 +epoll_create1_01,3 +epoll_ctl01,3 +epoll_ctl01,5 +epoll_ctl02,3 +epoll_ctl02,4 +epoll_ctl02,7 +epoll_ctl02,8 +epoll_ctl02,9 epoll_wait03,1 epoll_wait03,2 +execl01,1 +execlp01,1 +execv01,1 +execvp01,1 +exit01,1 +exit02,1 +exit_group01,1 faccessat01,1 faccessat01,2 faccessat01,3 @@ -67,6 +119,13 @@ fchdir01,1 fchdir02,1 fchmod01,1 fchmod07,1 +fchmod07,2 +fchmod07,3 +fchmod07,4 +fchmod07,5 +fchmod07,6 +fchmod07,7 +fchmod07,8 fchmodat01,1 fchmodat01,2 fchmodat01,3 @@ -75,13 +134,28 @@ fchmodat01,5 fchmodat01,6 fchown01,1 fchown02,4 +fcntl02,1 +fcntl02_64,1 +fcntl03,1 +fcntl03_64,1 +fcntl04,1 +fcntl04_64,1 fcntl08,1 +fcntl08_64,1 fcntl13,6 +fcntl13_64,6 fcntl27,1 +fcntl27_64,1 fcntl28,1 +fcntl28_64,1 fdatasync01,1 fdatasync02,1 flock06,2 +fmtmsg01,1 +fmtmsg01,2 +fmtmsg01,3 +fmtmsg01,4 +fmtmsg01,5 fork01,1 fork01,2 fork02,1 @@ -100,15 +174,20 @@ fpathconf01,7 fpathconf01,8 fpathconf01,9 fstat01,1 +fstat01_64,1 fstat03,1 -fstat05,1 +fstat03_64,1 fsync01,1 fsync03,1 ftruncate01,1 ftruncate01_64,1 ftruncate02,1 ftruncate02_64,1 +ftruncate03,1 +ftruncate03,2 ftruncate03,3 +ftruncate03_64,1 +ftruncate03_64,2 ftruncate03_64,3 futex_wait01,1 futex_wait01,2 @@ -117,23 +196,27 @@ futex_wait01,4 futex_wait03,1 futex_wait04,1 futex_wait05,1 +futex_wait_bitset01,1 +futex_wait_bitset02,1 futex_wake01,1 futex_wake01,2 futex_wake01,3 futex_wake01,4 futex_wake01,5 futex_wake01,6 -futex_wait_bitset01,1 -futex_wait_bitset02,1 getcontext01,1 getdents02,1 getdents02,2 getdents02,3 +getdents02,4 getdomainname01,1 getdtablesize01,1 getegid01,1 +getegid02,1 geteuid01,1 +geteuid02,1 getgid01,1 +getgid03,1 gethostbyname_r01,1 gethostname01,1 getitimer01,1 @@ -148,6 +231,7 @@ getpgrp01,1 getpid01,1 getpid02,1 getppid01,1 +getrlimit01,3 getrlimit01,4 getrlimit01,6 getrlimit01,8 @@ -157,6 +241,8 @@ getsockopt01,1 getsockopt01,2 gettid01,1 getuid01,1 +getuid03,1 +kill01,1 kill03,1 kill09,1 listen01,1 @@ -183,13 +269,13 @@ mallopt01,3 mallopt01,4 mallopt01,5 mallopt01,6 -memset01,1 -memset01,2 memcmp01,1 memcmp01,2 memcpy01,1 memcpy01,2 memcpy01,3 +memset01,1 +memset01,2 mkdir08,1 mlock03,1 mmap001,1 @@ -203,14 +289,21 @@ mmap08,1 mmap09,1 mmap09,2 mmap09,3 +mmap13,1 +mprotect01,3 mprotect02,1 mprotect02,2 mprotect03,1 mprotect04,1 mprotect04,2 msgrcv01,1 +msgsnd02,2 +msgsnd03,3 +msgsnd03,4 +msgsnd04,1 munmap01,1 munmap02,1 +nanosleep01,1 nanosleep03,1 newuname01,1 open03,1 @@ -224,16 +317,65 @@ pathconf01,5 pathconf01,6 pathconf01,7 personality02,1 +pipe01,3 pipe09,1 pipe10,1 pipe2_01,1 poll01,1 poll01,2 +poll02,1 pread01,1 +pread01_64,1 pread02,1 -ptrace05,1 +pread02_64,1 +preadv01,3 +preadv01,4 +preadv01,5 +preadv01_64,3 +preadv01_64,4 +preadv01_64,5 +preadv02,3 +preadv02_64,3 +process_vm01,2 +process_vm01,4 +process_vm01,6 +process_vm01,8 +process_vm01,11 +process_vm01,13 +process_vm01,15 +process_vm01,17 +process_vm01,19 +process_vm01,21 +pselect01,1 +pselect01,2 +pselect01,3 +pselect01,4 +pselect01,5 +pselect01,6 +pselect01,7 +pselect01,8 +pselect01,9 +pselect01_64,1 +pselect01_64,2 +pselect01_64,3 +pselect01_64,4 +pselect01_64,5 +pselect01_64,6 +pselect01_64,7 +pselect01_64,8 +pselect01_64,9 pwrite01,1 +pwrite01_64,1 pwrite04,2 +pwrite04_64,2 +pwritev01,3 +pwritev01,4 +pwritev01,5 +pwritev01_64,3 +pwritev01_64,4 +pwritev01_64,5 +pwritev02,3 +pwritev02_64,3 read01,1 read04,1 readdir01,1 @@ -396,6 +538,162 @@ rt_sigaction01,152 rt_sigaction01,153 rt_sigaction01,154 rt_sigaction01,155 +rt_sigaction03,1 +rt_sigaction03,2 +rt_sigaction03,3 +rt_sigaction03,4 +rt_sigaction03,5 +rt_sigaction03,6 +rt_sigaction03,7 +rt_sigaction03,8 +rt_sigaction03,9 +rt_sigaction03,10 +rt_sigaction03,11 +rt_sigaction03,12 +rt_sigaction03,13 +rt_sigaction03,14 +rt_sigaction03,15 +rt_sigaction03,16 +rt_sigaction03,17 +rt_sigaction03,18 +rt_sigaction03,19 +rt_sigaction03,20 +rt_sigaction03,21 +rt_sigaction03,22 +rt_sigaction03,23 +rt_sigaction03,24 +rt_sigaction03,25 +rt_sigaction03,26 +rt_sigaction03,27 +rt_sigaction03,28 +rt_sigaction03,29 +rt_sigaction03,30 +rt_sigaction03,31 +rt_sigaction03,32 +rt_sigaction03,33 +rt_sigaction03,34 +rt_sigaction03,35 +rt_sigaction03,36 +rt_sigaction03,37 +rt_sigaction03,38 +rt_sigaction03,39 +rt_sigaction03,40 +rt_sigaction03,41 +rt_sigaction03,42 +rt_sigaction03,43 +rt_sigaction03,44 +rt_sigaction03,45 +rt_sigaction03,46 +rt_sigaction03,47 +rt_sigaction03,48 +rt_sigaction03,49 +rt_sigaction03,50 +rt_sigaction03,51 +rt_sigaction03,52 +rt_sigaction03,53 +rt_sigaction03,54 +rt_sigaction03,55 +rt_sigaction03,56 +rt_sigaction03,57 +rt_sigaction03,58 +rt_sigaction03,59 +rt_sigaction03,60 +rt_sigaction03,61 +rt_sigaction03,62 +rt_sigaction03,63 +rt_sigaction03,64 +rt_sigaction03,65 +rt_sigaction03,66 +rt_sigaction03,67 +rt_sigaction03,68 +rt_sigaction03,69 +rt_sigaction03,70 +rt_sigaction03,71 +rt_sigaction03,72 +rt_sigaction03,73 +rt_sigaction03,74 +rt_sigaction03,75 +rt_sigaction03,76 +rt_sigaction03,77 +rt_sigaction03,78 +rt_sigaction03,79 +rt_sigaction03,80 +rt_sigaction03,81 +rt_sigaction03,82 +rt_sigaction03,83 +rt_sigaction03,84 +rt_sigaction03,85 +rt_sigaction03,86 +rt_sigaction03,87 +rt_sigaction03,88 +rt_sigaction03,89 +rt_sigaction03,90 +rt_sigaction03,91 +rt_sigaction03,92 +rt_sigaction03,93 +rt_sigaction03,94 +rt_sigaction03,95 +rt_sigaction03,96 +rt_sigaction03,97 +rt_sigaction03,98 +rt_sigaction03,99 +rt_sigaction03,100 +rt_sigaction03,101 +rt_sigaction03,102 +rt_sigaction03,103 +rt_sigaction03,104 +rt_sigaction03,105 +rt_sigaction03,106 +rt_sigaction03,107 +rt_sigaction03,108 +rt_sigaction03,109 +rt_sigaction03,110 +rt_sigaction03,111 +rt_sigaction03,112 +rt_sigaction03,113 +rt_sigaction03,114 +rt_sigaction03,115 +rt_sigaction03,116 +rt_sigaction03,117 +rt_sigaction03,118 +rt_sigaction03,119 +rt_sigaction03,120 +rt_sigaction03,121 +rt_sigaction03,122 +rt_sigaction03,123 +rt_sigaction03,124 +rt_sigaction03,125 +rt_sigaction03,126 +rt_sigaction03,127 +rt_sigaction03,128 +rt_sigaction03,129 +rt_sigaction03,130 +rt_sigaction03,131 +rt_sigaction03,132 +rt_sigaction03,133 +rt_sigaction03,134 +rt_sigaction03,135 +rt_sigaction03,136 +rt_sigaction03,137 +rt_sigaction03,138 +rt_sigaction03,139 +rt_sigaction03,140 +rt_sigaction03,141 +rt_sigaction03,142 +rt_sigaction03,143 +rt_sigaction03,144 +rt_sigaction03,145 +rt_sigaction03,146 +rt_sigaction03,147 +rt_sigaction03,148 +rt_sigaction03,149 +rt_sigaction03,150 +rt_sigaction03,151 +rt_sigaction03,152 +rt_sigaction03,153 +rt_sigaction03,154 +rt_sigaction03,155 +rt_sigsuspend01,1 sbrk01,1 sbrk01,2 sbrk02,1 @@ -407,6 +705,7 @@ select02,1 semctl01,2 semctl01,3 semctl07,4 +semget02,2 semget03,1 semop01,1 semop04,1 @@ -419,7 +718,6 @@ sendfile03_64,2 sendfile03_64,3 sendfile05,1 sendfile05_64,1 -set_tid_address01,1 setgid01,1 setitimer01,1 setpgid01,1 @@ -429,6 +727,7 @@ setpgrp02,1 setrlimit01,1 setsockopt01,1 setsockopt01,2 +set_tid_address01,1 settimeofday01,3 setuid01,1 setuid02,1 @@ -436,6 +735,9 @@ sigaction01,4 sigaction02,1 sigaction02,2 sigaction02,3 +sigaltstack01,1 +sigaltstack02,1 +sigaltstack02,2 signal02,1 signal02,2 signal02,3 @@ -534,15 +836,30 @@ signal06,2 signal06,3 signal06,4 signal06,5 +sigprocmask01,1 +sigsuspend01,1 +socket01,10 +socket01,5 +socket01,7 +socket02,3 +socket02,4 +socket02,5 +socket02,6 socketcall02,1 socketcall03,1 socketcall04,1 +socketpair02,3 sockioctl01,1 -splice02,1 +stat02,1 +stat02_64,1 stat05,1 +stat05_64,1 string01,1 sync01,1 sync02,1 +syscall01,3 +syscall01,4 +syscall01,5 sysconf01,1 sysconf01,2 sysconf01,4 @@ -596,8 +913,6 @@ tkill01,1 tkill01,2 truncate01,1 truncate01_64,1 -umask01,1 -umask02,1 uname01,1 uname03,1 unlink05,1 @@ -608,28 +923,42 @@ unlinkat01,4 unlinkat01,6 unlinkat01,7 ustat02,1 +vfork02,1 wait01,1 wait02,1 wait401,1 wait401,2 waitpid01,1 +waitpid01,2 waitpid02,1 +waitpid02,2 waitpid02,3 waitpid03,1 waitpid03,2 waitpid05,1 -waitpid05,11 -waitpid05,14 -waitpid05,18 -waitpid05,22 -waitpid05,26 +waitpid05,2 waitpid05,3 -waitpid05,30 -waitpid05,34 -waitpid05,37 waitpid05,4 -waitpid05,40 +waitpid05,5 waitpid05,7 +waitpid05,8 +waitpid05,10 +waitpid05,11 +waitpid05,13 +waitpid05,14 +waitpid05,16 +waitpid05,17 +waitpid05,19 +waitpid05,20 +waitpid05,21 +waitpid05,22 +waitpid05,24 +waitpid05,25 +waitpid05,26 +waitpid05,27 +waitpid05,28 +waitpid05,29 +waitpid05,30 write01,1 write02,1 write03,1 diff --git a/LibOS/shim/test/apps/ltp/TIMEOUTS b/LibOS/shim/test/apps/ltp/TIMEOUTS index 03c9ab1d..b315bcbd 100644 --- a/LibOS/shim/test/apps/ltp/TIMEOUTS +++ b/LibOS/shim/test/apps/ltp/TIMEOUTS @@ -1,4 +1,5 @@ testcase,timeout clone05,30 alarm01,5 -alarm06,16 +alarm06,16 +waitpid05,160 diff --git a/LibOS/shim/test/apps/ltp/edit_sys_tests.awk b/LibOS/shim/test/apps/ltp/edit_sys_tests.awk index 448f6952..d0cdddbf 100644 --- a/LibOS/shim/test/apps/ltp/edit_sys_tests.awk +++ b/LibOS/shim/test/apps/ltp/edit_sys_tests.awk @@ -4,22 +4,29 @@ BEGIN{ test = $1$2$3 blocked[test] } + + if (SGX) { + pal_str = "./pal_loader SGX" + } else { + pal_str = "./pal_loader" + } } + NF && ! /^#/ { test = $2$3 if($1=="splice02") { - s = "./pal_loader" + s = pal_str for (i=2; i<=NF; i++) { s = s " " $i if($i=="|") { i++ - s = s " ./pal_loader " $i + s = s " " pal_str " " $i } } print s } else if(! (test in blocked)) { - s = "./pal_loader" + s = pal_str for (i=2; i<=NF; i++) { s = s " " $i } diff --git a/LibOS/shim/test/apps/ltp/fetch.py b/LibOS/shim/test/apps/ltp/fetch.py index 53e3d293..fe6afa6e 100644 --- a/LibOS/shim/test/apps/ltp/fetch.py +++ b/LibOS/shim/test/apps/ltp/fetch.py @@ -1,80 +1,92 @@ import subprocess import csv import os -import threading import time import signal import tempfile +import multiprocessing -class RunCmd(threading.Thread): - def __init__(self, cmd, timeout, test): - threading.Thread.__init__(self) - self.cmd = cmd - self.timeout = int(timeout)*100 - self.output = "" - self.test = test - self.test_subtest = test - - def run(self): - name = tempfile.NamedTemporaryFile(mode='w+b') - self.p = subprocess.Popen(self.cmd, shell=True, stdout=name, stderr=subprocess.STDOUT, preexec_fn=os.setsid, close_fds=True) - self.curtime = time.time() - self.endtime = self.curtime + self.timeout - needed_times = self.timeout +def run(cmd, timeout, test): + try: + timeout = timeout * 100 + result = {} + result['test'] = test + outfile = tempfile.NamedTemporaryFile(mode='w+b') + p = subprocess.Popen(cmd, shell=True, stdout=outfile, stderr=subprocess.STDOUT, preexec_fn=os.setsid, close_fds=True) + result['curtime'] = time.time() + result['endtime'] = result['curtime'] + timeout sleep_time = 0 finish = False - while sleep_time < self.timeout: - if self.p.poll() is not None: + while sleep_time < timeout: + if p.poll() is not None: finish = True break sleep_time += 1 time.sleep(.01) - if not finish and self.p.poll() is None: - timed_out = True - print CRED + "[Hanged ] " + self.test_subtest + CEND - current_hanged[self.test_subtest] = 1 - os.killpg(os.getpgid(self.p.pid), signal.SIGKILL) - del self.p + result['finish'] = finish + outfile.seek(0) + result['output'] = outfile.readlines() + return result + except Exception as e: + print str(e) + return None + finally: + if p is not None and p.poll() is None: + os.killpg(os.getpgid(p.pid), signal.SIGKILL) - if (finish): +def finish(result): + try: + test = result['test'] + if not result['finish']: + print CRED + "[Hanged ] " + test + CEND + current_hanged[test] = 1 + else: reported = False - name.seek(0) - for output in name.readlines(): - toks = output.split() - if len(toks)<2 or (toks[0] != self.test and self.test != "memcmp01" and self.test != "memcpy01"): + count = 1 + for output in result['output']: + tokens = output.split() + if len(tokens) < 2: continue - test_subtest = self.test + "," + toks[1] - self.test_subtest = test_subtest - if "TINFO" in output or test_subtest in current_passed or test_subtest in current_failed or self.test in current_hanged or test_subtest in current_broken: + if tokens[1].isdigit(): + test_subtest = test + "," + tokens[1] + count = int(tokens[1]) + 1 + else: + test_subtest = test + "," + str(count) + count = count + 1 + if "TINFO" in output or test_subtest in current_passed or test_subtest in current_failed or test in current_hanged or test_subtest in current_broken: continue + if output: output = output.strip() print >>f1, output + if "TFAIL" in output: print >>failed_tests_fh, test_subtest print CRED + "[Fail ] " + test_subtest + CEND current_failed[test_subtest] = 1 reported = True - elif "TPASS" in output: + + elif "TPASS" in output or "PASS:" in output: print >>passed_tests_fh, test_subtest print CGREEN + "[Pass ] " + test_subtest + CEND current_passed[test_subtest] = 1 reported = True - elif "TCONF" in output or "TBROK" in output or "error" in output: + + elif "TCONF" in output or "TBROK" in output or "BROK" in output or "error" in output: print >>broken_tests_fh, test_subtest - print "[Broken ] " + test_subtest #Syscall not implemented or test preparation failed + # Syscall not implemented or test preparation failed + print "[Broken ] " + test_subtest current_broken[test_subtest] = 1 reported = True - #else: - # print "[Broken ] " + self.test #Syscall not implemented or test preparation failed + if (not reported): - print >>broken_tests_fh, self.test - print CRED + "[Broken ] " + self.test + CEND - current_broken[self.test] = 1 - def Run(self): - self.start() - self.join() + print >>broken_tests_fh, test + print CRED + "[Broken ] " + test + CEND + current_broken[test] = 1 + + except Exception as e: + print str(e) CRED = '\033[91m' CGREEN = '\033[92m' @@ -109,22 +121,30 @@ with open(timeouts, 'rb') as csvfile: for row in test_timeout: test = row[0] timeout = row[1] - timeouts_dict[test] = timeout + timeouts_dict[test] = int(timeout) os.chdir("opt/ltp/testcases/bin") +pool = multiprocessing.Pool() with open('../../../../syscalls.graphene') as testcases: for line in testcases: + line = line.strip('\r\n\t') tokens = line.split( ) - test = tokens[1] + if (tokens[1] == "SGX") : + test = tokens[2] + else : + test = tokens[1] + if test=="seq": test = tokens[6] #splice02 try: timeout = timeouts_dict[test] except KeyError: timeout = DEFAULT_TIMEOUT - RunCmd([line], timeout, test).Run() - time.sleep(.1) + pool.apply_async(run, args=([line], timeout, test), callback=finish) os.chdir("../../../..") + +pool.close() +pool.join() stable_passed = dict() with open(stablePass, 'rb') as csvfile: @@ -136,11 +156,11 @@ with open(stablePass, 'rb') as csvfile: print "\n\nRESULT [Difference] :\n---------------------\n" -for test in stable_passed: +for test in sorted(stable_passed): if not test in current_passed: print CRED + "Test '" + test + "' did not pass in the current run!!" + CEND -for test in current_passed: +for test in sorted(current_passed): if not test in stable_passed: print CGREEN + "Test '" + test + "' passed in the current run!!" + CEND print "\n" diff --git a/LibOS/shim/test/apps/ltp/manifest.template b/LibOS/shim/test/apps/ltp/manifest.template index 226b0a91..eb476db2 100644 --- a/LibOS/shim/test/apps/ltp/manifest.template +++ b/LibOS/shim/test/apps/ltp/manifest.template @@ -1,15 +1,28 @@ loader.preload = file:$(SHIMPATH) -loader.env.LD_LIBRARY_PATH = /lib:/lib64:/usr/lib:/usr/lib64 +loader.env.LD_LIBRARY_PATH = /lib:/lib/x86_64-linux-gnu:/usr/lib:/usr/lib64 +loader.env.PATH = /bin:/usr/bin:. loader.debug_type = none +fs.mount.shm.type = chroot +fs.mount.shm.path = /dev/shm +fs.mount.shm.uri = file:/tmp + fs.mount.lib.type = chroot fs.mount.lib.path = /lib fs.mount.lib.uri = file:$(LIBCDIR) +fs.mount.lib64.type = chroot +fs.mount.lib64.path = /lib/x86_64-linux-gnu +fs.mount.lib64.uri = file:/lib/x86_64-linux-gnu + fs.mount.usr.type = chroot fs.mount.usr.path = /usr fs.mount.usr.uri = file:/usr +fs.mount.tmp.type = chroot +fs.mount.tmp.path = /tmp +fs.mount.tmp.uri = file:/tmp + sys.brk.size = 32M sys.stack.size = 4M @@ -18,3 +31,5 @@ sgx.trusted_files.libc = file:$(LIBCDIR)/libc.so.6 sgx.trusted_files.libdl = file:$(LIBCDIR)/libdl.so.2 sgx.trusted_files.libm = file:$(LIBCDIR)/libm.so.6 sgx.trusted_files.libpthread = file:$(LIBCDIR)/libpthread.so.0 + +sgx.allowed_files.tmp = file:/tmp diff --git a/LibOS/shim/test/apps/ltp/syscalls.sh b/LibOS/shim/test/apps/ltp/syscalls.sh index 659bc655..9527177b 100755 --- a/LibOS/shim/test/apps/ltp/syscalls.sh +++ b/LibOS/shim/test/apps/ltp/syscalls.sh @@ -1,6 +1,6 @@ #!/bin/sh cd `dirname $0` export LTPROOT=$PWD"/opt/ltp" -awk -f edit_sys_tests.awk $LTPROOT/runtest/syscalls > syscalls.graphene +awk -v SGX=$SGX_RUN -f edit_sys_tests.awk $LTPROOT/runtest/syscalls > syscalls.graphene cd $LTPROOT/../.. python fetch.py diff --git a/LibOS/shim/test/pal_loader b/LibOS/shim/test/pal_loader deleted file mode 120000 index 508715d1..00000000 --- a/LibOS/shim/test/pal_loader +++ /dev/null @@ -1 +0,0 @@ -../../../Runtime/pal_loader \ No newline at end of file diff --git a/LibOS/shim/test/regression/Makefile b/LibOS/shim/test/regression/Makefile index 0a0f0027..bbea0339 100644 --- a/LibOS/shim/test/regression/Makefile +++ b/LibOS/shim/test/regression/Makefile @@ -55,8 +55,6 @@ regression: $(target) @for f in $(wildcard 30_*.py); do env $(PYTHONENV) python $$f $(RUNTIME)/pal-$(PAL_HOST); done @echo "\n\nLarge File Support:" @for f in $(wildcard 90_*.py); do env $(PYTHONENV) python $$f $(RUNTIME)/pal-$(PAL_HOST); done - @echo "\n\nLTP tests for system calls:" - ../apps/ltp/syscalls.sh clean-tmp: rm -rf *.tmp ../apps/ltp/*.csv *.cached *.manifest.sgx *~ *.sig *.token diff --git a/Pal/include/bits/dlfcn.h b/Pal/include/bits/dlfcn.h deleted file mode 100644 index 99a20320..00000000 --- a/Pal/include/bits/dlfcn.h +++ /dev/null @@ -1,66 +0,0 @@ -/* System dependent definitions for run-time dynamic loading. - Copyright (C) 1996-2001, 2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _DLFCN_H -#define _DLFCN_H - -/* The MODE argument to `dlopen' contains one of the following: */ -#define RTLD_LAZY 0x00001 /* Lazy function call binding. */ -#define RTLD_NOW 0x00002 /* Immediate function call binding. */ -#define RTLD_BINDING_MASK 0x3 /* Mask of binding time value. */ -#define RTLD_NOLOAD 0x00004 /* Do not load the object. */ -#define RTLD_DEEPBIND 0x00008 /* Use deep binding. */ - -/* If the following bit is set in the MODE argument to `dlopen', - the symbols of the loaded object and its dependencies are made - visible as if the object were linked directly into the program. */ -#define RTLD_GLOBAL 0x00100 - -/* Unix98 demands the following flag which is the inverse to RTLD_GLOBAL. - The implementation does this by default and so we can define the - value to zero. */ -#define RTLD_LOCAL 0 - -/* Do not delete object when closed. */ -#define RTLD_NODELETE 0x01000 - -#ifdef __USE_GNU -/* To support profiling of shared objects it is a good idea to call - the function found using `dlsym' using the following macro since - these calls do not use the PLT. But this would mean the dynamic - loader has no chance to find out when the function is called. The - macro applies the necessary magic so that profiling is possible. - Rewrite - foo = (*fctp) (arg1, arg2); - into - foo = DL_CALL_FCT (fctp, (arg1, arg2)); -*/ -# define DL_CALL_FCT(fctp, args) \ - (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args) - -__BEGIN_DECLS - -/* This function calls the profiling functions. */ -extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW; - -__END_DECLS - -#endif - -#endif diff --git a/Pal/include/bits/libc-tsd.h b/Pal/include/bits/libc-tsd.h deleted file mode 100644 index 6d24a0d6..00000000 --- a/Pal/include/bits/libc-tsd.h +++ /dev/null @@ -1,70 +0,0 @@ -/* libc-internal interface for thread-specific data. Stub or TLS version. - Copyright (C) 1998,2001,2002,2008 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _GENERIC_BITS_LIBC_TSD_H -#define _GENERIC_BITS_LIBC_TSD_H 1 - -/* This file defines the following macros for accessing a small fixed - set of thread-specific `void *' data used only internally by libc. - - __libc_tsd_define(CLASS, TYPE, KEY) -- Define or declare a datum with TYPE - for KEY. CLASS can be `static' for - keys used in only one source file, - empty for global definitions, or - `extern' for global declarations. - __libc_tsd_address(TYPE, KEY) -- Return the `TYPE *' pointing to - the current thread's datum for KEY. - __libc_tsd_get(TYPE, KEY) -- Return the `TYPE' datum for KEY. - __libc_tsd_set(TYPE, KEY, VALUE) -- Set the datum for KEY to VALUE. - - The set of available KEY's will usually be provided as an enum, - and contains (at least): - _LIBC_TSD_KEY_MALLOC - _LIBC_TSD_KEY_DL_ERROR - _LIBC_TSD_KEY_RPC_VARS - All uses must be the literal _LIBC_TSD_* name in the __libc_tsd_* macros. - Some implementations may not provide any enum at all and instead - using string pasting in the macros. */ - -//#include - -/* When full support for __thread variables is available, this interface is - just a trivial wrapper for it. Without TLS, this is the generic/stub - implementation for wholly single-threaded systems. - - We don't define an enum for the possible key values, because the KEYs - translate directly into variables by macro magic. */ - -#if USE___THREAD -# define __libc_tsd_define(CLASS, TYPE, KEY) \ - CLASS __thread TYPE __libc_tsd_##KEY attribute_tls_model_ie; - -# define __libc_tsd_address(TYPE, KEY) (&__libc_tsd_##KEY) -# define __libc_tsd_get(TYPE, KEY) (__libc_tsd_##KEY) -# define __libc_tsd_set(TYPE, KEY, VALUE) (__libc_tsd_##KEY = (VALUE)) -#else -# define __libc_tsd_define(CLASS, TYPE, KEY) \ - CLASS TYPE __libc_tsd_##KEY##_data; - -# define __libc_tsd_address(TYPE, KEY) (&__libc_tsd_##KEY##_data) -# define __libc_tsd_get(TYPE, KEY) (__libc_tsd_##KEY##_data) -# define __libc_tsd_set(TYPE, KEY, VALUE) (__libc_tsd_##KEY##_data = (VALUE)) -#endif - -#endif /* bits/libc-tsd.h */ diff --git a/Pal/include/bp-asm.h b/Pal/include/bp-asm.h deleted file mode 100644 index 18d19eda..00000000 --- a/Pal/include/bp-asm.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Bounded-pointer definitions for x86-64 assembler. - Copyright (C) 2001 Free Software Foundation, Inc. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _bp_asm_h_ -# define _bp_asm_h_ 1 - -# if __ASSEMBLER__ - -# if __BOUNDED_POINTERS__ - -/* Bounded pointers occupy three words. */ -# define PTR_SIZE 24 -/* Bounded pointer return values are passed back through a hidden - argument that points to caller-allocate space. The hidden arg - occupies one word on the stack. */ -# define RTN_SIZE 6 -/* Although the caller pushes the hidden arg, the callee is - responsible for popping it. */ -# define RET_PTR ret $RTN_SIZE -/* Maintain frame pointer chain in leaf assembler functions for the benefit - of debugging stack traces when bounds violations occur. */ -# define ENTER pushq %rbp; movq %rsp, %rbp -# define LEAVE movq %rbp, %rsp; popq %rbp -/* Stack space overhead of procedure-call linkage: return address and - frame pointer. */ -# define LINKAGE 16 -/* Stack offset of return address after calling ENTER. */ -# define PCOFF 8 - -/* Int 5 is the "bound range" exception also raised by the "bound" - instruction. */ -# define BOUNDS_VIOLATED int $5 - -# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) \ - cmpq 8+BP_MEM, VAL_REG; \ - jae 0f; /* continue if value >= low */ \ - BOUNDS_VIOLATED; \ - 0: - -# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) \ - cmpq 16+BP_MEM, VAL_REG; \ - Jcc 0f; /* continue if value < high */ \ - BOUNDS_VIOLATED; \ - 0: - -# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) \ - cmpq 8+BP_MEM, VAL_REG; \ - jb 1f; /* die if value < low */ \ - cmpq 16+BP_MEM, VAL_REG; \ - jb 0f; /* continue if value < high */ \ - 1: BOUNDS_VIOLATED; \ - 0: - -# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) \ - CHECK_BOUNDS_LOW(VAL_REG, BP_MEM); \ - addl LENGTH, VAL_REG; \ - cmpq 16+BP_MEM, VAL_REG; \ - jbe 0f; /* continue if value <= high */ \ - BOUNDS_VIOLATED; \ - 0: subq LENGTH, VAL_REG /* restore value */ - -/* Take bounds from BP_MEM and affix them to the pointer - value in %rax, stuffing all into memory at RTN(%esp). - Use %rdx as a scratch register. */ - -# define RETURN_BOUNDED_POINTER(BP_MEM) \ - movq RTN(%rsp), %rdx; \ - movq %rax, 0(%rdx); \ - movq 8+BP_MEM, %rax; \ - movq %rax, 4(%rdx); \ - movq 16+BP_MEM, %rax; \ - movq %rax, 8(%rdx) - -# define RETURN_NULL_BOUNDED_POINTER \ - movl RTN(%rsp), %rdx; \ - movl %rax, 0(%rdx); \ - movl %rax, 4(%rdx); \ - movl %rax, 8(%rdx) - -/* The caller of PAL(__errno_location) is responsible for allocating space - for the three-word BP return-value and passing pushing its address - as an implicit first argument. */ -# define PUSH_ERRNO_LOCATION_RETURN \ - subl $16, %esp; \ - subl $8, %esp; \ - pushq %rsp - -/* PAL(__errno_location) is responsible for popping the implicit first - argument, but we must pop the space for the BP itself. We also - dereference the return value in order to dig out the pointer value. */ -# define POP_ERRNO_LOCATION_RETURN \ - popq %rax; \ - addq $16, %rsp - -# else /* !__BOUNDED_POINTERS__ */ - -/* Unbounded pointers occupy one word. */ -# define PTR_SIZE 8 -/* Unbounded pointer return values are passed back in the register %rax. */ -# define RTN_SIZE 0 -/* Use simple return instruction for unbounded pointer values. */ -# define RET_PTR ret -/* Don't maintain frame pointer chain for leaf assembler functions. */ -# define ENTER -# define LEAVE -/* Stack space overhead of procedure-call linkage: return address only. */ -# define LINKAGE 8 -/* Stack offset of return address after calling ENTER. */ -# define PCOFF 0 - -# define CHECK_BOUNDS_LOW(VAL_REG, BP_MEM) -# define CHECK_BOUNDS_HIGH(VAL_REG, BP_MEM, Jcc) -# define CHECK_BOUNDS_BOTH(VAL_REG, BP_MEM) -# define CHECK_BOUNDS_BOTH_WIDE(VAL_REG, BP_MEM, LENGTH) -# define RETURN_BOUNDED_POINTER(BP_MEM) - -# define RETURN_NULL_BOUNDED_POINTER - -# define PUSH_ERRNO_LOCATION_RETURN -# define POP_ERRNO_LOCATION_RETURN - -# endif /* !__BOUNDED_POINTERS__ */ - -# endif /* __ASSEMBLER__ */ - -#endif /* _bp_asm_h_ */ diff --git a/Pal/include/sysdeps/generic/linkmap.h b/Pal/include/sysdeps/generic/linkmap.h deleted file mode 100644 index dd0d1408..00000000 --- a/Pal/include/sysdeps/generic/linkmap.h +++ /dev/null @@ -1,16 +0,0 @@ -#if __WORDSIZE == 64 -struct link_map_machine - { - Elf64_Addr plt; /* Address of .plt + 0x16 */ - Elf64_Addr gotplt; /* Address of .got + 0x18 */ - void *tlsdesc_table; /* Address of TLS descriptor hash table. */ - }; - -#else -struct link_map_machine - { - Elf32_Addr plt; /* Address of .plt + 0x16 */ - Elf32_Addr gotplt; /* Address of .got + 0x0c */ - void *tlsdesc_table; /* Address of TLS descriptor hash table. */ - }; -#endif diff --git a/Pal/include/sysdeps/unix/i386/sysdep.S b/Pal/include/sysdeps/unix/i386/sysdep.S deleted file mode 100644 index 723f9b8b..00000000 --- a/Pal/include/sysdeps/unix/i386/sysdep.S +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright (C) 1991,1992,1993,1994,1995,1996,1997,2000,2002,2004,2005 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#define _ERRNO_H -#include -#include -#include - -#ifdef IS_IN_rtld -# include /* Defines RTLD_PRIVATE_ERRNO. */ -#endif - -.globl C_SYMBOL_NAME(errno) -.globl syscall_error - -#undef syscall_error -#ifdef NO_UNDERSCORES -__syscall_error: -#else -syscall_error: -#endif -#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN - /* We translate the system's EWOULDBLOCK error into EAGAIN. - The GNU C library always defines EWOULDBLOCK==EAGAIN. - EWOULDBLOCK_sys is the original number. */ - cmpl $EWOULDBLOCK_sys, %eax /* Is it the old EWOULDBLOCK? */ - jne notb /* Branch if not. */ - movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */ -notb: -#endif -#ifndef PIC -# if USE___THREAD -# ifndef NO_TLS_DIRECT_SEG_REFS - movl %eax, %gs:C_SYMBOL_NAME(errno@NTPOFF) -# else - movl %gs:0, %ecx - movl %eax, C_SYMBOL_NAME(errno@NTPOFF)(%ecx) -# endif -# elif !defined _LIBC_REENTRANT - movl %eax, C_SYMBOL_NAME(errno) -# else - pushl %eax - PUSH_ERRNO_LOCATION_RETURN - call BP_SYM (PAL(__errno_location)) - POP_ERRNO_LOCATION_RETURN - popl %ecx - movl %ecx, (%eax) -# endif -#else - /* The caller has pushed %ebx and then set it up to - point to the GOT before calling us through the PLT. */ -# if USE___THREAD - movl C_SYMBOL_NAME(errno@GOTNTPOFF)(%ebx), %ecx - - /* Pop %ebx value saved before jumping here. */ - popl %ebx -# ifndef NO_TLS_DIRECT_SEG_REFS - addl %gs:0, %ecx - movl %eax, (%ecx) -# else - movl %eax, %gs:0(%ecx) -# endif -# elif RTLD_PRIVATE_ERRNO - movl %eax, C_SYMBOL_NAME(rtld_errno@GOTOFF)(%ebx) - - /* Pop %ebx value saved before jumping here. */ - popl %ebx -# elif !defined _LIBC_REENTRANT - movl C_SYMBOL_NAME(errno@GOT)(%ebx), %ecx - - /* Pop %ebx value saved before jumping here. */ - popl %ebx - movl %eax, (%ecx) -# else - pushl %eax - PUSH_ERRNO_LOCATION_RETURN - call C_SYMBOL_NAME (BP_SYM (PAL(__errno_location))@PLT) - POP_ERRNO_LOCATION_RETURN - popl %ecx - /* Pop %ebx value saved before jumping here. */ - popl %ebx - movl %ecx, (%eax) -# endif -#endif - movl $-1, %eax - ret - -#undef __syscall_error -END (__syscall_error) diff --git a/Pal/include/sysdeps/unix/x86_64/sysdep.S b/Pal/include/sysdeps/unix/x86_64/sysdep.S deleted file mode 100644 index 415e9a23..00000000 --- a/Pal/include/sysdeps/unix/x86_64/sysdep.S +++ /dev/null @@ -1,90 +0,0 @@ -/* Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#include -#define _ERRNO_H -#include -#include -#include -//#include - -#ifdef IS_IN_rtld -# include /* Defines RTLD_PRIVATE_ERRNO. */ -#endif - -.globl C_SYMBOL_NAME(errno) -.globl syscall_error - -#undef syscall_error -#ifdef NO_UNDERSCORES -__syscall_error: -#else -syscall_error: -#endif -#if defined (EWOULDBLOCK_sys) && EWOULDBLOCK_sys != EAGAIN - /* We translate the system's EWOULDBLOCK error into EAGAIN. - The GNU C library always defines EWOULDBLOCK==EAGAIN. - EWOULDBLOCK_sys is the original number. */ - cmpq $EWOULDBLOCK_sys, %rax /* Is it the old EWOULDBLOCK? */ - jne notb /* Branch if not. */ - movl $EAGAIN, %eax /* Yes; translate it to EAGAIN. */ -notb: -#endif -#if USE___THREAD -# ifdef PIC - movq C_SYMBOL_NAME(errno@GOTTPOFF)(%rip), %rcx - movl %eax, %fs:0(%rcx) -# else - movl %eax, %fs:C_SYMBOL_NAME(errno@TPOFF) -# endif -#elif !defined PIC -# ifndef _LIBC_REENTRANT - movl %eax, C_SYMBOL_NAME(errno) -# else - pushq %rax - cfi_adjust_cfa_offset(8) - PUSH_ERRNO_LOCATION_RETURN - call BP_SYM (PAL(__errno_location)) - POP_ERRNO_LOCATION_RETURN - popq %rcx - cfi_adjust_cfa_offset(-8) - movl %ecx, (%rax) -# endif -#else -# if RTLD_PRIVATE_ERRNO - leaq rtld_errno(%rip), %rcx - movl %eax, (%rcx) -# elif !defined _LIBC_REENTRANT - movq C_SYMBOL_NAME(errno)@GOTPCREL(%rip), %rcx - movl %eax, (%rcx) -# else - pushq %rax - cfi_adjust_cfa_offset(8) - PUSH_ERRNO_LOCATION_RETURN - call C_SYMBOL_NAME (BP_SYM (PAL(__errno_location))@PLT) - POP_ERRNO_LOCATION_RETURN - popq %rcx - cfi_adjust_cfa_offset(-8) - movl %ecx, (%rax) -# endif -#endif - movq $-1, %rax - ret - -#undef __syscall_error -END (__syscall_error) diff --git a/Pal/ipc/linux/graphene-ipc.c b/Pal/ipc/linux/graphene-ipc.c index f73159ac..6be23f1e 100644 --- a/Pal/ipc/linux/graphene-ipc.c +++ b/Pal/ipc/linux/graphene-ipc.c @@ -189,7 +189,11 @@ static inline void release_gipc_queue(struct gipc_queue *gq, bool locked) while (gq->next != gq->last) { idx = gq->next; if (gq->pages[idx].page) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + put_page(gq->pages[idx].page); +#else page_cache_release(gq->pages[idx].page); +#endif gq->pages[idx].page = NULL; } if (gq->pages[idx].file) { @@ -353,10 +357,15 @@ static int get_pages (struct task_struct *task, unsigned long start, DEBUG("GIPC_SEND get_user_pages %ld pages at %lx\n", addr, nr); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0) + rv = get_user_pages(addr, nr, + FOLL_GET|FOLL_FORCE|FOLL_SPLIT, + pages + last, vmas + last); +#else rv = __get_user_pages(task, mm, addr, nr, FOLL_GET|FOLL_FORCE|FOLL_SPLIT, pages + last, vmas + last, NULL); - +#endif if (rv <= 0) { printk(KERN_ERR "Graphene error: " "get_user_pages at 0x%016lx-0x%016lx\n", @@ -702,7 +711,11 @@ static int do_gipc_recv(struct task_struct *task, struct gipc_queue *gq, finish: /* Drop the kernel's reference to this page */ if (page) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 6, 0) + put_page(page); +#else page_cache_release(page); +#endif if (file) fput_atomic(file); if (rv) diff --git a/Pal/lib/Makefile b/Pal/lib/Makefile index fb7a7c4f..1c84afaa 100644 --- a/Pal/lib/Makefile +++ b/Pal/lib/Makefile @@ -13,7 +13,7 @@ include ../src/host/$(PAL_HOST)/Makefile.am CFLAGS += -I. -I../include -I../src subdirs = string stdlib network graphene util crypto crypto/mbedtls objs = $(foreach dir,$(subdirs),$(patsubst %.c,%.o,$(wildcard $(dir)/*.c))) -headers = asm-errlist.h api.h +headers = api.h # Select which crypto adpater you want to use here. This has to match # the #define in pal_crypto.h. diff --git a/Pal/lib/asm-errlist.h b/Pal/lib/asm-errlist.h deleted file mode 100644 index e1641eee..00000000 --- a/Pal/lib/asm-errlist.h +++ /dev/null @@ -1,1495 +0,0 @@ -/* -*- 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: */ - -/* Copyright (C) 2014 OSCAR lab, Stony Brook University - This file is part of Graphene Library OS. - - Graphene Library OS is free software: you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - Graphene Library OS is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - - -/* This file is generated from errno.texi by errlist.awk. */ - -#include - -#ifndef ERR_REMAP -# define ERR_REMAP(n) n -#endif - -#ifndef N -#define N_(str) (str) -#endif - -#ifdef ERR_MAX -# define ERRLIST_SIZE ERR_MAX + 1 -#else -# define ERRLIST_SIZE -#endif -static const char *const __sys_errlist_internal[ERRLIST_SIZE] = - { - [0] = N_("Success"), -#ifdef EPERM -/* -TRANS Operation not permitted; only the owner of the file (or other resource) -TRANS or processes with special privileges can perform the operation. */ - [ERR_REMAP (EPERM)] = N_("Operation not permitted"), -# if EPERM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPERM -# endif -#endif -#ifdef ENOENT -/* -TRANS No such file or directory. This is a ``file doesn't exist'' error -TRANS for ordinary files that are referenced in contexts where they are -TRANS expected to already exist. */ - [ERR_REMAP (ENOENT)] = N_("No such file or directory"), -# if ENOENT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOENT -# endif -#endif -#ifdef ESRCH -/* -TRANS No process matches the specified process ID. */ - [ERR_REMAP (ESRCH)] = N_("No such process"), -# if ESRCH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESRCH -# endif -#endif -#ifdef EINTR -/* -TRANS Interrupted function call; an asynchronous signal occurred and prevented -TRANS completion of the call. When this happens, you should try the call -TRANS again. -TRANS -TRANS You can choose to have functions resume after a signal that is handled, -TRANS rather than failing with @code{EINTR}; see @ref{Interrupted -TRANS Primitives}. */ - [ERR_REMAP (EINTR)] = N_("Interrupted system call"), -# if EINTR > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EINTR -# endif -#endif -#ifdef EIO -/* -TRANS Input/output error; usually used for physical read or write errors. */ - [ERR_REMAP (EIO)] = N_("Input/output error"), -# if EIO > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EIO -# endif -#endif -#ifdef ENXIO -/* -TRANS No such device or address. The system tried to use the device -TRANS represented by a file you specified, and it couldn't find the device. -TRANS This can mean that the device file was installed incorrectly, or that -TRANS the physical device is missing or not correctly attached to the -TRANS computer. */ - [ERR_REMAP (ENXIO)] = N_("No such device or address"), -# if ENXIO > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENXIO -# endif -#endif -#ifdef E2BIG -/* -TRANS Argument list too long; used when the arguments passed to a new program -TRANS being executed with one of the @code{exec} functions (@pxref{Executing a -TRANS File}) occupy too much memory space. This condition never arises in the -TRANS GNU system. */ - [ERR_REMAP (E2BIG)] = N_("Argument list too long"), -# if E2BIG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX E2BIG -# endif -#endif -#ifdef ENOEXEC -/* -TRANS Invalid executable file format. This condition is detected by the -TRANS @code{exec} functions; see @ref{Executing a File}. */ - [ERR_REMAP (ENOEXEC)] = N_("Exec format error"), -# if ENOEXEC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOEXEC -# endif -#endif -#ifdef EBADF -/* -TRANS Bad file descriptor; for example, I/O on a descriptor that has been -TRANS closed or reading from a descriptor open only for writing (or vice -TRANS versa). */ - [ERR_REMAP (EBADF)] = N_("Bad file descriptor"), -# if EBADF > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADF -# endif -#endif -#ifdef ECHILD -/* -TRANS There are no child processes. This error happens on operations that are -TRANS supposed to manipulate child processes, when there aren't any processes -TRANS to manipulate. */ - [ERR_REMAP (ECHILD)] = N_("No child processes"), -# if ECHILD > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECHILD -# endif -#endif -#ifdef EDEADLK -/* -TRANS Deadlock avoided; allocating a system resource would have resulted in a -TRANS deadlock situation. The system does not guarantee that it will notice -TRANS all such situations. This error means you got lucky and the system -TRANS noticed; it might just hang. @xref{File Locks}, for an example. */ - [ERR_REMAP (EDEADLK)] = N_("Resource deadlock avoided"), -# if EDEADLK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDEADLK -# endif -#endif -#ifdef ENOMEM -/* -TRANS No memory available. The system cannot allocate more virtual memory -TRANS because its capacity is full. */ - [ERR_REMAP (ENOMEM)] = N_("Cannot allocate memory"), -# if ENOMEM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOMEM -# endif -#endif -#ifdef EACCES -/* -TRANS Permission denied; the file permissions do not allow the attempted operation. */ - [ERR_REMAP (EACCES)] = N_("Permission denied"), -# if EACCES > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EACCES -# endif -#endif -#ifdef EFAULT -/* -TRANS Bad address; an invalid pointer was detected. -TRANS In the GNU system, this error never happens; you get a signal instead. */ - [ERR_REMAP (EFAULT)] = N_("Bad address"), -# if EFAULT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EFAULT -# endif -#endif -#ifdef ENOTBLK -/* -TRANS A file that isn't a block special file was given in a situation that -TRANS requires one. For example, trying to mount an ordinary file as a file -TRANS system in Unix gives this error. */ - [ERR_REMAP (ENOTBLK)] = N_("Block device required"), -# if ENOTBLK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTBLK -# endif -#endif -#ifdef EBUSY -/* -TRANS Resource busy; a system resource that can't be shared is already in use. -TRANS For example, if you try to delete a file that is the root of a currently -TRANS mounted filesystem, you get this error. */ - [ERR_REMAP (EBUSY)] = N_("Device or resource busy"), -# if EBUSY > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBUSY -# endif -#endif -#ifdef EEXIST -/* -TRANS File exists; an existing file was specified in a context where it only -TRANS makes sense to specify a new file. */ - [ERR_REMAP (EEXIST)] = N_("File exists"), -# if EEXIST > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EEXIST -# endif -#endif -#ifdef EXDEV -/* -TRANS An attempt to make an improper link across file systems was detected. -TRANS This happens not only when you use @code{link} (@pxref{Hard Links}) but -TRANS also when you rename a file with @code{rename} (@pxref{Renaming Files}). */ - [ERR_REMAP (EXDEV)] = N_("Invalid cross-device link"), -# if EXDEV > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EXDEV -# endif -#endif -#ifdef ENODEV -/* -TRANS The wrong type of device was given to a function that expects a -TRANS particular sort of device. */ - [ERR_REMAP (ENODEV)] = N_("No such device"), -# if ENODEV > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENODEV -# endif -#endif -#ifdef ENOTDIR -/* -TRANS A file that isn't a directory was specified when a directory is required. */ - [ERR_REMAP (ENOTDIR)] = N_("Not a directory"), -# if ENOTDIR > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTDIR -# endif -#endif -#ifdef EISDIR -/* -TRANS File is a directory; you cannot open a directory for writing, -TRANS or create or remove hard links to it. */ - [ERR_REMAP (EISDIR)] = N_("Is a directory"), -# if EISDIR > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EISDIR -# endif -#endif -#ifdef EINVAL -/* -TRANS Invalid argument. This is used to indicate various kinds of problems -TRANS with passing the wrong argument to a library function. */ - [ERR_REMAP (EINVAL)] = N_("Invalid argument"), -# if EINVAL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EINVAL -# endif -#endif -#ifdef EMFILE -/* -TRANS The current process has too many files open and can't open any more. -TRANS Duplicate descriptors do count toward this limit. -TRANS -TRANS In BSD and GNU, the number of open files is controlled by a resource -TRANS limit that can usually be increased. If you get this error, you might -TRANS want to increase the @code{RLIMIT_NOFILE} limit or make it unlimited; -TRANS @pxref{Limits on Resources}. */ - [ERR_REMAP (EMFILE)] = N_("Too many open files"), -# if EMFILE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EMFILE -# endif -#endif -#ifdef ENFILE -/* -TRANS There are too many distinct file openings in the entire system. Note -TRANS that any number of linked channels count as just one file opening; see -TRANS @ref{Linked Channels}. This error never occurs in the GNU system. */ - [ERR_REMAP (ENFILE)] = N_("Too many open files in system"), -# if ENFILE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENFILE -# endif -#endif -#ifdef ENOTTY -/* -TRANS Inappropriate I/O control operation, such as trying to set terminal -TRANS modes on an ordinary file. */ - [ERR_REMAP (ENOTTY)] = N_("Inappropriate ioctl for device"), -# if ENOTTY > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTTY -# endif -#endif -#ifdef ETXTBSY -/* -TRANS An attempt to execute a file that is currently open for writing, or -TRANS write to a file that is currently being executed. Often using a -TRANS debugger to run a program is considered having it open for writing and -TRANS will cause this error. (The name stands for ``text file busy''.) This -TRANS is not an error in the GNU system; the text is copied as necessary. */ - [ERR_REMAP (ETXTBSY)] = N_("Text file busy"), -# if ETXTBSY > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ETXTBSY -# endif -#endif -#ifdef EFBIG -/* -TRANS File too big; the size of a file would be larger than allowed by the system. */ - [ERR_REMAP (EFBIG)] = N_("File too large"), -# if EFBIG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EFBIG -# endif -#endif -#ifdef ENOSPC -/* -TRANS No space left on device; write operation on a file failed because the -TRANS disk is full. */ - [ERR_REMAP (ENOSPC)] = N_("No space left on device"), -# if ENOSPC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOSPC -# endif -#endif -#ifdef ESPIPE -/* -TRANS Invalid seek operation (such as on a pipe). */ - [ERR_REMAP (ESPIPE)] = N_("Illegal seek"), -# if ESPIPE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESPIPE -# endif -#endif -#ifdef EROFS -/* -TRANS An attempt was made to modify something on a read-only file system. */ - [ERR_REMAP (EROFS)] = N_("Read-only file system"), -# if EROFS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EROFS -# endif -#endif -#ifdef EMLINK -/* -TRANS Too many links; the link count of a single file would become too large. -TRANS @code{rename} can cause this error if the file being renamed already has -TRANS as many links as it can take (@pxref{Renaming Files}). */ - [ERR_REMAP (EMLINK)] = N_("Too many links"), -# if EMLINK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EMLINK -# endif -#endif -#ifdef EPIPE -/* -TRANS Broken pipe; there is no process reading from the other end of a pipe. -TRANS Every library function that returns this error code also generates a -TRANS @code{SIGPIPE} signal; this signal terminates the program if not handled -TRANS or blocked. Thus, your program will never actually see @code{EPIPE} -TRANS unless it has handled or blocked @code{SIGPIPE}. */ - [ERR_REMAP (EPIPE)] = N_("Broken pipe"), -# if EPIPE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPIPE -# endif -#endif -#ifdef EDOM -/* -TRANS Domain error; used by mathematical functions when an argument value does -TRANS not fall into the domain over which the function is defined. */ - [ERR_REMAP (EDOM)] = N_("Numerical argument out of domain"), -# if EDOM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDOM -# endif -#endif -#ifdef ERANGE -/* -TRANS Range error; used by mathematical functions when the result value is -TRANS not representable because of overflow or underflow. */ - [ERR_REMAP (ERANGE)] = N_("Numerical result out of range"), -# if ERANGE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ERANGE -# endif -#endif -#ifdef EAGAIN -/* -TRANS Resource temporarily unavailable; the call might work if you try again -TRANS later. The macro @code{EWOULDBLOCK} is another name for @code{EAGAIN}; -TRANS they are always the same in the GNU C library. -TRANS -TRANS This error can happen in a few different situations: -TRANS -TRANS @itemize @bullet -TRANS @item -TRANS An operation that would block was attempted on an object that has -TRANS non-blocking mode selected. Trying the same operation again will block -TRANS until some external condition makes it possible to read, write, or -TRANS connect (whatever the operation). You can use @code{select} to find out -TRANS when the operation will be possible; @pxref{Waiting for I/O}. -TRANS -TRANS @strong{Portability Note:} In many older Unix systems, this condition -TRANS was indicated by @code{EWOULDBLOCK}, which was a distinct error code -TRANS different from @code{EAGAIN}. To make your program portable, you should -TRANS check for both codes and treat them the same. -TRANS -TRANS @item -TRANS A temporary resource shortage made an operation impossible. @code{fork} -TRANS can return this error. It indicates that the shortage is expected to -TRANS pass, so your program can try the call again later and it may succeed. -TRANS It is probably a good idea to delay for a few seconds before trying it -TRANS again, to allow time for other processes to release scarce resources. -TRANS Such shortages are usually fairly serious and affect the whole system, -TRANS so usually an interactive program should report the error to the user -TRANS and return to its command loop. -TRANS @end itemize */ - [ERR_REMAP (EAGAIN)] = N_("Resource temporarily unavailable"), -# if EAGAIN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EAGAIN -# endif -#endif -#if defined (EWOULDBLOCK) && EWOULDBLOCK != EAGAIN -/* -TRANS In the GNU C library, this is another name for @code{EAGAIN} (above). -TRANS The values are always the same, on every operating system. -TRANS -TRANS C libraries in many older Unix systems have @code{EWOULDBLOCK} as a -TRANS separate error code. */ - [ERR_REMAP (EWOULDBLOCK)] = N_("Operation would block"), -# if EWOULDBLOCK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EWOULDBLOCK -# endif -#endif -#ifdef EINPROGRESS -/* -TRANS An operation that cannot complete immediately was initiated on an object -TRANS that has non-blocking mode selected. Some functions that must always -TRANS block (such as @code{connect}; @pxref{Connecting}) never return -TRANS @code{EAGAIN}. Instead, they return @code{EINPROGRESS} to indicate that -TRANS the operation has begun and will take some time. Attempts to manipulate -TRANS the object before the call completes return @code{EALREADY}. You can -TRANS use the @code{select} function to find out when the pending operation -TRANS has completed; @pxref{Waiting for I/O}. */ - [ERR_REMAP (EINPROGRESS)] = N_("Operation now in progress"), -# if EINPROGRESS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EINPROGRESS -# endif -#endif -#ifdef EALREADY -/* -TRANS An operation is already in progress on an object that has non-blocking -TRANS mode selected. */ - [ERR_REMAP (EALREADY)] = N_("Operation already in progress"), -# if EALREADY > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EALREADY -# endif -#endif -#ifdef ENOTSOCK -/* -TRANS A file that isn't a socket was specified when a socket is required. */ - [ERR_REMAP (ENOTSOCK)] = N_("Socket operation on non-socket"), -# if ENOTSOCK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTSOCK -# endif -#endif -#ifdef EMSGSIZE -/* -TRANS The size of a message sent on a socket was larger than the supported -TRANS maximum size. */ - [ERR_REMAP (EMSGSIZE)] = N_("Message too long"), -# if EMSGSIZE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EMSGSIZE -# endif -#endif -#ifdef EPROTOTYPE -/* -TRANS The socket type does not support the requested communications protocol. */ - [ERR_REMAP (EPROTOTYPE)] = N_("Protocol wrong type for socket"), -# if EPROTOTYPE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROTOTYPE -# endif -#endif -#ifdef ENOPROTOOPT -/* -TRANS You specified a socket option that doesn't make sense for the -TRANS particular protocol being used by the socket. @xref{Socket Options}. */ - [ERR_REMAP (ENOPROTOOPT)] = N_("Protocol not available"), -# if ENOPROTOOPT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOPROTOOPT -# endif -#endif -#ifdef EPROTONOSUPPORT -/* -TRANS The socket domain does not support the requested communications protocol -TRANS (perhaps because the requested protocol is completely invalid). -TRANS @xref{Creating a Socket}. */ - [ERR_REMAP (EPROTONOSUPPORT)] = N_("Protocol not supported"), -# if EPROTONOSUPPORT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROTONOSUPPORT -# endif -#endif -#ifdef ESOCKTNOSUPPORT -/* -TRANS The socket type is not supported. */ - [ERR_REMAP (ESOCKTNOSUPPORT)] = N_("Socket type not supported"), -# if ESOCKTNOSUPPORT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESOCKTNOSUPPORT -# endif -#endif -#ifdef EOPNOTSUPP -/* -TRANS The operation you requested is not supported. Some socket functions -TRANS don't make sense for all types of sockets, and others may not be -TRANS implemented for all communications protocols. In the GNU system, this -TRANS error can happen for many calls when the object does not support the -TRANS particular operation; it is a generic indication that the server knows -TRANS nothing to do for that call. */ - [ERR_REMAP (EOPNOTSUPP)] = N_("Operation not supported"), -# if EOPNOTSUPP > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EOPNOTSUPP -# endif -#endif -#ifdef EPFNOSUPPORT -/* -TRANS The socket communications protocol family you requested is not supported. */ - [ERR_REMAP (EPFNOSUPPORT)] = N_("Protocol family not supported"), -# if EPFNOSUPPORT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPFNOSUPPORT -# endif -#endif -#ifdef EAFNOSUPPORT -/* -TRANS The address family specified for a socket is not supported; it is -TRANS inconsistent with the protocol being used on the socket. @xref{Sockets}. */ - [ERR_REMAP (EAFNOSUPPORT)] = N_("Address family not supported by protocol"), -# if EAFNOSUPPORT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EAFNOSUPPORT -# endif -#endif -#ifdef EADDRINUSE -/* -TRANS The requested socket address is already in use. @xref{Socket Addresses}. */ - [ERR_REMAP (EADDRINUSE)] = N_("Address already in use"), -# if EADDRINUSE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EADDRINUSE -# endif -#endif -#ifdef EADDRNOTAVAIL -/* -TRANS The requested socket address is not available; for example, you tried -TRANS to give a socket a name that doesn't match the local host name. -TRANS @xref{Socket Addresses}. */ - [ERR_REMAP (EADDRNOTAVAIL)] = N_("Cannot assign requested address"), -# if EADDRNOTAVAIL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EADDRNOTAVAIL -# endif -#endif -#ifdef ENETDOWN -/* -TRANS A socket operation failed because the network was down. */ - [ERR_REMAP (ENETDOWN)] = N_("Network is down"), -# if ENETDOWN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENETDOWN -# endif -#endif -#ifdef ENETUNREACH -/* -TRANS A socket operation failed because the subnet containing the remote host -TRANS was unreachable. */ - [ERR_REMAP (ENETUNREACH)] = N_("Network is unreachable"), -# if ENETUNREACH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENETUNREACH -# endif -#endif -#ifdef ENETRESET -/* -TRANS A network connection was reset because the remote host crashed. */ - [ERR_REMAP (ENETRESET)] = N_("Network dropped connection on reset"), -# if ENETRESET > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENETRESET -# endif -#endif -#ifdef ECONNABORTED -/* -TRANS A network connection was aborted locally. */ - [ERR_REMAP (ECONNABORTED)] = N_("Software caused connection abort"), -# if ECONNABORTED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECONNABORTED -# endif -#endif -#ifdef ECONNRESET -/* -TRANS A network connection was closed for reasons outside the control of the -TRANS local host, such as by the remote machine rebooting or an unrecoverable -TRANS protocol violation. */ - [ERR_REMAP (ECONNRESET)] = N_("Connection reset by peer"), -# if ECONNRESET > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECONNRESET -# endif -#endif -#ifdef ENOBUFS -/* -TRANS The kernel's buffers for I/O operations are all in use. In GNU, this -TRANS error is always synonymous with @code{ENOMEM}; you may get one or the -TRANS other from network operations. */ - [ERR_REMAP (ENOBUFS)] = N_("No buffer space available"), -# if ENOBUFS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOBUFS -# endif -#endif -#ifdef EISCONN -/* -TRANS You tried to connect a socket that is already connected. -TRANS @xref{Connecting}. */ - [ERR_REMAP (EISCONN)] = N_("Transport endpoint is already connected"), -# if EISCONN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EISCONN -# endif -#endif -#ifdef ENOTCONN -/* -TRANS The socket is not connected to anything. You get this error when you -TRANS try to transmit data over a socket, without first specifying a -TRANS destination for the data. For a connectionless socket (for datagram -TRANS protocols, such as UDP), you get @code{EDESTADDRREQ} instead. */ - [ERR_REMAP (ENOTCONN)] = N_("Transport endpoint is not connected"), -# if ENOTCONN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTCONN -# endif -#endif -#ifdef EDESTADDRREQ -/* -TRANS No default destination address was set for the socket. You get this -TRANS error when you try to transmit data over a connectionless socket, -TRANS without first specifying a destination for the data with @code{connect}. */ - [ERR_REMAP (EDESTADDRREQ)] = N_("Destination address required"), -# if EDESTADDRREQ > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDESTADDRREQ -# endif -#endif -#ifdef ESHUTDOWN -/* -TRANS The socket has already been shut down. */ - [ERR_REMAP (ESHUTDOWN)] = N_("Cannot send after transport endpoint shutdown"), -# if ESHUTDOWN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESHUTDOWN -# endif -#endif -#ifdef ETOOMANYREFS -/* -TRANS ??? */ - [ERR_REMAP (ETOOMANYREFS)] = N_("Too many references: cannot splice"), -# if ETOOMANYREFS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ETOOMANYREFS -# endif -#endif -#ifdef ETIMEDOUT -/* -TRANS A socket operation with a specified timeout received no response during -TRANS the timeout period. */ - [ERR_REMAP (ETIMEDOUT)] = N_("Connection timed out"), -# if ETIMEDOUT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ETIMEDOUT -# endif -#endif -#ifdef ECONNREFUSED -/* -TRANS A remote host refused to allow the network connection (typically because -TRANS it is not running the requested service). */ - [ERR_REMAP (ECONNREFUSED)] = N_("Connection refused"), -# if ECONNREFUSED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECONNREFUSED -# endif -#endif -#ifdef ELOOP -/* -TRANS Too many levels of symbolic links were encountered in looking up a file name. -TRANS This often indicates a cycle of symbolic links. */ - [ERR_REMAP (ELOOP)] = N_("Too many levels of symbolic links"), -# if ELOOP > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELOOP -# endif -#endif -#ifdef ENAMETOOLONG -/* -TRANS Filename too long (longer than @code{PATH_MAX}; @pxref{Limits for -TRANS Files}) or host name too long (in @code{gethostname} or -TRANS @code{sethostname}; @pxref{Host Identification}). */ - [ERR_REMAP (ENAMETOOLONG)] = N_("File name too long"), -# if ENAMETOOLONG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENAMETOOLONG -# endif -#endif -#ifdef EHOSTDOWN -/* -TRANS The remote host for a requested network connection is down. */ - [ERR_REMAP (EHOSTDOWN)] = N_("Host is down"), -# if EHOSTDOWN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EHOSTDOWN -# endif -#endif -#ifdef EHOSTUNREACH -/* -TRANS The remote host for a requested network connection is not reachable. */ - [ERR_REMAP (EHOSTUNREACH)] = N_("No route to host"), -# if EHOSTUNREACH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EHOSTUNREACH -# endif -#endif -#ifdef ENOTEMPTY -/* -TRANS Directory not empty, where an empty directory was expected. Typically, -TRANS this error occurs when you are trying to delete a directory. */ - [ERR_REMAP (ENOTEMPTY)] = N_("Directory not empty"), -# if ENOTEMPTY > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTEMPTY -# endif -#endif -#ifdef EPROCLIM -/* -TRANS This means that the per-user limit on new process would be exceeded by -TRANS an attempted @code{fork}. @xref{Limits on Resources}, for details on -TRANS the @code{RLIMIT_NPROC} limit. */ - [ERR_REMAP (EPROCLIM)] = N_("Too many processes"), -# if EPROCLIM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROCLIM -# endif -#endif -#ifdef EUSERS -/* -TRANS The file quota system is confused because there are too many users. -TRANS @c This can probably happen in a GNU system when using NFS. */ - [ERR_REMAP (EUSERS)] = N_("Too many users"), -# if EUSERS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EUSERS -# endif -#endif -#ifdef EDQUOT -/* -TRANS The user's disk quota was exceeded. */ - [ERR_REMAP (EDQUOT)] = N_("Disk quota exceeded"), -# if EDQUOT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDQUOT -# endif -#endif -#ifdef ESTALE -/* -TRANS Stale NFS file handle. This indicates an internal confusion in the NFS -TRANS system which is due to file system rearrangements on the server host. -TRANS Repairing this condition usually requires unmounting and remounting -TRANS the NFS file system on the local host. */ - [ERR_REMAP (ESTALE)] = N_("Stale NFS file handle"), -# if ESTALE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESTALE -# endif -#endif -#ifdef EREMOTE -/* -TRANS An attempt was made to NFS-mount a remote file system with a file name that -TRANS already specifies an NFS-mounted file. -TRANS (This is an error on some operating systems, but we expect it to work -TRANS properly on the GNU system, making this error code impossible.) */ - [ERR_REMAP (EREMOTE)] = N_("Object is remote"), -# if EREMOTE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EREMOTE -# endif -#endif -#ifdef EBADRPC -/* -TRANS ??? */ - [ERR_REMAP (EBADRPC)] = N_("RPC struct is bad"), -# if EBADRPC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADRPC -# endif -#endif -#ifdef ERPCMISMATCH -/* -TRANS ??? */ - [ERR_REMAP (ERPCMISMATCH)] = N_("RPC version wrong"), -# if ERPCMISMATCH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ERPCMISMATCH -# endif -#endif -#ifdef EPROGUNAVAIL -/* -TRANS ??? */ - [ERR_REMAP (EPROGUNAVAIL)] = N_("RPC program not available"), -# if EPROGUNAVAIL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROGUNAVAIL -# endif -#endif -#ifdef EPROGMISMATCH -/* -TRANS ??? */ - [ERR_REMAP (EPROGMISMATCH)] = N_("RPC program version wrong"), -# if EPROGMISMATCH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROGMISMATCH -# endif -#endif -#ifdef EPROCUNAVAIL -/* -TRANS ??? */ - [ERR_REMAP (EPROCUNAVAIL)] = N_("RPC bad procedure for program"), -# if EPROCUNAVAIL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROCUNAVAIL -# endif -#endif -#ifdef ENOLCK -/* -TRANS No locks available. This is used by the file locking facilities; see -TRANS @ref{File Locks}. This error is never generated by the GNU system, but -TRANS it can result from an operation to an NFS server running another -TRANS operating system. */ - [ERR_REMAP (ENOLCK)] = N_("No locks available"), -# if ENOLCK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOLCK -# endif -#endif -#ifdef EFTYPE -/* -TRANS Inappropriate file type or format. The file was the wrong type for the -TRANS operation, or a data file had the wrong format. -TRANS -TRANS On some systems @code{chmod} returns this error if you try to set the -TRANS sticky bit on a non-directory file; @pxref{Setting Permissions}. */ - [ERR_REMAP (EFTYPE)] = N_("Inappropriate file type or format"), -# if EFTYPE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EFTYPE -# endif -#endif -#ifdef EAUTH -/* -TRANS ??? */ - [ERR_REMAP (EAUTH)] = N_("Authentication error"), -# if EAUTH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EAUTH -# endif -#endif -#ifdef ENEEDAUTH -/* -TRANS ??? */ - [ERR_REMAP (ENEEDAUTH)] = N_("Need authenticator"), -# if ENEEDAUTH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENEEDAUTH -# endif -#endif -#ifdef ENOSYS -/* -TRANS Function not implemented. This indicates that the function called is -TRANS not implemented at all, either in the C library itself or in the -TRANS operating system. When you get this error, you can be sure that this -TRANS particular function will always fail with @code{ENOSYS} unless you -TRANS install a new version of the C library or the operating system. */ - [ERR_REMAP (ENOSYS)] = N_("Function not implemented"), -# if ENOSYS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOSYS -# endif -#endif -#if defined (ENOTSUP) && ENOTSUP != EOPNOTSUPP -/* -TRANS Not supported. A function returns this error when certain parameter -TRANS values are valid, but the functionality they request is not available. -TRANS This can mean that the function does not implement a particular command -TRANS or option value or flag bit at all. For functions that operate on some -TRANS object given in a parameter, such as a file descriptor or a port, it -TRANS might instead mean that only @emph{that specific object} (file -TRANS descriptor, port, etc.) is unable to support the other parameters given; -TRANS different file descriptors might support different ranges of parameter -TRANS values. -TRANS -TRANS If the entire function is not available at all in the implementation, -TRANS it returns @code{ENOSYS} instead. */ - [ERR_REMAP (ENOTSUP)] = N_("Not supported"), -# if ENOTSUP > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTSUP -# endif -#endif -#ifdef EILSEQ -/* -TRANS While decoding a multibyte character the function came along an invalid -TRANS or an incomplete sequence of bytes or the given wide character is invalid. */ - [ERR_REMAP (EILSEQ)] = N_("Invalid or incomplete multibyte or wide character"), -# if EILSEQ > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EILSEQ -# endif -#endif -#ifdef EBACKGROUND -/* -TRANS In the GNU system, servers supporting the @code{term} protocol return -TRANS this error for certain operations when the caller is not in the -TRANS foreground process group of the terminal. Users do not usually see this -TRANS error because functions such as @code{read} and @code{write} translate -TRANS it into a @code{SIGTTIN} or @code{SIGTTOU} signal. @xref{Job Control}, -TRANS for information on process groups and these signals. */ - [ERR_REMAP (EBACKGROUND)] = N_("Inappropriate operation for background process"), -# if EBACKGROUND > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBACKGROUND -# endif -#endif -#ifdef EDIED -/* -TRANS In the GNU system, opening a file returns this error when the file is -TRANS translated by a program and the translator program dies while starting -TRANS up, before it has connected to the file. */ - [ERR_REMAP (EDIED)] = N_("Translator died"), -# if EDIED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDIED -# endif -#endif -#ifdef ED -/* -TRANS The experienced user will know what is wrong. -TRANS @c This error code is a joke. Its perror text is part of the joke. -TRANS @c Don't change it. */ - [ERR_REMAP (ED)] = N_("?"), -# if ED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ED -# endif -#endif -#ifdef EGREGIOUS -/* -TRANS You did @strong{what}? */ - [ERR_REMAP (EGREGIOUS)] = N_("You really blew it this time"), -# if EGREGIOUS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EGREGIOUS -# endif -#endif -#ifdef EIEIO -/* -TRANS Go home and have a glass of warm, dairy-fresh milk. */ - [ERR_REMAP (EIEIO)] = N_("Computer bought the farm"), -# if EIEIO > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EIEIO -# endif -#endif -#ifdef EGRATUITOUS -/* -TRANS This error code has no purpose. */ - [ERR_REMAP (EGRATUITOUS)] = N_("Gratuitous error"), -# if EGRATUITOUS > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EGRATUITOUS -# endif -#endif -#ifdef EBADMSG -/* */ - [ERR_REMAP (EBADMSG)] = N_("Bad message"), -# if EBADMSG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADMSG -# endif -#endif -#ifdef EIDRM -/* */ - [ERR_REMAP (EIDRM)] = N_("Identifier removed"), -# if EIDRM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EIDRM -# endif -#endif -#ifdef EMULTIHOP -/* */ - [ERR_REMAP (EMULTIHOP)] = N_("Multihop attempted"), -# if EMULTIHOP > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EMULTIHOP -# endif -#endif -#ifdef ENODATA -/* */ - [ERR_REMAP (ENODATA)] = N_("No data available"), -# if ENODATA > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENODATA -# endif -#endif -#ifdef ENOLINK -/* */ - [ERR_REMAP (ENOLINK)] = N_("Link has been severed"), -# if ENOLINK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOLINK -# endif -#endif -#ifdef ENOMSG -/* */ - [ERR_REMAP (ENOMSG)] = N_("No message of desired type"), -# if ENOMSG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOMSG -# endif -#endif -#ifdef ENOSR -/* */ - [ERR_REMAP (ENOSR)] = N_("Out of streams resources"), -# if ENOSR > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOSR -# endif -#endif -#ifdef ENOSTR -/* */ - [ERR_REMAP (ENOSTR)] = N_("Device not a stream"), -# if ENOSTR > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOSTR -# endif -#endif -#ifdef EOVERFLOW -/* */ - [ERR_REMAP (EOVERFLOW)] = N_("Value too large for defined data type"), -# if EOVERFLOW > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EOVERFLOW -# endif -#endif -#ifdef EPROTO -/* */ - [ERR_REMAP (EPROTO)] = N_("Protocol error"), -# if EPROTO > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EPROTO -# endif -#endif -#ifdef ETIME -/* */ - [ERR_REMAP (ETIME)] = N_("Timer expired"), -# if ETIME > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ETIME -# endif -#endif -#ifdef ECANCELED -/* -TRANS Operation canceled; an asynchronous operation was canceled before it -TRANS completed. @xref{Asynchronous I/O}. When you call @code{aio_cancel}, -TRANS the normal result is for the operations affected to complete with this -TRANS error; @pxref{Cancel AIO Operations}. */ - [ERR_REMAP (ECANCELED)] = N_("Operation canceled"), -# if ECANCELED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECANCELED -# endif -#endif -#ifdef ERESTART -/* */ - [ERR_REMAP (ERESTART)] = N_("Interrupted system call should be restarted"), -# if ERESTART > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ERESTART -# endif -#endif -#ifdef ECHRNG -/* */ - [ERR_REMAP (ECHRNG)] = N_("Channel number out of range"), -# if ECHRNG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECHRNG -# endif -#endif -#ifdef EL2NSYNC -/* */ - [ERR_REMAP (EL2NSYNC)] = N_("Level 2 not synchronized"), -# if EL2NSYNC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EL2NSYNC -# endif -#endif -#ifdef EL3HLT -/* */ - [ERR_REMAP (EL3HLT)] = N_("Level 3 halted"), -# if EL3HLT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EL3HLT -# endif -#endif -#ifdef EL3RST -/* */ - [ERR_REMAP (EL3RST)] = N_("Level 3 reset"), -# if EL3RST > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EL3RST -# endif -#endif -#ifdef ELNRNG -/* */ - [ERR_REMAP (ELNRNG)] = N_("Link number out of range"), -# if ELNRNG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELNRNG -# endif -#endif -#ifdef EUNATCH -/* */ - [ERR_REMAP (EUNATCH)] = N_("Protocol driver not attached"), -# if EUNATCH > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EUNATCH -# endif -#endif -#ifdef ENOCSI -/* */ - [ERR_REMAP (ENOCSI)] = N_("No CSI structure available"), -# if ENOCSI > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOCSI -# endif -#endif -#ifdef EL2HLT -/* */ - [ERR_REMAP (EL2HLT)] = N_("Level 2 halted"), -# if EL2HLT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EL2HLT -# endif -#endif -#ifdef EBADE -/* */ - [ERR_REMAP (EBADE)] = N_("Invalid exchange"), -# if EBADE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADE -# endif -#endif -#ifdef EBADR -/* */ - [ERR_REMAP (EBADR)] = N_("Invalid request descriptor"), -# if EBADR > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADR -# endif -#endif -#ifdef EXFULL -/* */ - [ERR_REMAP (EXFULL)] = N_("Exchange full"), -# if EXFULL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EXFULL -# endif -#endif -#ifdef ENOANO -/* */ - [ERR_REMAP (ENOANO)] = N_("No anode"), -# if ENOANO > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOANO -# endif -#endif -#ifdef EBADRQC -/* */ - [ERR_REMAP (EBADRQC)] = N_("Invalid request code"), -# if EBADRQC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADRQC -# endif -#endif -#ifdef EBADSLT -/* */ - [ERR_REMAP (EBADSLT)] = N_("Invalid slot"), -# if EBADSLT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADSLT -# endif -#endif -#if defined (EDEADLOCK) && EDEADLOCK != EDEADLK -/* */ - [ERR_REMAP (EDEADLOCK)] = N_("File locking deadlock error"), -# if EDEADLOCK > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDEADLOCK -# endif -#endif -#ifdef EBFONT -/* */ - [ERR_REMAP (EBFONT)] = N_("Bad font file format"), -# if EBFONT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBFONT -# endif -#endif -#ifdef ENONET -/* */ - [ERR_REMAP (ENONET)] = N_("Machine is not on the network"), -# if ENONET > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENONET -# endif -#endif -#ifdef ENOPKG -/* */ - [ERR_REMAP (ENOPKG)] = N_("Package not installed"), -# if ENOPKG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOPKG -# endif -#endif -#ifdef EADV -/* */ - [ERR_REMAP (EADV)] = N_("Advertise error"), -# if EADV > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EADV -# endif -#endif -#ifdef ESRMNT -/* */ - [ERR_REMAP (ESRMNT)] = N_("Srmount error"), -# if ESRMNT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESRMNT -# endif -#endif -#ifdef ECOMM -/* */ - [ERR_REMAP (ECOMM)] = N_("Communication error on send"), -# if ECOMM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ECOMM -# endif -#endif -#ifdef EDOTDOT -/* */ - [ERR_REMAP (EDOTDOT)] = N_("RFS specific error"), -# if EDOTDOT > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EDOTDOT -# endif -#endif -#ifdef ENOTUNIQ -/* */ - [ERR_REMAP (ENOTUNIQ)] = N_("Name not unique on network"), -# if ENOTUNIQ > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTUNIQ -# endif -#endif -#ifdef EBADFD -/* */ - [ERR_REMAP (EBADFD)] = N_("File descriptor in bad state"), -# if EBADFD > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EBADFD -# endif -#endif -#ifdef EREMCHG -/* */ - [ERR_REMAP (EREMCHG)] = N_("Remote address changed"), -# if EREMCHG > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EREMCHG -# endif -#endif -#ifdef ELIBACC -/* */ - [ERR_REMAP (ELIBACC)] = N_("Can not access a needed shared library"), -# if ELIBACC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELIBACC -# endif -#endif -#ifdef ELIBBAD -/* */ - [ERR_REMAP (ELIBBAD)] = N_("Accessing a corrupted shared library"), -# if ELIBBAD > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELIBBAD -# endif -#endif -#ifdef ELIBSCN -/* */ - [ERR_REMAP (ELIBSCN)] = N_(".lib section in a.out corrupted"), -# if ELIBSCN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELIBSCN -# endif -#endif -#ifdef ELIBMAX -/* */ - [ERR_REMAP (ELIBMAX)] = N_("Attempting to link in too many shared libraries"), -# if ELIBMAX > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELIBMAX -# endif -#endif -#ifdef ELIBEXEC -/* */ - [ERR_REMAP (ELIBEXEC)] = N_("Cannot exec a shared library directly"), -# if ELIBEXEC > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ELIBEXEC -# endif -#endif -#ifdef ESTRPIPE -/* */ - [ERR_REMAP (ESTRPIPE)] = N_("Streams pipe error"), -# if ESTRPIPE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ESTRPIPE -# endif -#endif -#ifdef EUCLEAN -/* */ - [ERR_REMAP (EUCLEAN)] = N_("Structure needs cleaning"), -# if EUCLEAN > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EUCLEAN -# endif -#endif -#ifdef ENOTNAM -/* */ - [ERR_REMAP (ENOTNAM)] = N_("Not a XENIX named type file"), -# if ENOTNAM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTNAM -# endif -#endif -#ifdef ENAVAIL -/* */ - [ERR_REMAP (ENAVAIL)] = N_("No XENIX semaphores available"), -# if ENAVAIL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENAVAIL -# endif -#endif -#ifdef EISNAM -/* */ - [ERR_REMAP (EISNAM)] = N_("Is a named type file"), -# if EISNAM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EISNAM -# endif -#endif -#ifdef EREMOTEIO -/* */ - [ERR_REMAP (EREMOTEIO)] = N_("Remote I/O error"), -# if EREMOTEIO > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EREMOTEIO -# endif -#endif -#ifdef ENOMEDIUM -/* */ - [ERR_REMAP (ENOMEDIUM)] = N_("No medium found"), -# if ENOMEDIUM > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOMEDIUM -# endif -#endif -#ifdef EMEDIUMTYPE -/* */ - [ERR_REMAP (EMEDIUMTYPE)] = N_("Wrong medium type"), -# if EMEDIUMTYPE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EMEDIUMTYPE -# endif -#endif -#ifdef ENOKEY -/* */ - [ERR_REMAP (ENOKEY)] = N_("Required key not available"), -# if ENOKEY > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOKEY -# endif -#endif -#ifdef EKEYEXPIRED -/* */ - [ERR_REMAP (EKEYEXPIRED)] = N_("Key has expired"), -# if EKEYEXPIRED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EKEYEXPIRED -# endif -#endif -#ifdef EKEYREVOKED -/* */ - [ERR_REMAP (EKEYREVOKED)] = N_("Key has been revoked"), -# if EKEYREVOKED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EKEYREVOKED -# endif -#endif -#ifdef EKEYREJECTED -/* */ - [ERR_REMAP (EKEYREJECTED)] = N_("Key was rejected by service"), -# if EKEYREJECTED > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EKEYREJECTED -# endif -#endif -#ifdef EOWNERDEAD -/* */ - [ERR_REMAP (EOWNERDEAD)] = N_("Owner died"), -# if EOWNERDEAD > ERR_MAX -# undef ERR_MAX -# define ERR_MAX EOWNERDEAD -# endif -#endif -#ifdef ENOTRECOVERABLE -/* */ - [ERR_REMAP (ENOTRECOVERABLE)] = N_("State not recoverable"), -# if ENOTRECOVERABLE > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ENOTRECOVERABLE -# endif -#endif -#ifdef ERFKILL -/* */ - [ERR_REMAP (ERFKILL)] = N_("Operation not possible due to RF-kill"), -# if ERFKILL > ERR_MAX -# undef ERR_MAX -# define ERR_MAX ERFKILL -# endif -#endif - }; - -#define NERR \ - (sizeof __sys_errlist_internal / sizeof __sys_errlist_internal [0]) - -#ifdef EMIT_ERR_MAX -void dummy (void) -{ asm volatile (" @@@ %0 @@@ " : : "i" (ERR_REMAP (ERR_MAX))); } -#endif diff --git a/Pal/lib/crypto/aes.c b/Pal/lib/crypto/aes.c index c1f96f93..8e66563e 100644 --- a/Pal/lib/crypto/aes.c +++ b/Pal/lib/crypto/aes.c @@ -28,6 +28,7 @@ #define XMEMSET memset #define XMEMCPY memcpy +#define XMEMCMP memcmp #ifndef rotlFixed static inline word32 rotlFixed(word32 x, word32 y) @@ -1334,7 +1335,7 @@ int AESCBCDecrypt(AES *aes, byte *out, const byte *in, word32 sz) } /* Increment AES counter */ -static inline void IncrementAESCounter(byte* inOutCTR) +static inline void IncrementAESCounter(byte *inOutCTR) { int i; @@ -1383,4 +1384,336 @@ void AESCTREncrypt(AES *aes, byte *out, const byte *in, word32 sz) } } +enum { + CTR_SZ = 4 +}; +static inline void InitGCMCounter(byte *inOutCtr) +{ + inOutCtr[AES_BLOCK_SIZE - 4] = 0; + inOutCtr[AES_BLOCK_SIZE - 3] = 0; + inOutCtr[AES_BLOCK_SIZE - 2] = 0; + inOutCtr[AES_BLOCK_SIZE - 1] = 1; +} + +static inline void IncrementGCMCounter(byte *inOutCtr) +{ + int i; + + /* in network byte order so start at end and work back */ + for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) { + if (++inOutCtr[i]) /* we're done unless we overflow */ + return; + } +} + +static inline void FlattenSzInBits(byte *buf, word32 sz) +{ + /* Multiply the sz by 8 */ + word32 szHi = (sz >> (8*sizeof(sz) - 3)); + sz <<= 3; + + /* copy over the words of the sz into the destination buffer */ + buf[0] = (szHi >> 24) & 0xff; + buf[1] = (szHi >> 16) & 0xff; + buf[2] = (szHi >> 8) & 0xff; + buf[3] = szHi & 0xff; + buf[4] = (sz >> 24) & 0xff; + buf[5] = (sz >> 16) & 0xff; + buf[6] = (sz >> 8) & 0xff; + buf[7] = sz & 0xff; +} + +static inline void RIGHTSHIFTX(byte *x) +{ + int i; + int carryOut = 0; + int carryIn = 0; + int borrow = x[15] & 0x01; + + for (i = 0; i < AES_BLOCK_SIZE; i++) { + carryOut = x[i] & 0x01; + x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0); + carryIn = carryOut; + } + if (borrow) x[0] ^= 0xE1; +} + +static void GenerateM0(AES *aes) +{ + int i, j; + byte (*m)[AES_BLOCK_SIZE] = aes->M0; + + XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE); + + for (i = 64; i > 0; i /= 2) { + XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE); + RIGHTSHIFTX(m[i]); + } + + for (i = 2; i < 256; i *= 2) { + for (j = 1; j < i; j++) { + XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE); + xorbuf(m[i+j], m[j], AES_BLOCK_SIZE); + } + } + + XMEMSET(m[0], 0, AES_BLOCK_SIZE); +} + +int AESGCMSetKey(AES* aes, const byte* key, word32 len) +{ + int ret; + byte iv[AES_BLOCK_SIZE]; + + if (!((len == 16) || (len == 24) || (len == 32))) + return BAD_FUNC_ARG; + + XMEMSET(iv, 0, AES_BLOCK_SIZE); + ret = AESSetKey(aes, key, len, iv, AES_ENCRYPTION); + + if (ret == 0) { + AESEncrypt(aes, iv, aes->H); + GenerateM0(aes); + } + + return ret; +} + +static const byte R[256][2] = { + {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46}, + {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e}, + {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56}, + {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e}, + {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66}, + {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e}, + {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76}, + {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e}, + {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06}, + {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e}, + {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16}, + {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e}, + {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26}, + {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e}, + {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36}, + {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e}, + {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6}, + {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce}, + {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6}, + {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde}, + {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6}, + {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee}, + {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6}, + {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe}, + {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86}, + {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e}, + {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96}, + {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e}, + {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6}, + {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae}, + {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6}, + {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe}, + {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46}, + {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e}, + {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56}, + {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e}, + {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66}, + {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e}, + {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76}, + {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e}, + {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06}, + {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e}, + {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16}, + {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e}, + {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26}, + {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e}, + {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36}, + {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e}, + {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6}, + {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce}, + {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6}, + {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde}, + {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6}, + {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee}, + {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6}, + {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe}, + {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86}, + {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e}, + {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96}, + {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e}, + {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6}, + {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae}, + {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6}, + {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} }; + +static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE]) +{ + int i, j; + byte Z[AES_BLOCK_SIZE]; + byte a; + + XMEMSET(Z, 0, sizeof(Z)); + + for (i = 15; i > 0; i--) { + xorbuf(Z, m[x[i]], AES_BLOCK_SIZE); + a = Z[15]; + + for (j = 15; j > 0; j--) { + Z[j] = Z[j-1]; + } + + Z[0] = R[a][0]; + Z[1] ^= R[a][1]; + } + xorbuf(Z, m[x[0]], AES_BLOCK_SIZE); + + XMEMCPY(x, Z, AES_BLOCK_SIZE); +} + +static void GHASH(AES *aes, const byte *a, word32 aSz, + const byte *c, word32 cSz, byte *s, word32 sSz) +{ + byte x[AES_BLOCK_SIZE]; + byte scratch[AES_BLOCK_SIZE]; + word32 blocks, partial; + + XMEMSET(x, 0, AES_BLOCK_SIZE); + + /* Hash in A, the Additional Authentication Data */ + if (aSz != 0 && a != NULL) { + blocks = aSz / AES_BLOCK_SIZE; + partial = aSz % AES_BLOCK_SIZE; + while (blocks--) { + xorbuf(x, a, AES_BLOCK_SIZE); + GMULT(x, aes->M0); + a += AES_BLOCK_SIZE; + } + if (partial != 0) { + XMEMSET(scratch, 0, AES_BLOCK_SIZE); + XMEMCPY(scratch, a, partial); + xorbuf(x, scratch, AES_BLOCK_SIZE); + GMULT(x, aes->M0); + } + } + + /* Hash in C, the Ciphertext */ + if (cSz != 0 && c != NULL) { + blocks = cSz / AES_BLOCK_SIZE; + partial = cSz % AES_BLOCK_SIZE; + while (blocks--) { + xorbuf(x, c, AES_BLOCK_SIZE); + GMULT(x, aes->M0); + c += AES_BLOCK_SIZE; + } + if (partial != 0) { + XMEMSET(scratch, 0, AES_BLOCK_SIZE); + XMEMCPY(scratch, c, partial); + xorbuf(x, scratch, AES_BLOCK_SIZE); + GMULT(x, aes->M0); + } + } + + /* Hash in the lengths of A and C in bits */ + FlattenSzInBits(&scratch[0], aSz); + FlattenSzInBits(&scratch[8], cSz); + xorbuf(x, scratch, AES_BLOCK_SIZE); + GMULT(x, aes->M0); + + /* Copy the result into s. */ + XMEMCPY(s, x, sSz); +} + +int AESGCMEncrypt(AES *aes, byte *out, const byte *in, word32 sz, + const byte *iv, word32 ivSz, + byte *authTag, word32 authTagSz, + const byte *authIn, word32 authInSz) +{ + word32 blocks = sz / AES_BLOCK_SIZE; + word32 partial = sz % AES_BLOCK_SIZE; + const byte *p = in; + byte *c = out; + byte counter[AES_BLOCK_SIZE]; + byte *ctr; + byte scratch[AES_BLOCK_SIZE]; + + ctr = counter; + + XMEMSET(ctr, 0, AES_BLOCK_SIZE); + XMEMCPY(ctr, iv, ivSz); + InitGCMCounter(ctr); + + while (blocks--) { + IncrementGCMCounter(ctr); + AESEncrypt(aes, ctr, scratch); + xorbuf(scratch, p, AES_BLOCK_SIZE); + XMEMCPY(c, scratch, AES_BLOCK_SIZE); + p += AES_BLOCK_SIZE; + c += AES_BLOCK_SIZE; + } + + if (partial != 0) { + IncrementGCMCounter(ctr); + AESEncrypt(aes, ctr, scratch); + xorbuf(scratch, p, partial); + XMEMCPY(c, scratch, partial); + + } + + GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz); + InitGCMCounter(ctr); + AESEncrypt(aes, ctr, scratch); + xorbuf(authTag, scratch, authTagSz); + + return 0; +} + +int AESGCMDecrypt(AES *aes, byte *out, const byte *in, word32 sz, + const byte *iv, word32 ivSz, + const byte *authTag, word32 authTagSz, + const byte *authIn, word32 authInSz) +{ + word32 blocks = sz / AES_BLOCK_SIZE; + word32 partial = sz % AES_BLOCK_SIZE; + const byte *c = in; + byte *p = out; + byte counter[AES_BLOCK_SIZE]; + byte *ctr ; + byte scratch[AES_BLOCK_SIZE]; + + ctr = counter; + + XMEMSET(ctr, 0, AES_BLOCK_SIZE); + XMEMCPY(ctr, iv, ivSz); + InitGCMCounter(ctr); + + /* Calculate the authTag again using the received auth data and the + * cipher text. */ + { + byte Tprime[AES_BLOCK_SIZE]; + byte EKY0[AES_BLOCK_SIZE]; + + GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime)); + AESEncrypt(aes, ctr, EKY0); + xorbuf(Tprime, EKY0, sizeof(Tprime)); + + if (XMEMCMP(authTag, Tprime, authTagSz) != 0) { + return AES_GCM_AUTH_E; + } + } + + while (blocks--) { + IncrementGCMCounter(ctr); + AESEncrypt(aes, ctr, scratch); + xorbuf(scratch, c, AES_BLOCK_SIZE); + XMEMCPY(p, scratch, AES_BLOCK_SIZE); + p += AES_BLOCK_SIZE; + c += AES_BLOCK_SIZE; + } + if (partial != 0) { + IncrementGCMCounter(ctr); + AESEncrypt(aes, ctr, scratch); + xorbuf(scratch, c, partial); + XMEMCPY(p, scratch, partial); + } + return 0; +} diff --git a/Pal/lib/crypto/aes.h b/Pal/lib/crypto/aes.h index 6e2fbcf6..fec4150c 100644 --- a/Pal/lib/crypto/aes.h +++ b/Pal/lib/crypto/aes.h @@ -61,6 +61,10 @@ typedef struct AES { ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)]; /* for CBC mode */ ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)]; /* same */ word32 left; + + ALIGN16 byte H[AES_BLOCK_SIZE]; + /* key-based fast multiplication table. */ + ALIGN16 byte M0[256][AES_BLOCK_SIZE]; } AES; int AESSetKey(AES *aes, const byte *key, word32 len, const byte *iv, @@ -73,5 +77,14 @@ int AESCBCDecrypt(AES *aes, byte *out, const byte *in, word32 sz); int AESCBCDecryptWithKey(byte *out, const byte *in, word32 inSz, const byte *key, word32 keySz, const byte *iv); void AESCTREncrypt(AES *aes, byte *out, const byte *in, word32 sz); +int AESGCMSetKey(AES *aes, const byte *key, word32 len); +int AESGCMEncrypt(AES *aes, byte *out, const byte *in, word32 sz, + const byte *iv, word32 ivSz, + byte* authTag, word32 authTagSz, + const byte *authIn, word32 authInSz); +int AESGCMDecrypt(AES *aes, byte *out, const byte *in, word32 sz, + const byte *iv, word32 ivSz, + const byte *authTag, word32 authTagSz, + const byte *authIn, word32 authInSz); #endif /* CTAO_CRYPT_AES_H */ diff --git a/Pal/regression/Process3.c b/Pal/regression/Process3.c index 6658b64d..46140e91 100644 --- a/Pal/regression/Process3.c +++ b/Pal/regression/Process3.c @@ -8,10 +8,14 @@ int main (int argc, char ** argv, char ** envp) { PAL_STR args[1] = { 0 }; - PAL_HANDLE child = DkProcessCreate(NULL, 0, args); - if (child) - pal_printf("Create Process without Executable OK\n"); + // Hack to differentiate parent from child + if (argc == 1) { + PAL_HANDLE child = DkProcessCreate(NULL, 0, args); + + if (child) + pal_printf("Create Process without Executable OK\n"); + } return 0; } diff --git a/Pal/src/db_events.c b/Pal/src/db_events.c index c0ab4ac8..030a4590 100644 --- a/Pal/src/db_events.c +++ b/Pal/src/db_events.c @@ -128,10 +128,10 @@ static int event_close (PAL_HANDLE handle) return _DkEventClear(handle); } -static int event_wait (PAL_HANDLE handle, int timeout) +static int event_wait (PAL_HANDLE handle, uint64_t timeout) { - return timeout >=0 ? _DkEventWaitTimeout(handle, timeout) : - _DkEventWait(handle); + return timeout == NO_TIMEOUT ? _DkEventWait(handle) : + _DkEventWaitTimeout(handle, timeout); } struct handle_ops event_ops = { diff --git a/Pal/src/db_main.c b/Pal/src/db_main.c index 98db3d51..99ecb7b6 100644 --- a/Pal/src/db_main.c +++ b/Pal/src/db_main.c @@ -33,7 +33,6 @@ #include #include -#include PAL_CONTROL __pal_control; @@ -347,6 +346,40 @@ has_manifest: } } + /* If we still don't have an exec in the manifest, but we have a manifest + * try implicitly from the manifest name */ + if ((!exec_handle) && manifest_uri) { + size_t manifest_strlen = strlen(manifest_uri); + size_t exec_strlen = manifest_strlen - 9; + int success = 0; + // Try .manifest + if (strcmp_static(&manifest_uri[exec_strlen], ".manifest")) { + success = 1; + } else { + exec_strlen -= 4; + if (strcmp_static(&manifest_uri[exec_strlen], ".manifest.sgx")) { + success = 1; + } + } + + if (success) { + exec_uri = malloc(exec_strlen + 1); + if (!exec_uri) + init_fail(-PAL_ERROR_NOMEM, "Cannot allocate URI buf"); + memcpy (exec_uri, manifest_uri, exec_strlen); + exec_uri[exec_strlen] = '\0'; + ret = _DkStreamOpen(&exec_handle, exec_uri, PAL_ACCESS_RDONLY, + 0, 0, 0); + // DEP 3/20/17: There are cases where we want to let + // the PAL start up without a main executable. Don't + // die here, just free the exec_uri buffer. + if (ret < 0) { + free(exec_uri); + exec_uri = NULL; + } + } + } + /* must be a ELF */ if (exec_handle && check_elf_object(exec_handle) < 0) init_fail(PAL_ERROR_INVAL, "executable is not a ELF binary"); diff --git a/Pal/src/db_process.c b/Pal/src/db_process.c index bd569e17..9293f3f3 100644 --- a/Pal/src/db_process.c +++ b/Pal/src/db_process.c @@ -40,6 +40,13 @@ DkProcessCreate (PAL_STR uri, PAL_FLG flags, PAL_STR * args) { ENTER_PAL_CALL(DkProcessCreate); + /* DEP 3/22/17: There seems to be a default semantics that + * a NULL URI should replicate the parent. I think we may want + * this to become an error in the future, but keep the behavior + * for now, and make it consistent across hosts. */ + if (!uri) + uri = pal_control.executable; + log_stream(uri); PAL_HANDLE handle = NULL; diff --git a/Pal/src/db_rtld.c b/Pal/src/db_rtld.c index a7a83b2f..674ddcae 100644 --- a/Pal/src/db_rtld.c +++ b/Pal/src/db_rtld.c @@ -36,7 +36,6 @@ #include #include -#include struct link_map * loaded_maps = NULL; struct link_map * exec_map = NULL; diff --git a/Pal/src/db_semaphore.c b/Pal/src/db_semaphore.c index ca9c0970..53911a0a 100644 --- a/Pal/src/db_semaphore.c +++ b/Pal/src/db_semaphore.c @@ -75,7 +75,7 @@ void DkSemaphoreRelease (PAL_HANDLE handle, PAL_NUM count) LEAVE_PAL_CALL(); } -static int sem_wait (PAL_HANDLE handle, int timeout) +static int sem_wait (PAL_HANDLE handle, uint64_t timeout) { return _DkSemaphoreAcquireTimeout(handle, 1, timeout); } diff --git a/Pal/src/db_streams.c b/Pal/src/db_streams.c index 71e1bcdd..df928cc2 100644 --- a/Pal/src/db_streams.c +++ b/Pal/src/db_streams.c @@ -618,7 +618,7 @@ void DkStreamUnmap (PAL_PTR addr, PAL_NUM size) /* _DkStreamSetLength for internal use. This function truncate the stream to certain length. This call might not be support for certain streams */ -uint64_t _DkStreamSetLength (PAL_HANDLE handle, uint64_t length) +int64_t _DkStreamSetLength (PAL_HANDLE handle, uint64_t length) { if (UNKNOWN_HANDLE(handle)) return -PAL_ERROR_BADHANDLE; @@ -643,7 +643,7 @@ DkStreamSetLength (PAL_HANDLE handle, PAL_NUM length) LEAVE_PAL_CALL_RETURN(0); } - uint64_t ret = _DkStreamSetLength(handle, length); + int64_t ret = _DkStreamSetLength(handle, length); if (ret < 0) { _DkRaiseFailure(-ret); diff --git a/Pal/src/host/Linux-SGX/Makefile b/Pal/src/host/Linux-SGX/Makefile index f9301c5e..d2f056fd 100644 --- a/Pal/src/host/Linux-SGX/Makefile +++ b/Pal/src/host/Linux-SGX/Makefile @@ -1,6 +1,6 @@ include Makefile.am -CFLAGS += -I. -Iinclude -I../.. -I../../../include -I../../../lib +CFLAGS += -I. -Iinclude -I../.. -I../../../include -I../../../lib -Isgx-driver ASFLAGS += -I. -I../.. -I../../../include host_files = libpal-Linux-SGX.a pal-sgx debugger/sgx_gdb.so @@ -14,7 +14,8 @@ enclave-asm-objs = enclave_entry urts-objs = $(addprefix sgx_,enclave framework main rtld thread process exception graphene) urts-asm-objs = sgx_entry graphene_lib = ../../.lib/graphene-lib.a -headers = $(wildcard *.h) $(wildcard ../../*.h) $(wildcard ../../../lib/*.h) +headers = $(wildcard *.h) $(wildcard ../../*.h) $(wildcard ../../../lib/*.h) \ + $(addprefix sgx-driver/,graphene-sgx.h isgx_version.h) all: $(host_files) @@ -64,6 +65,9 @@ debugger/sgx_gdb.so: debugger/sgx_gdb.c debugger/sgx_gdb.h sgx_arch.h $(CC) -Wall -fPIC -O2 -std=gnu99 -fgnu89-inline -c debugger/sgx_gdb.c -o debugger/sgx_gdb.o $(LD) -shared debugger/sgx_gdb.o -o debugger/sgx_gdb.so -lc +sgx-driver/isgx_version.h: + cd sgx-driver && make isgx_version.h + ../../libpal.so: ../../libpal-enclave.so ln -s libpal-enclave.so $@ diff --git a/Pal/src/host/Linux-SGX/db_events.c b/Pal/src/host/Linux-SGX/db_events.c index 4c70d4e3..2754f6fa 100644 --- a/Pal/src/host/Linux-SGX/db_events.c +++ b/Pal/src/host/Linux-SGX/db_events.c @@ -81,7 +81,7 @@ int _DkEventSet (PAL_HANDLE event, int wakeup) return ret; } -int _DkEventWaitTimeout (PAL_HANDLE event, int timeout) +int _DkEventWaitTimeout (PAL_HANDLE event, uint64_t timeout) { int ret = 0; diff --git a/Pal/src/host/Linux-SGX/db_files.c b/Pal/src/host/Linux-SGX/db_files.c index 02b1232d..39ff216b 100644 --- a/Pal/src/host/Linux-SGX/db_files.c +++ b/Pal/src/host/Linux-SGX/db_files.c @@ -243,13 +243,13 @@ static int file_map (PAL_HANDLE handle, void ** addr, int prot, } /* 'setlength' operation for file stream. */ -static uint64_t file_setlength (PAL_HANDLE handle, uint64_t length) +static int64_t file_setlength (PAL_HANDLE handle, uint64_t length) { int ret = ocall_ftruncate(handle->file.fd, length); if (ret < 0) return ret; handle->file.total = length; - return length; + return (int64_t) length; } /* 'flush' operation for file stream. */ @@ -330,7 +330,7 @@ static int file_attrsetbyhdl (PAL_HANDLE handle, PAL_STREAM_ATTR * attr) { int fd = HANDLE_HDR(handle)->fds[0]; - int ret = ocall_fchmod(fd, attr->share_flags); + int ret = ocall_fchmod(fd, attr->share_flags | 0600); if (ret < 0) return ret; diff --git a/Pal/src/host/Linux-SGX/db_object.c b/Pal/src/host/Linux-SGX/db_object.c index 56f74195..92dfad34 100644 --- a/Pal/src/host/Linux-SGX/db_object.c +++ b/Pal/src/host/Linux-SGX/db_object.c @@ -42,7 +42,7 @@ /* internally to wait for one object. Also used as a shortcut to wait on events and semaphores */ -static int _DkObjectWaitOne (PAL_HANDLE handle, int timeout) +static int _DkObjectWaitOne (PAL_HANDLE handle, uint64_t timeout) { /* only for all these handle which has a file descriptor, or a eventfd. events and semaphores will skip this part */ @@ -74,7 +74,7 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, int timeout) if (!nfds) return -PAL_ERROR_TRYAGAIN; - unsigned long waittime = timeout; + uint64_t waittime = timeout; int ret = ocall_poll(fds, nfds, timeout >= 0 ? &waittime : NULL); if (ret < 0) return ret; @@ -104,7 +104,7 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, int timeout) /* _DkObjectsWaitAny for internal use. The function wait for any of the handle in the handle array. timeout can be set for the wait. */ -int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, int timeout, +int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, uint64_t timeout, PAL_HANDLE * polled) { if (count <= 0) @@ -180,7 +180,7 @@ int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, int timeout, if (!nfds) return -PAL_ERROR_TRYAGAIN; - unsigned long waittime = timeout; + uint64_t waittime = timeout; ret = ocall_poll(fds, nfds, timeout >= 0 ? &waittime : NULL); if (ret < 0) return ret; diff --git a/Pal/src/host/Linux-SGX/db_rtld.c b/Pal/src/host/Linux-SGX/db_rtld.c index 18fbae8e..6a431b1b 100644 --- a/Pal/src/host/Linux-SGX/db_rtld.c +++ b/Pal/src/host/Linux-SGX/db_rtld.c @@ -39,7 +39,6 @@ #include #include -#include #include "elf-x86_64.h" diff --git a/Pal/src/host/Linux-SGX/db_semaphore.c b/Pal/src/host/Linux-SGX/db_semaphore.c index 85b46e43..d8ea59aa 100644 --- a/Pal/src/host/Linux-SGX/db_semaphore.c +++ b/Pal/src/host/Linux-SGX/db_semaphore.c @@ -146,7 +146,7 @@ int _DkSemaphoreAcquire (PAL_HANDLE sem, int count) return ret; } -int _DkSemaphoreAcquireTimeout (PAL_HANDLE sem, int count, int timeout) +int _DkSemaphoreAcquireTimeout (PAL_HANDLE sem, int count, uint64_t timeout) { /* Pass it up to the no-timeout version if no timeout requested */ if (timeout == -1) diff --git a/Pal/src/host/Linux-SGX/enclave_framework.c b/Pal/src/host/Linux-SGX/enclave_framework.c index e00563b0..2ee2ad1f 100644 --- a/Pal/src/host/Linux-SGX/enclave_framework.c +++ b/Pal/src/host/Linux-SGX/enclave_framework.c @@ -124,7 +124,8 @@ int load_trusted_file (PAL_HANDLE file, sgx_arch_mac_t ** stubptr, { struct trusted_file * tf = NULL, * tmp; char uri[URI_MAX]; - int ret, fd = HANDLE_HDR(file)->fds[0], uri_len; + char normpath[URI_MAX]; + int ret, fd = HANDLE_HDR(file)->fds[0], uri_len, len; if (!(HANDLE_HDR(file)->flags & RFD(0))) return -PAL_ERROR_DENIED; @@ -133,24 +134,38 @@ int load_trusted_file (PAL_HANDLE file, sgx_arch_mac_t ** stubptr, if (uri_len < 0) return uri_len; + /* Normalize the uri */ + if (!strpartcmp_static(uri, "file:")) { + SGX_DBG(DBG_E, "Invalid URI [%s]: Trusted files must start with 'file:'\n", uri);; + return -PAL_ERROR_INVAL; + } + normpath [0] = 'f'; + normpath [1] = 'i'; + normpath [2] = 'l'; + normpath [3] = 'e'; + normpath [4] = ':'; + len = get_norm_path(uri + 5, normpath + 5, 0, URI_MAX); + uri_len = len + 5; + _DkSpinLock(&trusted_file_lock); - list_for_each_entry(tmp, &trusted_file_list, list) + list_for_each_entry(tmp, &trusted_file_list, list) { if (tmp->stubs) { /* trusted files: must be exactly the same URI */ - if (tmp->uri_len == uri_len && !memcmp(tmp->uri, uri, uri_len + 1)) { + if (tmp->uri_len == uri_len && !memcmp(tmp->uri, normpath, uri_len + 1)) { tf = tmp; break; } } else { /* allowed files: must be a subfolder or file */ if (tmp->uri_len <= uri_len && - !memcmp(tmp->uri, uri, tmp->uri_len) && - (!uri[tmp->uri_len] || uri[tmp->uri_len] == '/')) { + !memcmp(tmp->uri, normpath, tmp->uri_len) && + (!normpath[tmp->uri_len] || normpath[tmp->uri_len] == '/')) { tf = tmp; break; } } + } _DkSpinUnlock(&trusted_file_lock); @@ -171,7 +186,7 @@ int load_trusted_file (PAL_HANDLE file, sgx_arch_mac_t ** stubptr, if (!tf->index) { *stubptr = NULL; PAL_STREAM_ATTR attr; - ret = _DkStreamAttributesQuery(uri, &attr); + ret = _DkStreamAttributesQuery(normpath, &attr); if (!ret) *sizeptr = attr.pending_size; else @@ -248,6 +263,16 @@ failed: } _DkSpinUnlock(&trusted_file_lock); +#if PRINT_ENCLAVE_STAT + if (!ret) { + sgx_stub_t * loaded_stub; + uint64_t loaded_size; + PAL_HANDLE handle = NULL; + if (!_DkStreamOpen(&handle, normpath, PAL_ACCESS_RDONLY, 0, 0, 0)) + load_trusted_file (handle, &loaded_stub, &loaded_size); + } +#endif + return ret; } @@ -377,7 +402,8 @@ static int init_trusted_file (const char * key, const char * uri) { char cskey[URI_MAX], * tmp; char checksum[URI_MAX]; - + char normpath[URI_MAX]; + tmp = strcpy_static(cskey, "sgx.trusted_checksum.", URI_MAX); memcpy(tmp, key, strlen(key) + 1); @@ -385,7 +411,19 @@ static int init_trusted_file (const char * key, const char * uri) if (len < 0) return 0; - return register_trusted_file(uri, checksum); + /* Normalize the uri */ + if (!strpartcmp_static(uri, "file:")) { + SGX_DBG(DBG_E, "Invalid URI [%s]: Trusted files must start with 'file:'\n", uri); + return -PAL_ERROR_INVAL; + } + normpath [0] = 'f'; + normpath [1] = 'i'; + normpath [2] = 'l'; + normpath [3] = 'e'; + normpath [4] = ':'; + len = get_norm_path(uri + 5, normpath + 5, 0, URI_MAX); + + return register_trusted_file(normpath, checksum); } int init_trusted_files (void) diff --git a/Pal/src/host/Linux-SGX/enclave_ocalls.c b/Pal/src/host/Linux-SGX/enclave_ocalls.c index e24c90bc..6d2a4708 100644 --- a/Pal/src/host/Linux-SGX/enclave_ocalls.c +++ b/Pal/src/host/Linux-SGX/enclave_ocalls.c @@ -425,7 +425,7 @@ int ocall_create_process (const char * uri, } int ocall_futex (int * futex, int op, int val, - const unsigned long * timeout) + const uint64_t * timeout) { int retval = 0; ms_ocall_futex_t * ms; @@ -439,7 +439,7 @@ int ocall_futex (int * futex, int op, int val, ms->ms_futex = futex; ms->ms_op = op; ms->ms_val = val; - ms->ms_timeout = timeout ? *timeout : (unsigned long) -1; + ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT; retval = SGX_OCALL(OCALL_FUTEX, ms); OCALL_EXIT(); @@ -718,7 +718,7 @@ int ocall_sleep (unsigned long * microsec) return retval; } -int ocall_poll (struct pollfd * fds, int nfds, unsigned long * timeout) +int ocall_poll (struct pollfd * fds, int nfds, uint64_t * timeout) { int retval = 0; ms_ocall_poll_t * ms; @@ -726,7 +726,7 @@ int ocall_poll (struct pollfd * fds, int nfds, unsigned long * timeout) ms->ms_fds = COPY_TO_USER(fds, sizeof(struct pollfd) * nfds); ms->ms_nfds = nfds; - ms->ms_timeout = timeout ? *timeout : (unsigned long) -1; + ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT; retval = SGX_OCALL(OCALL_POLL, ms); if (retval == -EINTR && timeout) diff --git a/Pal/src/host/Linux-SGX/enclave_ocalls.h b/Pal/src/host/Linux-SGX/enclave_ocalls.h index 7baa7f07..64df71e9 100644 --- a/Pal/src/host/Linux-SGX/enclave_ocalls.h +++ b/Pal/src/host/Linux-SGX/enclave_ocalls.h @@ -88,7 +88,7 @@ int ocall_create_process (const char * uri, int procfds[3], unsigned int * pid); -int ocall_futex (int * uaddr, int op, int val, const unsigned long * timeout); +int ocall_futex (int * uaddr, int op, int val, const uint64_t * timeout); int ocall_gettime (unsigned long * microsec); @@ -96,7 +96,7 @@ int ocall_sleep (unsigned long * microsec); int ocall_socketpair (int domain, int type, int protocol, int sockfds[2]); -int ocall_poll (struct pollfd * fds, int nfds, unsigned long * microsec); +int ocall_poll (struct pollfd * fds, int nfds, uint64_t * timeout); int ocall_rename (const char * oldpath, const char * newpath); diff --git a/Pal/src/host/Linux-SGX/ocall_types.h b/Pal/src/host/Linux-SGX/ocall_types.h index 40d85a0b..150b3f35 100644 --- a/Pal/src/host/Linux-SGX/ocall_types.h +++ b/Pal/src/host/Linux-SGX/ocall_types.h @@ -48,6 +48,8 @@ enum { OCALL_NR, }; +#define OCALL_NO_TIMEOUT ((uint64_t) -1) + typedef struct { const char * ms_str; int ms_length; @@ -154,7 +156,7 @@ typedef struct { typedef struct { int * ms_futex; int ms_op, ms_val; - unsigned long ms_timeout; + uint64_t ms_timeout; } ms_ocall_futex_t; typedef struct { @@ -241,7 +243,7 @@ typedef struct { typedef struct { struct pollfd * ms_fds; int ms_nfds; - unsigned long ms_timeout; + uint64_t ms_timeout; } ms_ocall_poll_t; typedef struct { diff --git a/Pal/src/host/Linux-SGX/sgx-driver/.gitignore b/Pal/src/host/Linux-SGX/sgx-driver/.gitignore index 511bc34d..26286649 100644 --- a/Pal/src/host/Linux-SGX/sgx-driver/.gitignore +++ b/Pal/src/host/Linux-SGX/sgx-driver/.gitignore @@ -7,3 +7,4 @@ Module.symvers modules.order .tmp_versions linux-sgx-driver +isgx_version.h diff --git a/Pal/src/host/Linux-SGX/sgx-driver/Makefile b/Pal/src/host/Linux-SGX/sgx-driver/Makefile index 73081f26..1015c719 100644 --- a/Pal/src/host/Linux-SGX/sgx-driver/Makefile +++ b/Pal/src/host/Linux-SGX/sgx-driver/Makefile @@ -1,18 +1,25 @@ ifneq ($(KERNELRELEASE),) - ccflags-y += -I$(PWD)/linux-sgx-driver graphene-sgx-y := \ + gsgx_ioctl_1_6.o \ + gsgx_ioctl_1_7.o \ + gsgx_fsgsbase.o \ gsgx_main.o obj-m += graphene-sgx.o else KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) -default: linux-sgx-driver/isgx.h +default: isgx_version.h linux-sgx-driver $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) CFLAGS_MODULE="-DDEBUG -g -O0" modules -linux-sgx-driver/isgx.h: +.INTERMEDIATE: link-sgx-driver +link-sgx-driver: @./link-intel-driver.py + +isgx_version.h linux-sgx-driver: link-sgx-driver + endif clean: + rm -vrf linux-sgx-driver isgx_version.h rm -vrf *.o *.ko *.order *.symvers *.mod.c .tmp_versions .*o.cmd diff --git a/Pal/src/host/Linux-SGX/sgx-driver/graphene-sgx.h b/Pal/src/host/Linux-SGX/sgx-driver/graphene-sgx.h index f234c4a0..ae6ddf38 100644 --- a/Pal/src/host/Linux-SGX/sgx-driver/graphene-sgx.h +++ b/Pal/src/host/Linux-SGX/sgx-driver/graphene-sgx.h @@ -5,9 +5,25 @@ #include #include +#include "isgx_version.h" + #define GSGX_FILE "/dev/gsgx" #define GSGX_MINOR MISC_DYNAMIC_MINOR +#if SDK_DRIVER_VERSION >= KERNEL_VERSION(1, 8, 0) + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +#include "linux-sgx-driver/sgx_user.h" + +#endif + +#if SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) + +#include "linux-sgx-driver/isgx_user.h" + #define GSGX_IOCTL_ENCLAVE_CREATE _IOWR('p', 0x01, struct gsgx_enclave_create) #define GSGX_IOCTL_ENCLAVE_ADD_PAGES _IOW('p', 0x02, struct gsgx_enclave_add_pages) #define GSGX_IOCTL_ENCLAVE_INIT _IOW('p', 0x03, struct gsgx_enclave_init) @@ -35,4 +51,34 @@ struct gsgx_enclave_init { uint64_t einittoken; }; +#endif /* SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) */ + +#if SDK_DRIVER_VERSION == KERNEL_VERSION(1, 6, 0) +#define SGX_SUCCESS ISGX_SUCCESS +#define SGX_INVALID_SIG_STRUCT ISGX_INVALID_SIG_STRUCT +#define SGX_INVALID_ATTRIBUTE ISGX_INVALID_ATTRIBUTE +#define SGX_BLKSTATE ISGX_BLKSTATE +#define SGX_INVALID_MEASUREMENT ISGX_INVALID_MEASUREMENT +#define SGX_NOTBLOCKABLE ISGX_NOTBLOCKABLE +#define SGX_PG_INVLD ISGX_PG_INVLD +#define SGX_LOCKFAIL ISGX_LOCKFAIL +#define SGX_INVALID_SIGNATURE ISGX_INVALID_SIGNATURE +#define SGX_MAC_COMPARE_FAIL ISGX_MAC_COMPARE_FAIL +#define SGX_PAGE_NOT_BLOCKED ISGX_PAGE_NOT_BLOCKED +#define SGX_NOT_TRACKED ISGX_NOT_TRACKED +#define SGX_VA_SLOT_OCCUPIED ISGX_VA_SLOT_OCCUPIED +#define SGX_CHILD_PRESENT ISGX_CHILD_PRESENT +#define SGX_ENCLAVE_ACT ISGX_ENCLAVE_ACT +#define SGX_ENTRYEPOCH_LOCKED ISGX_ENTRYEPOCH_LOCKED +#define SGX_INVALID_LICENSE ISGX_INVALID_LICENSE +#define SGX_PREV_TRK_INCMPL ISGX_PREV_TRK_INCMPL +#define SGX_PG_IS_SECS ISGX_PG_IS_SECS +#define SGX_INVALID_CPUSVN ISGX_INVALID_CPUSVN +#define SGX_INVALID_ISVSVN ISGX_INVALID_ISVSVN +#define SGX_UNMASKED_EVENT ISGX_UNMASKED_EVENT +#define SGX_INVALID_KEYNAME ISGX_INVALID_KEYNAME +#define SGX_POWER_LOST_ENCLAVE ISGX_POWER_LOST_ENCLAVE +#define SGX_LE_ROLLBACK ISGX_LE_ROLLBACK +#endif + #endif /* _X86_GSGX_USER_H */ diff --git a/Pal/src/host/Linux-SGX/sgx-driver/gsgx.h b/Pal/src/host/Linux-SGX/sgx-driver/gsgx.h index 06aca148..f2249a88 100644 --- a/Pal/src/host/Linux-SGX/sgx-driver/gsgx.h +++ b/Pal/src/host/Linux-SGX/sgx-driver/gsgx.h @@ -1,25 +1,35 @@ -/* - * (C) Copyright 2013 Intel Corporation - * Author: Jarkko Sakkinen - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 - * of the License. - */ - -#ifndef __ARCH_GSGX_H__ -#define __ARCH_GSGX_H__ - -#include -#include -#include - -#include "graphene-sgx.h" -#include "isgx_ksyms.h" - -extern struct vm_operations_struct gsgx_vm_ops; - -long gsgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); - -#endif /* __ARCH_X86_GSGX_H__ */ +/* + * (C) Copyright 2013 Intel Corporation + * Author: Jarkko Sakkinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#ifndef __ARCH_GSGX_H__ +#define __ARCH_GSGX_H__ + +#include "isgx_version.h" +#include "graphene-sgx.h" + +#if SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) + +#include "isgx_ksyms.h" + +extern struct file *isgx_dev; + +extern long gsgx_ioctl(struct file *, unsigned int, unsigned long); +extern int gsgx_mmap(struct file *, struct vm_area_struct *); +extern unsigned long gsgx_get_unmapped_area(struct file *, unsigned long, + unsigned long, unsigned long, + unsigned long); + +extern int gsgx_lookup_ksyms(void); + +#endif + +extern int gsgx_open(struct inode *, struct file *); + +#endif /* __ARCH_GSGX_H__ */ diff --git a/Pal/src/host/Linux-SGX/sgx-driver/gsgx_fsgsbase.c b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_fsgsbase.c new file mode 100644 index 00000000..147ea15a --- /dev/null +++ b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_fsgsbase.c @@ -0,0 +1,37 @@ +/* + * (C) Copyright 2015 Intel Corporation + * Author: Chia-Che Tsai + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gsgx.h" + +static void __enable_fsgsbase(void *v) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) + write_cr4(read_cr4() | X86_CR4_FSGSBASE); +#else + cr4_set_bits(X86_CR4_FSGSBASE); + __write_cr4(__read_cr4() | X86_CR4_FSGSBASE); +#endif +} + +int gsgx_open(struct inode *inode, struct file *file) +{ + __enable_fsgsbase(NULL); + smp_call_function(__enable_fsgsbase, NULL, 1); + return 0; +} diff --git a/Pal/src/host/Linux-SGX/sgx-driver/gsgx_ioctl_1_6.c b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_ioctl_1_6.c new file mode 100644 index 00000000..ab0177ff --- /dev/null +++ b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_ioctl_1_6.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2013 Intel Corporation + * Author: Jarkko Sakkinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gsgx.h" + +#if SDK_DRIVER_VERSION == KERNEL_VERSION(1, 6, 0) + +#include "isgx.h" +#include "isgx_arch.h" +#include "isgx_user.h" + +struct file *isgx_dev; + +static long enclave_create(struct file *filep, void * arg) +{ + struct gsgx_enclave_create *createp = arg; + struct isgx_create_param isgx_create; + + isgx_create.addr = createp->src; + filep->private_data = (void *) createp->src; + + return KSYM(isgx_ioctl_enclave_create)(filep, ISGX_IOCTL_ENCLAVE_CREATE, + (unsigned long) &isgx_create); +} + +static long enclave_add_pages(struct file *filep, void * arg) +{ + struct gsgx_enclave_add_pages *addp = arg; + struct isgx_add_param isgx_add; + uint64_t off; + int ret = 0; + + if (!addp->addr || (addp->addr & (PAGE_SIZE - 1))) + return -EINVAL; + if (!addp->size || (addp->size & (PAGE_SIZE - 1))) + return -EINVAL; + if (!addp->secinfo) + return -EINVAL; + + isgx_add.secinfo = (struct isgx_secinfo *) addp->secinfo; + + for (off = 0 ; off < addp->size ; off += PAGE_SIZE) { + isgx_add.addr = addp->addr + off; + isgx_add.user_addr = + addp->flags & GSGX_ENCLAVE_ADD_PAGES_REPEAT_SRC ? + addp->user_addr : addp->user_addr + off; + isgx_add.flags = + addp->flags & GSGX_ENCLAVE_ADD_PAGES_SKIP_EEXTEND ? + ISGX_ADD_SKIP_EEXTEND : 0; + ret = KSYM(isgx_ioctl_enclave_add_page)(filep, + ISGX_IOCTL_ENCLAVE_ADD_PAGE, (unsigned long) &isgx_add); + if (ret < 0) + break; + } + + return ret; +} + +static long enclave_init(struct file *filep, void * arg) +{ + struct gsgx_enclave_init *initp = arg; + struct isgx_init_param isgx_init; + + isgx_init.addr = initp->addr; + isgx_init.sigstruct = (void *) initp->sigstruct; + isgx_init.einittoken = (struct isgx_einittoken *) initp->einittoken; + + return KSYM(isgx_ioctl_enclave_init)(filep, ISGX_IOCTL_ENCLAVE_INIT, + (unsigned long) &isgx_init); +} + +long gsgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + char data[256]; + long (*handler) (struct file *filp, void *arg) = NULL; + long ret; + + switch (cmd) { + case GSGX_IOCTL_ENCLAVE_CREATE: + handler = enclave_create; + break; + case GSGX_IOCTL_ENCLAVE_ADD_PAGES: + handler = enclave_add_pages; + break; + case GSGX_IOCTL_ENCLAVE_INIT: + handler = enclave_init; + break; + default: + return -EINVAL; + } + + if (copy_from_user(data, (void __user *) arg, _IOC_SIZE(cmd))) + return -EFAULT; + + ret = handler(filep, (void *) data); + + if (!ret && (cmd & IOC_OUT)) { + if (copy_to_user((void __user *) arg, data, _IOC_SIZE(cmd))) + return -EFAULT; + } + + return ret; +} + +int gsgx_mmap(struct file *file, struct vm_area_struct *vma) +{ + return KSYM(isgx_mmap)(file, vma); +} + +unsigned long gsgx_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + if (file->private_data == (void *) GSGX_ENCLAVE_CREATE_NO_ADDR) { + unsigned long unmapped_addr = + KSYM(isgx_get_unmapped_area)(file, addr, len, + pgoff, flags); + file->private_data = (void *) unmapped_addr; + return unmapped_addr; + } else { + unsigned long unmapped_addr = (unsigned long) file->private_data; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma = find_vma(mm, unmapped_addr); + if (vma && vma->vm_start <= len) + return -EINVAL; + return unmapped_addr; + } +} + +IMPORT_KSYM_PROTO(isgx_ioctl_enclave_create, long, + struct file *filep, unsigned int cmd, unsigned long arg); +IMPORT_KSYM_PROTO(isgx_ioctl_enclave_init, long, + struct file *filep, unsigned int cmd, unsigned long arg); +IMPORT_KSYM_PROTO(isgx_ioctl_enclave_add_page, long, + struct file *filep, unsigned int cmd, unsigned long arg); + +IMPORT_KSYM(isgx_enclave_release); +IMPORT_KSYM_PROTO(isgx_mmap, int, struct file *, struct vm_area_struct *); +IMPORT_KSYM_PROTO(isgx_get_unmapped_area, unsigned long, + struct file *, unsigned long, unsigned long, + unsigned long, unsigned long); + +int gsgx_lookup_ksyms(void) +{ + int ret; + if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_create))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_init))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_add_page))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_enclave_release))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_mmap))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_get_unmapped_area))) + return ret; + return 0; +} + +#endif /* SGX_DRIVER_VERSION == 1.7 */ diff --git a/Pal/src/host/Linux-SGX/sgx-driver/gsgx_ioctl_1_7.c b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_ioctl_1_7.c new file mode 100644 index 00000000..8803877d --- /dev/null +++ b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_ioctl_1_7.c @@ -0,0 +1,173 @@ +/* + * (C) Copyright 2013 Intel Corporation + * Author: Jarkko Sakkinen + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; version 2 + * of the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gsgx.h" + +#if SDK_DRIVER_VERSION == KERNEL_VERSION(1, 7, 0) + +struct file *isgx_dev; + +static long enclave_create(struct file *filep, void * arg) +{ + struct gsgx_enclave_create *createp = arg; + struct sgx_enclave_create isgx_create; + + isgx_create.src = createp->src; + filep->private_data = (void *) createp->src; + + return KSYM(isgx_ioctl_enclave_create)(filep, SGX_IOC_ENCLAVE_CREATE, + (unsigned long) &isgx_create); +} + +static long enclave_add_pages(struct file *filep, void * arg) +{ + struct gsgx_enclave_add_pages *addp = arg; + struct sgx_enclave_add_page isgx_add; + uint64_t off; + int ret = 0; + + if (!addp->addr || (addp->addr & (PAGE_SIZE - 1))) + return -EINVAL; + if (!addp->size || (addp->size & (PAGE_SIZE - 1))) + return -EINVAL; + if (!addp->secinfo) + return -EINVAL; + + isgx_add.secinfo = addp->secinfo; + + for (off = 0 ; off < addp->size ; off += PAGE_SIZE) { + isgx_add.addr = addp->addr + off; + isgx_add.src = + addp->flags & GSGX_ENCLAVE_ADD_PAGES_REPEAT_SRC ? + addp->user_addr : addp->user_addr + off; + isgx_add.mrmask = + addp->flags & GSGX_ENCLAVE_ADD_PAGES_SKIP_EEXTEND ? + 0 : ~0; + ret = KSYM(isgx_ioctl_enclave_add_page)(filep, + SGX_IOC_ENCLAVE_ADD_PAGE, (unsigned long) &isgx_add); + if (ret < 0) + break; + } + + return ret; +} + +static long enclave_init(struct file *filep, void * arg) +{ + struct gsgx_enclave_init *initp = arg; + struct sgx_enclave_init isgx_init; + + isgx_init.addr = initp->addr; + isgx_init.sigstruct = initp->sigstruct; + isgx_init.einittoken = initp->einittoken; + + return KSYM(isgx_ioctl_enclave_init)(filep, SGX_IOC_ENCLAVE_INIT, + (unsigned long) &isgx_init); +} + +long gsgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) +{ + char data[256]; + long (*handler) (struct file *filp, void *arg) = NULL; + long ret; + + switch (cmd) { + case GSGX_IOCTL_ENCLAVE_CREATE: + handler = enclave_create; + break; + case GSGX_IOCTL_ENCLAVE_ADD_PAGES: + handler = enclave_add_pages; + break; + case GSGX_IOCTL_ENCLAVE_INIT: + handler = enclave_init; + break; + default: + return -EINVAL; + } + + if (copy_from_user(data, (void __user *) arg, _IOC_SIZE(cmd))) + return -EFAULT; + + ret = handler(filep, (void *) data); + + if (!ret && (cmd & IOC_OUT)) { + if (copy_to_user((void __user *) arg, data, _IOC_SIZE(cmd))) + return -EFAULT; + } + + return ret; +} + +int gsgx_mmap(struct file *file, struct vm_area_struct *vma) +{ + return KSYM(isgx_mmap)(file, vma); +} + +unsigned long gsgx_get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + if (file->private_data == (void *) GSGX_ENCLAVE_CREATE_NO_ADDR) { + unsigned long unmapped_addr = + KSYM(isgx_get_unmapped_area)(file, addr, len, + pgoff, flags); + file->private_data = (void *) unmapped_addr; + return unmapped_addr; + } else { + unsigned long unmapped_addr = (unsigned long) file->private_data; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma = find_vma(mm, unmapped_addr); + if (vma && vma->vm_start <= len) + return -EINVAL; + return unmapped_addr; + } +} + +IMPORT_KSYM_PROTO(isgx_ioctl_enclave_create, long, + struct file *filep, unsigned int cmd, unsigned long arg); +IMPORT_KSYM_PROTO(isgx_ioctl_enclave_init, long, + struct file *filep, unsigned int cmd, unsigned long arg); +IMPORT_KSYM_PROTO(isgx_ioctl_enclave_add_page, long, + struct file *filep, unsigned int cmd, unsigned long arg); + +IMPORT_KSYM(isgx_enclave_release); +IMPORT_KSYM_PROTO(isgx_mmap, int, struct file *, struct vm_area_struct *); +IMPORT_KSYM_PROTO(isgx_get_unmapped_area, unsigned long, + struct file *, unsigned long, unsigned long, + unsigned long, unsigned long); + +int gsgx_lookup_ksyms(void) +{ + int ret; + if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_create))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_init))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_add_page))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_enclave_release))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_mmap))) + return ret; + if ((ret = LOOKUP_KSYM(isgx_get_unmapped_area))) + return ret; + return 0; +} + +#endif /* SGX_DRIVER_VERSION == 1.7 */ diff --git a/Pal/src/host/Linux-SGX/sgx-driver/gsgx_main.c b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_main.c index fb5f3bad..719873e6 100644 --- a/Pal/src/host/Linux-SGX/sgx-driver/gsgx_main.c +++ b/Pal/src/host/Linux-SGX/sgx-driver/gsgx_main.c @@ -1,6 +1,6 @@ /* - * (C) Copyright 2013 Intel Corporation - * Author: Jarkko Sakkinen + * (C) Copyright 2015 Intel Corporation + * Author: Chia-Che Tsai * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -11,178 +11,30 @@ #include #include #include -#include +#include #include -#include -#include -#include -#include + #include "gsgx.h" #define DRV_DESCRIPTION "Graphene SGX Driver" -#define DRV_VERSION "0.10" +#define DRV_VERSION "0.10-" SDK_DRIVER_VERSION_STRING MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_AUTHOR("Chia-Che Tsai "); MODULE_VERSION(DRV_VERSION); -IMPORT_KSYM(dac_mmap_min_addr); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) -static void __enable_fsgsbase(void *v) -{ - write_cr4(read_cr4() | X86_CR4_FSGSBASE); -} -#endif - -static long gsgx_ioctl_enclave_create(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - struct gsgx_enclave_create *createp = (struct gsgx_enclave_create *) arg; - struct sgx_enclave_create isgx_create; - unsigned long old_mmap_min_addr = *KSYM(dac_mmap_min_addr); - int ret; - - if (createp->src != GSGX_ENCLAVE_CREATE_NO_ADDR && - createp->src < old_mmap_min_addr) { - *KSYM(dac_mmap_min_addr) = createp->src; - old_mmap_min_addr = 0; - } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0) - __enable_fsgsbase(NULL); - smp_call_function(__enable_fsgsbase, NULL, 1); -#endif - - isgx_create.src = createp->src; - filep->private_data = (void *) createp->src; - - ret = KSYM(isgx_ioctl_enclave_create)(filep, SGX_IOC_ENCLAVE_CREATE, - (unsigned long) &isgx_create); - - if (old_mmap_min_addr) - *KSYM(dac_mmap_min_addr) = old_mmap_min_addr; - return ret; -} - -static long gsgx_ioctl_enclave_add_pages(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - struct gsgx_enclave_add_pages *addp = (struct gsgx_enclave_add_pages *) arg; - struct sgx_enclave_add_page isgx_add; - uint64_t off; - int ret = 0; - - if (!addp->addr || (addp->addr & (PAGE_SIZE - 1))) - return -EINVAL; - if (!addp->size || (addp->size & (PAGE_SIZE - 1))) - return -EINVAL; - if (!addp->secinfo) - return -EINVAL; - - isgx_add.secinfo = addp->secinfo; - - for (off = 0 ; off < addp->size ; off += PAGE_SIZE) { - isgx_add.addr = addp->addr + off; - isgx_add.src = - addp->flags & GSGX_ENCLAVE_ADD_PAGES_REPEAT_SRC ? - addp->user_addr : addp->user_addr + off; - isgx_add.mrmask = - addp->flags & GSGX_ENCLAVE_ADD_PAGES_SKIP_EEXTEND ? - 0 : ~0; - ret = KSYM(isgx_ioctl_enclave_add_page)(filep, - SGX_IOC_ENCLAVE_ADD_PAGE, (unsigned long) &isgx_add); - if (ret < 0) - break; - } - - return ret; -} - -static long gsgx_ioctl_enclave_init(struct file *filep, unsigned int cmd, - unsigned long arg) -{ - struct gsgx_enclave_init *initp = (struct gsgx_enclave_init *) arg; - struct sgx_enclave_init isgx_init; - - isgx_init.addr = initp->addr; - isgx_init.sigstruct = initp->sigstruct; - isgx_init.einittoken = initp->einittoken; - - return KSYM(isgx_ioctl_enclave_init)(filep, SGX_IOC_ENCLAVE_INIT, - (unsigned long) &isgx_init); -} - -typedef long (*ioctl_t)(struct file *filep, unsigned int cmd, unsigned long arg); - -long gsgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) -{ - char data[256]; - ioctl_t handler = NULL; - long ret; - - switch (cmd) { - case GSGX_IOCTL_ENCLAVE_CREATE: - handler = gsgx_ioctl_enclave_create; - break; - case GSGX_IOCTL_ENCLAVE_ADD_PAGES: - handler = gsgx_ioctl_enclave_add_pages; - break; - case GSGX_IOCTL_ENCLAVE_INIT: - handler = gsgx_ioctl_enclave_init; - break; - default: - return -EINVAL; - } - - if (copy_from_user(data, (void __user *) arg, _IOC_SIZE(cmd))) - return -EFAULT; - - ret = handler(filep, cmd, (unsigned long) ((void *) data)); - - if (!ret && (cmd & IOC_OUT)) { - if (copy_to_user((void __user *) arg, data, _IOC_SIZE(cmd))) - return -EFAULT; - } - - return ret; -} - -static int gsgx_mmap(struct file *file, struct vm_area_struct *vma) -{ - return KSYM(isgx_mmap)(file, vma); -} - -static unsigned long gsgx_get_unmapped_area(struct file *file, - unsigned long addr, - unsigned long len, - unsigned long pgoff, - unsigned long flags) -{ - if (file->private_data == (void *) GSGX_ENCLAVE_CREATE_NO_ADDR) { - unsigned long unmapped_addr = - KSYM(isgx_get_unmapped_area)(file, addr, len, - pgoff, flags); - file->private_data = (void *) unmapped_addr; - return unmapped_addr; - } else { - unsigned long unmapped_addr = (unsigned long) file->private_data; - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma = find_vma(mm, unmapped_addr); - if (vma && vma->vm_start <= len) - return -EINVAL; - return unmapped_addr; - } -} - static const struct file_operations gsgx_fops = { .owner = THIS_MODULE, + .open = gsgx_open, + +#if SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) .unlocked_ioctl = gsgx_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = gsgx_ioctl, #endif .mmap = gsgx_mmap, .get_unmapped_area = gsgx_get_unmapped_area, +#endif }; static struct miscdevice gsgx_dev = { @@ -192,51 +44,10 @@ static struct miscdevice gsgx_dev = { .mode = S_IRUGO | S_IWUGO, }; -IMPORT_KSYM_PROTO(isgx_ioctl_enclave_create, long, - struct file *filep, unsigned int cmd, unsigned long arg); -IMPORT_KSYM_PROTO(isgx_ioctl_enclave_init, long, - struct file *filep, unsigned int cmd, unsigned long arg); -IMPORT_KSYM_PROTO(isgx_ioctl_enclave_add_page, long, - struct file *filep, unsigned int cmd, unsigned long arg); - -IMPORT_KSYM(isgx_enclave_release); -IMPORT_KSYM_PROTO(isgx_mmap, int, struct file *, struct vm_area_struct *); -IMPORT_KSYM_PROTO(isgx_get_unmapped_area, unsigned long, - struct file *, unsigned long, unsigned long, - unsigned long, unsigned long); - -static int gsgx_lookup_ksyms(void) -{ - int ret; - if ((ret = LOOKUP_KSYM(dac_mmap_min_addr))) - return ret; - if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_create))) - return ret; - if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_init))) - return ret; - if ((ret = LOOKUP_KSYM(isgx_ioctl_enclave_add_page))) - return ret; - if ((ret = LOOKUP_KSYM(isgx_enclave_release))) - return ret; - if ((ret = LOOKUP_KSYM(isgx_mmap))) - return ret; - if ((ret = LOOKUP_KSYM(isgx_get_unmapped_area))) - return ret; - return 0; -} - -struct file *isgx_dev; - static int gsgx_setup(void) { - unsigned cpu; int ret; - isgx_dev = filp_open("/dev/isgx", O_RDONLY, 0); - if (!isgx_dev) { - return PTR_ERR(isgx_dev); - } - ret = misc_register(&gsgx_dev); if (ret) { pr_err("gsgx: misc_register() failed\n"); @@ -244,9 +55,16 @@ static int gsgx_setup(void) return ret; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) - for_each_online_cpu(cpu) { - per_cpu(cpu_tlbstate.cr4, cpu) |= X86_CR4_FSGSBASE; +#if SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) + isgx_dev = filp_open("/dev/isgx", O_RDONLY, 0); + if (!isgx_dev) { + return PTR_ERR(isgx_dev); + } + + ret = gsgx_lookup_ksyms(); + if (ret) { + pr_err("gsgx: lookup kernel symbols failed\n"); + return ret; } #endif @@ -258,8 +76,10 @@ static void gsgx_teardown(void) if (gsgx_dev.this_device) misc_deregister(&gsgx_dev); +#if SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) if (isgx_dev) filp_close(isgx_dev, NULL); +#endif } static int __init gsgx_init(void) @@ -268,15 +88,8 @@ static int __init gsgx_init(void) pr_info("gsgx: " DRV_DESCRIPTION " v" DRV_VERSION "\n"); - ret = gsgx_lookup_ksyms(); - if (ret) { - pr_err("Likely module \"isgx\" is not loaded\n"); - return ret; - } - ret = gsgx_setup(); if (ret) { - pr_err("Likely module \"isgx\" is not loaded\n"); gsgx_teardown(); return ret; } diff --git a/Pal/src/host/Linux-SGX/sgx-driver/isgx_ksyms.h b/Pal/src/host/Linux-SGX/sgx-driver/isgx_ksyms.h index 260043ef..743f0d6a 100644 --- a/Pal/src/host/Linux-SGX/sgx-driver/isgx_ksyms.h +++ b/Pal/src/host/Linux-SGX/sgx-driver/isgx_ksyms.h @@ -1,6 +1,11 @@ #ifndef _ISGX_KSYMS_H #define _ISGX_KSYMS_H +#include "isgx_version.h" + +#if SDK_DRIVER_VERSION < KERNEL_VERSION(1, 8, 0) + +#include "linux-sgx-driver/isgx.h" #include "ksyms.h" extern IMPORT_KSYM_PROTO(isgx_ioctl_enclave_create, long, @@ -18,3 +23,5 @@ extern IMPORT_KSYM_PROTO(isgx_get_unmapped_area, unsigned long, unsigned long, unsigned long); #endif + +#endif diff --git a/Pal/src/host/Linux-SGX/sgx-driver/link-intel-driver.py b/Pal/src/host/Linux-SGX/sgx-driver/link-intel-driver.py index a87d5bf3..a151b1d5 100755 --- a/Pal/src/host/Linux-SGX/sgx-driver/link-intel-driver.py +++ b/Pal/src/host/Linux-SGX/sgx-driver/link-intel-driver.py @@ -1,27 +1,68 @@ #!/usr/bin/python +import sys, os, re -import sys, os, string, subprocess, shutil, fileinput, multiprocessing, re, resource + +isgx_path = os.getenv("ISGX_DRIVER_PATH") +isgx_version = os.getenv("ISGX_DRIVER_VERSION") try: - ######################################### - #### get the locations of directories ### - ######################################### + # get the locations of directories + print "\n" + \ + "*****************************************************************\n" + \ + "Make sure you have downloaded and installed the Intel sgx driver \n" + \ + "from https://github.com/01org/linux-sgx-driver.\n" + \ + "*****************************************************************\n" + \ + "\n" - print "Make sure you have downloaded and installed the Intel sgx driver " + \ - "from https://github.com/01org/linux-sgx-driver." while True: - isgx = raw_input('Enter the Intel sgx driver derctory: ') - if os.path.exists(isgx + '/isgx.h'): + if not isgx_path: + isgx_path = raw_input('Enter the Intel SGX driver derctory: ') + if os.path.exists(isgx_path + '/sgx.h'): break - print '{0} is not a directory for the Intel sgx driver'.format(isgx) + if os.path.exists(isgx_path + '/isgx.h'): + break + print '{0} is not a directory for the Intel SGX driver'.format(isgx_path) + isgx_path = None + + # get the driver version + while True: + if not isgx_version: + isgx_version = raw_input('Enter the driver version (default: 1.8): ') + if not isgx_version: + isgx_version_major = 1 + isgx_version_minor = 8 + break + m = re.match('([1-9])\.([0-9]+)', isgx_version) + if m: + isgx_version_major = m.group(1) + isgx_version_minor = m.group(2) + break + print '{0} is not a valid version (x.xx)'.format(isgx_version) + isgx_version = None + + + # create a symbolic link called 'linux-sgx-driver' isgx_link = 'linux-sgx-driver' - isgx = os.path.abspath(isgx) - print isgx_link + ' -> ' + isgx + isgx_path = os.path.abspath(isgx_path) + print isgx_link + ' -> ' + isgx_path if os.path.exists(isgx_link): os.unlink(isgx_link) - os.symlink(isgx, isgx_link) + os.symlink(isgx_path, isgx_link) + + + # create isgx_version.h + with open('isgx_version.h', 'w') as versionfile: + print 'create isgx_version.h' + print >> versionfile, '#include ' + print >> versionfile + print >> versionfile, '#define SDK_DRIVER_VERSION KERNEL_VERSION(' + \ + str(isgx_version_major) + ',' + \ + str(isgx_version_minor) + ',0)' + print >> versionfile, '#define SDK_DRIVER_VERSION_STRING "' + \ + str(isgx_version_major) + '.' + \ + str(isgx_version_minor) + '"' except: print 'uh-oh: {0}'.format(sys.exc_info()[0]) diff --git a/Pal/src/host/Linux-SGX/sgx_arch.h b/Pal/src/host/Linux-SGX/sgx_arch.h index d61fb1cc..bf8eb09c 100644 --- a/Pal/src/host/Linux-SGX/sgx_arch.h +++ b/Pal/src/host/Linux-SGX/sgx_arch.h @@ -243,8 +243,6 @@ typedef struct { typedef uint8_t sgx_arch_key128_t[16] __attribute__((aligned(16))); -#include "sgx-driver/graphene-sgx.h" - #else /* !__ASSEMBLER__ */ /* microcode to call ENCLU */ diff --git a/Pal/src/host/Linux-SGX/sgx_enclave.c b/Pal/src/host/Linux-SGX/sgx_enclave.c index 1e6c6c58..859d8629 100644 --- a/Pal/src/host/Linux-SGX/sgx_enclave.c +++ b/Pal/src/host/Linux-SGX/sgx_enclave.c @@ -240,7 +240,7 @@ static int sgx_ocall_futex(void * pms) int ret; ODEBUG(OCALL_FUTEX, ms); struct timespec * ts = NULL; - if (ms->ms_timeout != (unsigned long) -1) { + if (ms->ms_timeout != OCALL_NO_TIMEOUT) { ts = __alloca(sizeof(struct timespec)); ts->tv_sec = ms->ms_timeout / 1000000; ts->tv_nsec = (ms->ms_timeout - ts->tv_sec * 1000000) * 1000; @@ -610,7 +610,7 @@ static int sgx_ocall_poll(void * pms) int ret; ODEBUG(OCALL_POLL, ms); struct timespec * ts = NULL; - if (ms->ms_timeout != (unsigned long) -1) { + if (ms->ms_timeout != OCALL_NO_TIMEOUT) { ts = __alloca(sizeof(struct timespec)); ts->tv_sec = ms->ms_timeout / 1000000; ts->tv_nsec = (ms->ms_timeout - ts->tv_sec * 1000000) * 1000; diff --git a/Pal/src/host/Linux-SGX/sgx_framework.c b/Pal/src/host/Linux-SGX/sgx_framework.c index 4d031f34..b02943cf 100644 --- a/Pal/src/host/Linux-SGX/sgx_framework.c +++ b/Pal/src/host/Linux-SGX/sgx_framework.c @@ -6,7 +6,7 @@ #include "sgx_internal.h" #include "sgx_arch.h" #include "sgx_enclave.h" -#include "sgx-driver/graphene-sgx.h" +#include "graphene-sgx.h" #include @@ -18,18 +18,12 @@ void * zero_page; int open_gsgx(void) { - int fd = INLINE_SYSCALL(open, 3, GSGX_FILE, O_RDWR, 0); - if (IS_ERR(fd)) - return -ERRNO(fd); - - gsgx_device = fd; - - fd = INLINE_SYSCALL(open, 3, ISGX_FILE, O_RDWR, 0); - if (IS_ERR(fd)) - return -ERRNO(fd); - - isgx_device = fd; - + gsgx_device = INLINE_SYSCALL(open, 3, GSGX_FILE, O_RDWR, 0); + if (IS_ERR(gsgx_device)) + return -ERRNO(gsgx_device); + isgx_device = INLINE_SYSCALL(open, 3, ISGX_FILE, O_RDWR, 0); + if (IS_ERR(isgx_device)) + return -ERRNO(isgx_device); return 0; } @@ -125,8 +119,6 @@ int create_enclave(sgx_arch_secs_t * secs, sgx_arch_token_t * token) { int flags = MAP_SHARED; - if (gsgx_device == -1) - return -EACCES; if (!zero_page) { zero_page = (void *) @@ -148,7 +140,6 @@ int create_enclave(sgx_arch_secs_t * secs, memcpy(&secs->mrenclave, &token->mrenclave, sizeof(sgx_arch_hash_t)); memcpy(&secs->mrsigner, &token->mrsigner, sizeof(sgx_arch_hash_t)); - struct gsgx_enclave_create param; if (baseaddr) { secs->baseaddr = (uint64_t) baseaddr & ~(secs->size - 1); flags |= MAP_FIXED; @@ -156,7 +147,7 @@ int create_enclave(sgx_arch_secs_t * secs, secs->baseaddr = 0ULL; } - uint64_t addr = INLINE_SYSCALL(mmap, 6, secs->baseaddr, size, + uint64_t addr = INLINE_SYSCALL(mmap, 6, secs->baseaddr, secs->size, PROT_READ|PROT_WRITE|PROT_EXEC, flags, isgx_device, 0); @@ -171,13 +162,22 @@ int create_enclave(sgx_arch_secs_t * secs, } secs->baseaddr = addr; - param.src = (uint64_t) secs; + +#if SDK_DRIVER_VERSION >= KERNEL_VERSION(1, 8, 0) + struct sgx_enclave_create param = { + .src = (uint64_t) secs, + }; + int ret = INLINE_SYSCALL(ioctl, 3, isgx_device, SGX_IOC_ENCLAVE_CREATE, + ¶m); +#else + struct gsgx_enclave_create param = { + .src = (uint64_t) secs, + }; int ret = INLINE_SYSCALL(ioctl, 3, gsgx_device, GSGX_IOCTL_ENCLAVE_CREATE, ¶m); - +#endif + if (IS_ERR(ret)) { - if (ERRNO(ret) == EBADF) - gsgx_device = -1; SGX_DBG(DBG_I, "enclave ECREATE failed in enclave creation ioctl - %d\n", ERRNO(ret)); return -ERRNO(ret); } @@ -208,11 +208,8 @@ int add_pages_to_enclave(sgx_arch_secs_t * secs, bool skip_eextend, const char * comment) { - if (gsgx_device == -1) - return -EACCES; - - struct gsgx_enclave_add_pages param; sgx_arch_secinfo_t secinfo; + int ret; memset(&secinfo, 0, sizeof(sgx_arch_secinfo_t)); @@ -233,17 +230,6 @@ int add_pages_to_enclave(sgx_arch_secs_t * secs, break; } - param.addr = secs->baseaddr + (uint64_t) addr; - param.user_addr = (uint64_t) user_addr; - param.size = size; - param.secinfo = (uint64_t) &secinfo; - param.flags = skip_eextend ? GSGX_ENCLAVE_ADD_PAGES_SKIP_EEXTEND : 0; - - if (!param.user_addr) { - param.user_addr = (unsigned long) zero_page; - param.flags |= GSGX_ENCLAVE_ADD_PAGES_REPEAT_SRC; - } - char p[4] = "---"; const char * t = (type == SGX_PAGE_TCS) ? "TCS" : "REG"; const char * m = skip_eextend ? "" : " measured"; @@ -265,15 +251,49 @@ int add_pages_to_enclave(sgx_arch_secs_t * secs, addr, addr + size, t, p, comment, m); - int ret = INLINE_SYSCALL(ioctl, 3, gsgx_device, - GSGX_IOCTL_ENCLAVE_ADD_PAGES, - ¶m); +#if SDK_DRIVER_VERSION >= KERNEL_VERSION(1, 8, 0) + struct sgx_enclave_add_page param = { + .addr = secs->baseaddr + (uint64_t) addr, + .src = (uint64_t) (user_addr ? : zero_page), + .secinfo = (uint64_t) &secinfo, + .mrmask = skip_eextend ? 0 : (uint16_t) -1, + }; + + uint64_t added_size = 0; + while (added_size < size) { + ret = INLINE_SYSCALL(ioctl, 3, isgx_device, + SGX_IOC_ENCLAVE_ADD_PAGE, ¶m); + if (IS_ERR(ret)) { + SGX_DBG(DBG_I, "Enclave add page returned %d\n", ret); + return -ERRNO(ret); + } + + param.addr += pagesize; + if (param.src != (uint64_t) zero_page) param.src += pagesize; + added_size += pagesize; + } +#else + struct gsgx_enclave_add_pages param = { + .addr = secs->baseaddr + (uint64_t) addr, + .user_addr = (uint64_t) user_addr, + .size = size, + .secinfo = (uint64_t) &secinfo, + .flags = skip_eextend ? GSGX_ENCLAVE_ADD_PAGES_SKIP_EEXTEND : 0, + }; + + if (!user_addr) { + param.user_addr = (unsigned long) zero_page; + param.flags |= GSGX_ENCLAVE_ADD_PAGES_REPEAT_SRC; + } + + ret = INLINE_SYSCALL(ioctl, 3, gsgx_device, + GSGX_IOCTL_ENCLAVE_ADD_PAGES, + ¶m); if (IS_ERR(ret)) { SGX_DBG(DBG_I, "Enclave add page returned %d\n", ret); - if (ERRNO(ret) == EBADF) - gsgx_device = -1; return -ERRNO(ret); } +#endif return 0; } @@ -282,9 +302,6 @@ int init_enclave(sgx_arch_secs_t * secs, sgx_arch_sigstruct_t * sigstruct, sgx_arch_token_t * token) { - if (gsgx_device == -1) - return -EACCES; - unsigned long enclave_valid_addr = secs->baseaddr + secs->size - pagesize; @@ -295,23 +312,48 @@ int init_enclave(sgx_arch_secs_t * secs, SGX_DBG(DBG_I, " %02x", sigstruct->enclave_hash[i]); SGX_DBG(DBG_I, "\n"); - struct gsgx_enclave_init param; - param.addr = enclave_valid_addr; - // DEP 11/6/16: I think sigstruct and token are supposed to - // be pointers in the new driver - param.sigstruct = (uint64_t) sigstruct; - param.einittoken = (uint64_t) token; - +#if SDK_DRIVER_VERSION >= KERNEL_VERSION(1, 8, 0) + struct sgx_enclave_init param = { + .addr = enclave_valid_addr, + .sigstruct = (uint64_t) sigstruct, + .einittoken = (uint64_t) token, + }; + int ret = INLINE_SYSCALL(ioctl, 3, isgx_device, SGX_IOC_ENCLAVE_INIT, + ¶m); +#else + struct gsgx_enclave_init param = { + .addr = enclave_valid_addr, + .sigstruct = (uint64_t) sigstruct, + .einittoken = (uint64_t) token, + }; int ret = INLINE_SYSCALL(ioctl, 3, gsgx_device, GSGX_IOCTL_ENCLAVE_INIT, ¶m); +#endif + if (IS_ERR(ret)) { - if (ERRNO(ret) == EBADF) - gsgx_device = -1; return -ERRNO(ret); } if (ret) { - SGX_DBG(DBG_I, "enclave EINIT failed\n"); + const char * error; + /* DEP 3/22/17: Try to improve error messages */ + switch(ret) { + case SGX_INVALID_SIG_STRUCT: + error = "Invalid SIGSTRUCT"; break; + case SGX_INVALID_ATTRIBUTE: + error = "Invalid enclave attribute"; break; + case SGX_INVALID_MEASUREMENT: + error = "Invalid measurement"; break; + case SGX_INVALID_SIGNATURE: + error = "Invalid signature"; break; + case SGX_INVALID_LICENSE: + error = "Invalid EINIT token"; break; + case SGX_INVALID_CPUSVN: + error = "Invalid CPU SVN"; break; + default: + error = "Unknown reason"; break; + } + SGX_DBG(DBG_I, "enclave EINIT failed - %s\n", error); return -EPERM; } diff --git a/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token b/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token index e72b86ef..e302710c 100755 --- a/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token +++ b/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token @@ -67,7 +67,26 @@ def connect_aesmd(attr): req_msg_raw = req_msg.SerializeToString() aesm_service = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - aesm_service.connect("\0sgx_aesm_socket_base" + "\0" * 87) + connected = False + + # try to connect to the unnamed socket (for PSW 1.6 and 1.7) + if not connected: + try: + aesm_service.connect("\0sgx_aesm_socket_base" + "\0" * 87) + connected = True + except socket.error: + pass + + # try to connect to the named socket (for PSW 1.8+) + if not connected: + try: + aesm_service.connect("/var/run/aesmd/aesm.socket") + connected = True + except socket.error: + pass + + if not connected: + raise socket.error("Cannot connect to the AESMD service") aesm_service.send(struct.pack("file.fd, length); @@ -176,7 +176,7 @@ static uint64_t file_setlength (PAL_HANDLE handle, uint64_t length) return (ERRNO(ret) == EINVAL || ERRNO(ret) == EBADF) ? -PAL_ERROR_BADHANDLE : -PAL_ERROR_DENIED; - return length; + return (int64_t) length; } /* 'flush' operation for file stream. */ @@ -258,7 +258,7 @@ static int file_attrsetbyhdl (PAL_HANDLE handle, { int fd = HANDLE_HDR(handle)->fds[0], ret; - ret = INLINE_SYSCALL(fchmod, 2, fd, attr->share_flags); + ret = INLINE_SYSCALL(fchmod, 2, fd, attr->share_flags | 0600); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); diff --git a/Pal/src/host/Linux/db_mutex.c b/Pal/src/host/Linux/db_mutex.c index 113480f7..4ac1255c 100644 --- a/Pal/src/host/Linux/db_mutex.c +++ b/Pal/src/host/Linux/db_mutex.c @@ -56,7 +56,7 @@ #define MUTEX_SPINLOCK_TIMES 100 -int _DkMutexLockTimeout (struct mutex_handle * m, int timeout) +int _DkMutexLockTimeout (struct mutex_handle * m, uint64_t timeout) { int ret = 0; #ifdef DEBUG_MUTEX diff --git a/Pal/src/host/Linux/db_object.c b/Pal/src/host/Linux/db_object.c index 0a19c74e..c4498a75 100644 --- a/Pal/src/host/Linux/db_object.c +++ b/Pal/src/host/Linux/db_object.c @@ -46,7 +46,7 @@ * * Returns 0 on success, negative value on failure (e.g., -PAL_ERROR_TRYAGAIN) */ -static int _DkObjectWaitOne (PAL_HANDLE handle, int timeout) +static int _DkObjectWaitOne (PAL_HANDLE handle, uint64_t timeout) { /* only for all these handle which has a file descriptor, or a eventfd. events and semaphores will skip this part */ @@ -126,7 +126,7 @@ static int _DkObjectWaitOne (PAL_HANDLE handle, int timeout) /* _DkObjectsWaitAny for internal use. The function wait for any of the handle in the handle array. timeout can be set for the wait. */ -int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, int timeout, +int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, uint64_t timeout, PAL_HANDLE * polled) { if (count <= 0) diff --git a/Pal/src/host/Linux/db_rtld.c b/Pal/src/host/Linux/db_rtld.c index 461e5db2..61e68410 100644 --- a/Pal/src/host/Linux/db_rtld.c +++ b/Pal/src/host/Linux/db_rtld.c @@ -39,7 +39,6 @@ #include #include -#include #include "elf-x86_64.h" diff --git a/Pal/src/host/Linux/db_semaphore.c b/Pal/src/host/Linux/db_semaphore.c index b6b32edf..25a0005f 100644 --- a/Pal/src/host/Linux/db_semaphore.c +++ b/Pal/src/host/Linux/db_semaphore.c @@ -82,7 +82,7 @@ void _DkSemaphoreDestroy (PAL_HANDLE semaphoreHandle) free(semaphoreHandle); } -int _DkMutexLockTimeout (struct mutex_handle * mut, int timeout); +int _DkMutexLockTimeout (struct mutex_handle * mut, uint64_t timeout); int _DkSemaphoreAcquire (PAL_HANDLE sem, int count) { @@ -151,10 +151,10 @@ int _DkSemaphoreAcquire (PAL_HANDLE sem, int count) return ret; } -int _DkSemaphoreAcquireTimeout (PAL_HANDLE sem, int count, int timeout) +int _DkSemaphoreAcquireTimeout (PAL_HANDLE sem, int count, uint64_t timeout) { /* Pass it up to the no-timeout version if no timeout requested */ - if (timeout == -1) + if (timeout == NO_TIMEOUT) return _DkSemaphoreAcquire(sem, count); /* optimization: use it as a mutex */ diff --git a/Pal/src/host/Linux/pal_linux.h b/Pal/src/host/Linux/pal_linux.h index 6527343a..848078fd 100644 --- a/Pal/src/host/Linux/pal_linux.h +++ b/Pal/src/host/Linux/pal_linux.h @@ -156,7 +156,7 @@ bool stataccess (struct stat * stats, int acc); /* Locking and unlocking of Mutexes */ int _DkMutexLock (struct mutex_handle * mut); -int _DkMutexLockTimeout (struct mutex_handle * mut, int timeout); +int _DkMutexLockTimeout (struct mutex_handle * mut, uint64_t timeout); int _DkMutexUnlock (struct mutex_handle * mut); void init_child_process (PAL_HANDLE * parent, PAL_HANDLE * exec, diff --git a/Pal/src/pal.h b/Pal/src/pal.h index 3adf71af..fc1bd3b4 100644 --- a/Pal/src/pal.h +++ b/Pal/src/pal.h @@ -466,7 +466,9 @@ DkEventClear (PAL_HANDLE eventHandle); #define NO_TIMEOUT ((PAL_NUM) -1) -/* assuming timeout to be in microseconds */ +/* assuming timeout to be in microseconds + * NO_TIMEOUT means no timeout, as the name implies. + */ /* Returns: NULL if the call times out, the ready handle on success */ PAL_HANDLE DkObjectsWaitAny (PAL_NUM count, PAL_HANDLE * handleArray, PAL_NUM timeout); diff --git a/Pal/src/pal_internal.h b/Pal/src/pal_internal.h index 7e083933..4d6d7e0a 100644 --- a/Pal/src/pal_internal.h +++ b/Pal/src/pal_internal.h @@ -81,7 +81,7 @@ struct handle_ops { /* 'setlength' is used by DkStreamFlush. It truncate the stream to certain size. */ - uint64_t (*setlength) (PAL_HANDLE handle, uint64_t length); + int64_t (*setlength) (PAL_HANDLE handle, uint64_t length); /* 'flush' is used by DkStreamFlush. It syncs the stream to the device */ int (*flush) (PAL_HANDLE handle); @@ -104,11 +104,12 @@ struct handle_ops { int (*attrsetbyhdl) (PAL_HANDLE handle, PAL_STREAM_ATTR * attr); /* 'wait' is used for synchronous wait. + * Time is in microseconds, NO_TIMEOUT means no timeout. * Returns 0 on success, a negative value on failure. * Timeout: -PAL_ERROR_TRYAGAIN * Positive return values are undefined. */ - int (*wait) (PAL_HANDLE handle, int time); + int (*wait) (PAL_HANDLE handle, uint64_t time); /* 'rename' is used to change name of a stream, or reset its share option */ @@ -302,7 +303,7 @@ int _DkStreamAttributesQuerybyHandle (PAL_HANDLE hdl, PAL_STREAM_ATTR * attr); int _DkStreamMap (PAL_HANDLE handle, void ** addr, int prot, uint64_t offset, uint64_t size); int _DkStreamUnmap (void * addr, uint64_t size); -uint64_t _DkStreamSetLength (PAL_HANDLE handle, uint64_t length); +int64_t _DkStreamSetLength (PAL_HANDLE handle, uint64_t length); int _DkStreamFlush (PAL_HANDLE handle); int _DkStreamGetName (PAL_HANDLE handle, char * buf, int size); const char * _DkStreamRealpath (PAL_HANDLE hdl); @@ -327,7 +328,7 @@ int _DkProcessSandboxCreate (const char * manifest, int flags); int _DkSemaphoreCreate (PAL_HANDLE handle, int initialCount, int maxCount); void _DkSemaphoreDestroy (PAL_HANDLE semaphoreHandle); int _DkSemaphoreAcquire (PAL_HANDLE sem, int count); -int _DkSemaphoreAcquireTimeout (PAL_HANDLE sem, int count, int timeout); +int _DkSemaphoreAcquireTimeout (PAL_HANDLE sem, int count, uint64_t timeout); void _DkSemaphoreRelease (PAL_HANDLE sem, int count); int _DkSemaphoreGetCurrentCount (PAL_HANDLE sem); @@ -336,7 +337,7 @@ int _DkEventCreate (PAL_HANDLE * event, bool initialState, bool isnotification); void _DkEventDestroy (PAL_HANDLE handle); int _DkEventSet (PAL_HANDLE event, int wakeup); -int _DkEventWaitTimeout (PAL_HANDLE event, int timeout); +int _DkEventWaitTimeout (PAL_HANDLE event, uint64_t timeout); int _DkEventWait (PAL_HANDLE event); int _DkEventClear (PAL_HANDLE event); @@ -348,7 +349,7 @@ int _DkVirtualMemoryProtect (void * addr, uint64_t size, int prot); /* DkObject calls */ int _DkObjectReference (PAL_HANDLE objectHandle); int _DkObjectClose (PAL_HANDLE objectHandle); -int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, int timeout, +int _DkObjectsWaitAny (int count, PAL_HANDLE * handleArray, uint64_t timeout, PAL_HANDLE * polled); /* DkException calls & structures */ diff --git a/Pal/src/pal_rtld.h b/Pal/src/pal_rtld.h index 04cb7886..189a917e 100644 --- a/Pal/src/pal_rtld.h +++ b/Pal/src/pal_rtld.h @@ -30,7 +30,6 @@ #include #include -#include #ifndef DT_THISPROCNUM # define DT_THISPROCNUM 0 diff --git a/Pal/test/test.c b/Pal/test/test.c deleted file mode 100644 index df65a5a4..00000000 --- a/Pal/test/test.c +++ /dev/null @@ -1,63 +0,0 @@ -#include // printf -#include // strerror -#include // errno -#include // execl -#include // ptrace -#include // user_regs_struct -#include // personality -#include -#include -#include -#include - -int -main(int argc, char *argv[], char *envp[]) { - - // create a child process - int pid = fork(); - - // if error occurs - if (0 > pid) { - printf("Error during forking: %s\n", strerror(errno)); - return 1; - } - - // child process - if (0 == pid) { - ptrace(PTRACE_TRACEME, 0, 0, 0); - personality(ADDR_NO_RANDOMIZE); - execve(argv[1], &(argv[1]), envp); - } - - // parent process - int status; - struct user_regs_struct regs; - int n; - - wait(&status); - if(1407 == status) { - char infilename[128], line[256], out[256]; - char* outfilename = "/tmp/pal_range"; - int mapfd, ret, outfd; - unsigned long vas; - unsigned long vae; - - sprintf(infilename, "/proc/%d/maps",pid); - while((mapfd = open(infilename,O_RDONLY)) == -1); - read(mapfd, &line, 256); - - /*scan for the virtual addresses*/ - n = sscanf(line, "%lX-%lX r-xp", &vas, &vae); - if(n == 2) - { - outfd = open(outfilename, O_WRONLY|O_CREAT, S_IRUSR); - memset(out,0,256); - sprintf(out,"%lX,%lX\n", vas, vae); - write(outfd, out, 256); - close(outfd); - } - close(mapfd); - } - kill(pid,SIGKILL); - return 0; -} diff --git a/Runtime/pal_loader b/Runtime/pal_loader index 4d359040..9be911c4 100755 --- a/Runtime/pal_loader +++ b/Runtime/pal_loader @@ -2,7 +2,15 @@ if [ "$1" == "SGX" ]; then if [ "$SGX" != "0" ]; then - export SGX=1 + export SGX=1 + # Sometimes, we end up with a stray SGX_RUN in the environment, + # which makes the Makefile.Host unhappy + unset SGX_RUN + # The interaction of SGX and SGX_RUN is getting pretty unwieldly. + # We should kill off SGX_RUN. Here, we can get in trouble + # if the make invocation below gets SGX_RUN via an MAKEFLAGS + # from a wrapper makefile (e.g., the regression tests) + unset MAKEFLAGS fi shift fi