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