Commit Graph
170 Commits
Author SHA1 Message Date
Michał Kowalczyk f1c334357c Reformat repository to our clang-format rules (2nd iteration) 2020-01-09 02:35:50 +01:00
Isaku Yamahata f8f6a0c42f [LibOS] Replace init_fs_base() with update_fs_base()
Now init_fs_base() is same to update_fs_base() except struct shim_thread
argument which is unused.
2020-01-08 01:20:26 +01:00
Isaku Yamahata 1902c3862b [LibOS] Use set_cur_thread() to associate shim_tcb_t and shim_thread
Uniformly use set_cur_thread() to associate shim_tcb_t to struct
shim_thread. Remove unnecessary logic from init_fs_base() and
update_fs_base().
2020-01-08 01:20:26 +01:00
Isaku Yamahata 29bd2bdf9c [LibOS] Use uint64_t intead of unsigned long for GP register type 2020-01-08 01:06:58 +01:00
Isaku Yamahata a7cb199b9a [LibOS] Optimize shim_get_tcb() and its variants
- apply SHIM_TCB_GET() and SHIM_TCB_SET()
- remove dead code
2020-01-08 01:06:52 +01:00
Dmitrii Kuvaiskii da2dd37dd8 [LibOS, Pal/{Linux,Linux-SGX}] Better emulation of polling
This commit improves the emulation of polling mechanisms (select,
pselect, poll, ppoll, epoll_wait) and cleans up the corresponding
code:
- New DkObjectsWaitEvents() PAL interface, replaces the inefficient
  DkObjectsWaitAny() interface. This interface closely resembles
  Linux/POSIX poll() in semantics.
- Improved shim_do_epoll_wait() implementation, now using the new
  DkObjectsWaitEvents() interface.
- Improved shim_do_poll() implementation, now using the new
  DkObjectsWaitEvents() interface.
- Small cleanups of polling code.
2020-01-07 12:11:00 -08:00
Dmitrii Kuvaiskii 56bc2b49ad [LibOS] Comprehensive cleanup of epoll_create()/epoll_ctl()/epoll_wait()
Accurate cleanup of shim_do_epoll_create1(), shim_do_epoll_ctl(),
shim_do_epoll_wait(), and other epoll helper functions. This cleanup
also adds error handling (missing previously).

The commit makes (most of) the corresponding LTP tests pass now.

