mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 22:01:29 +00:00
Merge branch 'master' into sha256
This commit is contained in:
+18
-1
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
@@ -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 <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
* 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
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -78,6 +78,7 @@ struct shim_file_data {
|
||||
unsigned long atime;
|
||||
unsigned long mtime;
|
||||
unsigned long ctime;
|
||||
unsigned long nlink;
|
||||
};
|
||||
|
||||
struct shim_file_handle {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
+109
-22
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <errno.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 <shim_internal.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -39,11 +39,12 @@
|
||||
#include <linux/signal.h>
|
||||
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
*.manifest
|
||||
*.manifest.sgx
|
||||
*.sig
|
||||
*.token
|
||||
*.cached
|
||||
pal_loader
|
||||
@@ -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 ] || \
|
||||
|
||||
Executable
+41
@@ -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"
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+222
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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" > $@
|
||||
|
||||
+352
-23
@@ -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
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
testcase,timeout
|
||||
clone05,30
|
||||
alarm01,5
|
||||
alarm06,16
|
||||
alarm06,16
|
||||
waitpid05,160
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../../Runtime/pal_loader
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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 <tls.h>
|
||||
|
||||
/* 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 */
|
||||
@@ -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_ */
|
||||
@@ -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
|
||||
@@ -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 <sysdep.h>
|
||||
#define _ERRNO_H
|
||||
#include <bits/errno.h>
|
||||
#include <bp-asm.h>
|
||||
#include <bp-sym.h>
|
||||
|
||||
#ifdef IS_IN_rtld
|
||||
# include <dl-sysdep.h> /* 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)
|
||||
@@ -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 <sysdep.h>
|
||||
#define _ERRNO_H
|
||||
#include <bits/errno.h>
|
||||
#include <bp-asm.h>
|
||||
#include <bp-sym.h>
|
||||
//#include <tls.h>
|
||||
|
||||
#ifdef IS_IN_rtld
|
||||
# include <dl-sysdep.h> /* 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)
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+334
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+3
-3
@@ -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 = {
|
||||
|
||||
+34
-1
@@ -33,7 +33,6 @@
|
||||
|
||||
#include <sysdeps/generic/ldsodefs.h>
|
||||
#include <elf/elf.h>
|
||||
#include <bits/dlfcn.h>
|
||||
|
||||
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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <sysdeps/generic/ldsodefs.h>
|
||||
#include <elf/elf.h>
|
||||
#include <bits/dlfcn.h>
|
||||
|
||||
struct link_map * loaded_maps = NULL;
|
||||
struct link_map * exec_map = NULL;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 $@
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <sysdeps/generic/ldsodefs.h>
|
||||
#include <elf/elf.h>
|
||||
#include <bits/dlfcn.h>
|
||||
|
||||
#include "elf-x86_64.h"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -7,3 +7,4 @@ Module.symvers
|
||||
modules.order
|
||||
.tmp_versions
|
||||
linux-sgx-driver
|
||||
isgx_version.h
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -5,9 +5,25 @@
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#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 */
|
||||
|
||||
@@ -1,25 +1,35 @@
|
||||
/*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
|
||||
*
|
||||
* 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.h>
|
||||
#include <isgx_arch.h>
|
||||
#include <isgx_user.h>
|
||||
|
||||
#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 <jarkko.sakkinen@intel.com>
|
||||
*
|
||||
* 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__ */
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* (C) Copyright 2015 Intel Corporation
|
||||
* Author: Chia-Che Tsai <chiache-che.tsai@intel.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/security.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/security.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#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 */
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/security.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#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 */
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* (C) Copyright 2013 Intel Corporation
|
||||
* Author: Jarkko Sakkinen <jarkko.sakkinen@intel.com>
|
||||
* (C) Copyright 2015 Intel Corporation
|
||||
* Author: Chia-Che Tsai <chiache-che.tsai@intel.com>
|
||||
*
|
||||
* 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 <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/security.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#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 <chia-che.tsai@intel.com>");
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <linux/version.h>'
|
||||
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])
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 <asm/errno.h>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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("<I", len(req_msg_raw)))
|
||||
aesm_service.send(req_msg_raw)
|
||||
|
||||
@@ -79,7 +79,7 @@ int _DkEventSet (PAL_HANDLE event, int wakeup)
|
||||
return IS_ERR(ret) ? PAL_ERROR_TRYAGAIN : ret;
|
||||
}
|
||||
|
||||
int _DkEventWaitTimeout (PAL_HANDLE event, int timeout)
|
||||
int _DkEventWaitTimeout (PAL_HANDLE event, uint64_t timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -168,7 +168,7 @@ 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 = INLINE_SYSCALL(ftruncate, 2, handle->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));
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include <sysdeps/generic/ldsodefs.h>
|
||||
#include <elf/elf.h>
|
||||
#include <bits/dlfcn.h>
|
||||
|
||||
#include "elf-x86_64.h"
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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,
|
||||
|
||||
+3
-1
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#include <sysdeps/generic/ldsodefs.h>
|
||||
#include <elf/elf.h>
|
||||
#include <bits/dlfcn.h>
|
||||
|
||||
#ifndef DT_THISPROCNUM
|
||||
# define DT_THISPROCNUM 0
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
#include <stdio.h> // printf
|
||||
#include <string.h> // strerror
|
||||
#include <errno.h> // errno
|
||||
#include <unistd.h> // execl
|
||||
#include <sys/ptrace.h> // ptrace
|
||||
#include <sys/user.h> // user_regs_struct
|
||||
#include <sys/personality.h> // personality
|
||||
#include <sys/wait.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user