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