Note that epoll semantics are still incorrect and inefficient: current
epoll_wait() emulation returns only one event to the user.
2020-01-07 12:11:00 -08:00
borysp 1bf6423384 [LibOS/Pal] Replace hardcoded URI prefix strings 2020-01-06 16:17:26 -08:00
Dmitrii Kuvaiskii 7d99d4788c [LibOS,Pal] Remove Graphene IPC completely
Graphene IPC (GIPC) was introduced to perform faster bulk IPC by sharing pages as copy-on-write
across processes. This feature became stale, and it was shown that recent Linux kernels (4.2+)
have zero-copy transfers over UNIX sockets and exhibit similar performance. GIPC is not built and
not tested in Jenkins. Also, GIPC does not work under SGX. This commit completely removes GIPC.
2019-12-30 12:17:51 -08:00
borysp 6cfaf420b3 [LibOS] Rework futexes implementation
This commit completely rewrites futex implementation to (hopefully)
remove all races (both on memory access level and between waits and
wakes), make it compatible with actual Linux implementation and make
it more maintainable and readable.
2019-12-19 22:04:12 -08:00
Dmitrii Kuvaiskii 05cc50945f [LibOS] Allow inaccessible files during getdents()
Previously, if user performed getdents() on a directory containing
inaccessible files (because user doesn't have permission), whole
getdents failed with -EACCES. This is incorrect behavior: files must
still be listed. This commit fixes the root cause of this bug by
marking inaccessible files as DENTRY_NEGATIVE.
2019-12-18 02:59:02 -08:00
Dmitrii Kuvaiskii 7c45430355 [LibOS] Remove the data race on thread::is_alive
Previously, there was a data race on thread::is_alive between one thread
checking whether it is the last thread alive via check_last_thread() and
another thread exiting via thread_exit(). The former checks if is_alive
is true, the latter sets it to false. However, the exiting thread will
truly exit only after it called DkThreadExit(), thus the race on is_alive
led to scenarios where two threads believe to be the last threads alive
and compete on terminating Async Helper/IPC threads and exiting the whole
process. This commit introduces cleanup_thread() called by Async Helper
to set is_alive to false and delete the thread, freeing its resources.
The data race is thus removed, and shim_thread object leak is prevented.
2019-12-18 01:56:25 -08:00
Dmitrii Kuvaiskii b194aa17fb [LibOS,Pal] Correctly emulate CLONE_CHILD_CLEARTID
When child thread exits, it wakes up its parent if CLONE_CHILD_CLEARTID was set
during clone() call. Previously, this was done by the child thread itself as
part of its own clean-up in release_clear_child_id(). But this child thread is
still alive at this point and uses some resources, most notably the stack (that
might have been provided by the parent) and the SGX TCS slot. Upon waking up,
the parent might decide to free that stack (as Pthreads do) or re-use the TCS
slot, causing data races.

This commit introduces a correct emulation of CLONE_CHILD_CLEARTID:
- A new argument `PAL_PTR clear_child_tid` is added to DkThreadExit();
  it points to internal Graphene memory that is erased on child exit to notify
  Async Helper thread.
- At PAL layer, when thread finally exits, it sets PAL-level *clear_child_tid = 0
  (corresponds to &clear_child_tid_val_pal at LibOS level);  this signals to LibOS
  layer that the thread stopped using resources.
- At LibOS layer, Async Helper thread is set up to wait for the signal from
  PAL; it is now the responsibility of Async Helper thread to call
  release_clear_child_id() to wake up the parent thread.
- Async Helper thread waits for clear_child_tid_val_pal == 0 and then sets
  the actual clear_child_tid to 0 and wakes up the waiting parent.

Note that for Linux-SGX PAL, clear_child_tid is set to 0 not immediately
but as part of handle_thread_reset, otherwise the TCS slot could be still
occupied when LibOS wakes up the parent.

As a side effect, the LibOS code for threads/process exit is cleaned up.

This commit also fixes all regression tests to use the new signature of
DkThreadExit() and increases the number of SGX threads slightly (to
accommodate the newly used Async Helper thread).
2019-12-03 21:19:07 -08:00
Isaku Yamahata 250dcb7aea [LibOS] Fix gcc-9 warning
This patch removes __attribute__((packed)) to eliminate warnings gcc-9
generates. Example:

> warning: taking address of packed member of struct poll_handle may result in an unaligned pointer value [-Waddress-of-packed-member]

Packed attribute is used for structures using which Graphene processes
communicate with each other. We don't implement privilege separation, so
it's ok to leak data in struct paddings.

If the padding is really a concern, we could:
- Define two structures, a packed one for serialization and a non-packed
  one for code, and then explicitly (de)serialize.
- Define the structure fields with an explicit size (e.g. uint64_t
  instead of long), carefully add explicit padding and then zero it out
  before sending.
2019-12-02 23:55:48 +01:00
Isaku Yamahata 03f9e2cf1e [LibOS] Rename clone_args to shim_clone_args
Linux already defines `struct clone_args` for clone3. Rename LibOS one
to avoid name collision.
2019-12-02 23:53:29 +01:00
Dmitrii Kuvaiskii e14bf7950f [LibOS] Allow Graphene-SGX to occupy the same process on execve()
The execve() syscall starts a new executable in the *same* process. Previously,
Graphene followed this convention *only* for non-SGX PALs. If PAL was Linux-SGX,
Graphene silently terminated the process and created a new one.

This deviation from standard execve() behavior resulted in the host shell
becoming detached from the Graphene-SGX process. In turn, this led to our
Bash example (on Ubuntu 18.04, bash version 4.4.19) "terminating" early
from the point of view of Jenkins, and SGX-18.04 pipeline failed.

This commit allows Graphene-SGX to execve() in the same process, but only if it
is the same executable (as in the Bash example). It is still impossible to
execve() in the same process for a different executable since this requires a
new SGX enclave measurement and thus demands a new process.
2019-11-29 15:18:56 -08:00
Michał Kowalczyk bae8baa2dd [LibOS] Merge page size and allocation alignment
Those two values are currently (and we don't think this will ever
change) indistinguishable from each other from the LibOS perspective.
2019-11-27 00:31:35 -08:00
Isaku Yamahata 51b4714e2c [LibOS] Rename SHIM_TLS_CANARY -> SHIM_TCB_CANARY 2019-11-26 12:44:08 -08:00
Isaku Yamahata b42a8a9f0f [LibOS] Move shim_thread:fs_base to shim_context::fs_base
fs_base is now an opaque value of FS register. It belongs to shim_context.
2019-11-26 12:44:08 -08:00
Isaku Yamahata f53ea3a7cb [LibOS] Rename shim_tls.h to shim_tcb.h 2019-11-26 12:44:08 -08:00
Isaku Yamahata 3ec3c078fa [LibOS] Rename shim_tls_check_canary() to shim_tcb_check_canary() 2019-11-26 12:44:08 -08:00
Isaku Yamahata f5a8d8ac3c [LibOS] Remove IN_SHIM macro in shim_tls.h 2019-11-26 12:44:08 -08:00
Dmitrii Kuvaiskii 186f41e65c [LibOS] Add dummy implementation of Linux-specific mbind()
This call is used by libnuma. Always returning success is currently enough.
2019-11-15 11:35:17 -08:00
Isaku Yamahata d51f84f547 [LibOS] Rename shim_get_tls() to shim_get_tcb() for consistency 2019-11-12 19:46:54 -08:00
Isaku Yamahata e4f90b1eec [LibOS] Rename allocate_tls()/populate_tls() to init_fs_base()/update_fs_base() 2019-11-12 19:46:54 -08:00
Isaku Yamahata fde7cc1d6a [LibOS] Rename shim_thread::tcb to fs_base
Now, shim_thread::tcb is used only as an integer value for %fs_base,
and shim_thread::user_tcb is not needed anymore. This commit renames
shim_thread::tcb to shim_thread::fs_base and removes user_tcb.
2019-11-12 19:46:54 -08:00
Isaku Yamahata 0f0c64c4af [LibOS] Remove reserve argument from init_stack() 2019-11-12 19:46:54 -08:00
Isaku Yamahata 5f13f730e9 [LibOS] Use %gs register for LibOS TCB (shim_tcb)
For binaries statically linked against Glibc, %fs register cannot be
used for LibOS TCB (shim_tcb) because it is already used by Glibc.
Thus, this commit moves shim_tcb into PAL TCB. Also, now that LibOS
doesn't access Glibc TCB (__libc_tcb), we make it an opaque pointer
used only for clean up.
2019-11-12 19:46:54 -08:00
Dmitrii Kuvaiskii 376de63d5a [LibOS] Add dummy implementations of Linux scheduling APIs
This commit adds dummy implementations for setpriority, getpriority,
sched_setparam, sched_getparam, sched_setscheduler, sched_getscheduler,
sched_get_priority_max, sched_get_priority_min, sched_rr_get_interval,
sched_setaffinity, sched_getaffinity. These implementations only check
for incorrect user-supplied arguments and either do nothing (setters)
or return default values (getters). This commit also adds a simple LibOS
regression test.
2019-10-31 11:24:34 -07:00
Krishnakumar, Sudha 3ee41aa9ff [LibOS, Pal] Support eventfd()
This commit adds support for eventfd():
- shim_do_eventfd() and shim_do_eventfd2() emulation at LibOS level;
- new eventfd pseudo-FS;
- db_eventfd.c emulation to route eventfd calls to host OS at Pal
  level (implementation for Linux and Linux-SGX, stubs for Skeleton);
- new OCALL ocall_eventfd() for Linux-SGX Pal;
- LibOS regression test for eventfd.

This implementation of eventfd() correctly handles IPC between
threads of the same process; it also must handle IPC between parent/
child processes. This implementation currently doesn't support the
scenario when kernel signals the process via eventfd, but is easily
extensible for this. The implementation currently doesn't have
additional checks to prevent Iago attacks on eventfd.
2019-10-31 00:34:27 -07:00
borysp a971a5c0b6 [LibOS] Add missing put_thread() calls
There were some places where put_thread() calls were missing. This
caused reference counter to never reach 0, so that the shim_thread
struct was never freed, thus leaking memory.
2019-10-10 13:02:25 -07:00
Michał Kowalczyk bc0beaa253 Refactor alignment macros 2019-10-04 22:31:52 +02:00
Michał Kowalczyk 44e186c503 Clean up asserts
- Make assert() a no-op in non-debug builds.
- Use static_assert for compile-time asserts.
- Fix assert() implementation (previous version didn't work for
  expressions with types larger than long, it also always printed
  `(value:0)`).
- Clean up calls to asserts.
2019-10-02 03:22:52 +02:00
Thomas Knauth c6a0151baf [LibOS] Fix and add a test case for resource leak on file close 2019-10-01 16:18:38 +02:00
Isaku Yamahata 55e0bb1c6a [LibOS] Force variable update on tcb.test_range.has_fault in test_user_memory()
In test_user_memory(), a memory range is tested via probing of each page
in the range. If the memory page was not allocated, it leads to a
segfault which is captured by the LibOS memfault_upcall() and reported
in the variable tcb.test_range.has_fault. However, the compiler may
optimize away accesses to this variable in test_user_memory(), believing
it is never updated anywhere else. This commit introduces a memory
barrier to prevent this compiler optimization (same for test_user_string()).
2019-09-30 20:56:18 -07:00
Michał Kowalczyk 6ba48bdf59 [LibOS] shim_profile: Simplify no-op macros 2019-10-01 00:48:00 +02:00
borysp 323be6717d [LibOS] Change minimal file descriptor number to be 0
Previously, set_new_fd_handle() started searching for the first free fd
from 1 not 0. This commit fixes this, plus refactors this function.
2019-09-30 15:49:32 -07:00
Michał Kowalczyk de42ebabe1 Reformat repository to our clang-format rules 2019-09-09 22:11:23 +02:00
Michał Kowalczyk 6356559e39 Fix header dependencies 2019-09-09 22:11:23 +02:00
borysp 289ac3af4d [LibOS] Fix get_new_dentry reference count semantics
If `get_new_dentry` returns successfully, it increases returned dentry's
reference counter by one, which matches other similar functions' behavior.
2019-09-03 21:52:55 +02:00
borysp e23684bc3d [LibOS] Rewrite rename* syscalls
Present implementation is utterly broken, does not work even
in simplest cases.
2019-09-03 21:52:55 +02:00
Chia-Che Tsai d875e2eba7 [LibOS] Disable the warning when GIPC is not supported 2019-08-26 23:10:09 +02:00
Isaku Yamahata 5f5bc5af56 [Pal, LibOS] Consolidate elf.h
There is no point in keeping the same elf.h in both Pal and LibOS.
2019-08-14 01:47:57 +02:00
borysp 004c2fe9a4 [LibOS] Remove opened reference counter from struct shim_handle
Inside `struct shim_handle` `opened` reference counter is used incorrectly.
Additionally at this moment it guards the same resource (handle) as `ref_counter`,
making it obsolete. This patch removes `opened` counter and moves `close_handle`
logic into `put_handle`.
2019-08-13 16:20:44 -07:00
Isaku Yamahata bc715c2081 [LibOS] Fix memory leak in shim_do_execve_rtld()
__libcc_tcb_t is leaked. It should be allocated from stack.
2019-08-13 20:47:34 +02:00
Chia-Che Tsai f2591790d7 [LibOS] Fix timeout resolution for epoll_wait()/epoll_pwait()
Internal LibOS and PAL interfaces use microseconds (us) for timeout
values. However, Linux epoll_wait/epoll_pwait syscalls use milliseconds
(ms) for timeout. Previously, there was a bug in timeout resolution
because epoll_wait() emulation did not convert from ms to us. This
commit fixes this bug and also adds suffixes "_ms" and "_us" to make the
time units used explicit.
2019-08-08 17:37:39 -07:00
Michał Kowalczyk 5ec5e2f24c Delete all reference monitor residues 2019-07-31 02:30:47 +02:00
Isaku Yamahata c7571408d6 [LibOS] Cleanup of shim_tls.h 2019-07-30 16:50:34 -07:00
Isaku Yamahata 5fe52e4a0d [LibOS] Use atomic operations for shim_context.preempt
enable_preempt(), disable_preempt(), and other functions operated on
shim_context.preempt using non-atomic operations. This commit replaces
the old broken implementation with atomic operations.
2019-07-30 16:50:34 -07:00
Chia-Che Tsai 0d89dda052 [LibOS] Fix the implementation of getrlimit/setrlimit syscalls
- Deprecate sys_stack_size and max_brk_size. Get the values directly from __rlim.cur.
- Add internal routines for setting and getting __rlim.cur.
- Implement prlimit64() and simplify getrlimit() and setrlimit().
2019-07-30 15:14:11 +02:00