Commit Graph

1115 Commits

Author SHA1 Message Date
Stefan Berger 36ccd3ea4c [LibOS] Rename vdso.c to vdso-x86_64.c
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
2021-02-16 23:20:28 +01:00
Vijay Dhanraj aa9ded3c42 [LibOS] regression: Fix sysfs regression test
Current implementation incorrectly uses `_SC_ULONG_MAX` to check the max
ulong (instead of ULONG_MAX). This patch addresses the issue.

Note: `_SC_ULONG_MAX` is intended to be used with sysconf() to inquire
about the maximum value which can be stored in a variable of type
`unsigned long` and is defined to 117.

Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
2021-02-16 00:25:40 +01:00
Vijay Dhanraj a57dcf6f38 [LibOS] Fix /sys/devices/system/{cpu,node}/ path resolution
Current implementation of sysfs will fail for paths such as
/sys/devices/system/{cpu,node}/online which doesn't have a numeric
value. This patch fixes this issue. This patch also adds 2 test cases as
part of the sysfs regression test.

Signed-off-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
2021-02-16 00:25:40 +01:00
Paweł Marczewski 6ea8e951f0 [LibOS] Use GS register for syscalls
Instead of depending on dynamic linking for LibOS entry point
(syscalldb), we pass a pointer in the shim_tcb structure, so that
the patched code can enter syscall using 'jmp *%gs:<offset>'.

The same applies to the vDSO syscall code that previously needed
an up-to-date pointer to syscalldb function. Now, there is no
need to adjust the values inside the vDSO page.

In addition, this change removes the other two instances where we
import a symbol directly from LibOS: register_library (can be also
done through GS register) and glibc_version (not important because
we build Graphene and glibc together).

This simplifies things because the dynamic linking necessary to
make the syscalldb function available had to be performed by LibOS
itself (in many cases, effectively doing a second pass of dynamic
linking after ld.so). After this change, there will be no need for
LibOS to perform dynamic linking, and the ELF loading code can be
simplified.

Signed-off-by: Paweł Marczewski <pawel@invisiblethingslab.com>
2021-02-15 22:19:28 +01:00
Michał Kowalczyk a402a2a8d9 [Pal/Linux-SGX] Add sgx.preheat_enclave manifest option
Signed-off-by: Michał Kowalczyk <mkow@invisiblethingslab.com>
2021-02-10 12:22:47 +01:00
Paweł Marczewski a06b93d8dc [LibOS] Drop support for glibc 2.23
Signed-off-by: Paweł Marczewski <pawel@invisiblethingslab.com>
2021-02-09 16:34:22 +01:00
borysp c24bddd5aa [LibOS] Rework signal handling and syscall emulation
Change log (most important only):
- unify CPU context structures - now we have only one version -
  `PAL_CONTEXT` - which is shared between LibOS and PALs and it should
  depend only on the host architecture (not OS),
- syscalls emulation changed:
  - dedicated LibOS stack is now used for syscalls emulation,
  - removed one indirection level in syscalls table - now it stores
    `shim_do_*` functions directly,
- signal handling - completely rewritten:
  - all signal queues use proper locking schemes now,
  - signals are handled *only* when returning to the user app from LibOS
    or PAL,
  - nested signals are now possible,
  - the app is allowed to jump out of signal handler with the same
    sematics as on normal Linux,
  - signal altstack is now fully supported,
  - syscall restarting is now supported,
  - doing a backtrace from the signal handler works properly,
- disallow injecting host-level signals, with one exception, see
  `sys.enable_sigterm_injection` manifest option for more details.
2021-02-05 14:11:21 +01:00
borysp bec1d9b4ec [LibOS] Fix LibOS code range checks in shim_signal.c
The old version did not consider e.g. PLT as code.
2021-02-05 14:00:05 +01:00
Dmitrii Kuvaiskii 439524b941 [Pal/Linux-SGX] Allow CPUID leaves 0x40000000 - 0x4FFFFFFF
These CPUID leaves are used by virtualization software (Hyper-V, KVM,
etc.) and are zeroed out on bare metal. Some runtimes (e.g. JVM) query
them to detect underlying virtualization software. This commit makes
these leaves return zeroes ("no virtualization").
2021-02-05 03:22:12 +01:00
borysp e0f6ac9116 [LibOS] Make poll and epoll_wait pass errors from DkStreamsWaitEvents 2021-02-03 16:39:48 +01:00
Li, Xun 1ddfd0e36f [LibOS] Allow but ignore MSG_WAITALL flag in recv 2021-02-03 01:16:43 +01:00
Michał Kowalczyk 5521c70401 [LibOS] Fix 'wence' -> 'whence' typo 2021-02-01 02:36:59 +01:00
Stefan Berger 02e80ff1bf [LibOS] Disable UBSAN sanitizer in test_user_memory/test_user_string
This is to prevent UBSAN from tripping on legitimate NULL pointers.
2021-01-29 04:45:29 -08:00
Vijay Dhanraj ec4422d415 [Pal,LibOS] Add support for /sys pseudo filesystem
This commit also fixes `pseudo_name_ops::list_name()` function pointer
type: `size_t len` argument instead of `int len`.  It also adds a
regression test to exercise the newly supported /sys pseudo filesystem.
2021-01-28 23:28:29 -08:00
Vijay Dhanraj d947474ff0 [LibOS] Add /proc/[pid]/task path to /proc fs 2021-01-28 23:19:30 -08:00
Paweł Marczewski ae8beba1a7 [Pal,Docs] Convert 'info' log level to 'warning'; add description
We seem to be using it for warnings, so it should be less confusing.
This change also adds a description of the levels to documentation.
2021-01-26 21:01:32 +01:00
Dmitrii Kuvaiskii e4c661b164 [LibOS] Add manifest option libos.check_invalid_pointers
Previously, LibOS always checked whether user-supplied buffers for
syscalls are invalid and generated EFAULT error codes if so. Since the
invalid-buffer check needed to touch memory/traverse VMAs, it could
affect performance of certain workloads. This commit adds a manifest
option that controls this behavior: most real-world applications never
supply invalid buffers in syscalls, so such checks can be disabled.
2021-01-26 10:48:52 -08:00
Dmitrii Kuvaiskii e1e036461e [LibOS] Add dummy lseek emulation for /dev/{zero,random,null}
Some apps (e.g., Python Dill module) perform a dummy lseek() on
these /dev/ files.
2021-01-26 09:16:12 -08:00
borysp f1d7d29118 [LibOS] Add missing syscalls parsers 2021-01-25 19:22:38 +01:00
Paweł Marczewski 8ca27bd3c4 [Pal] Log to stderr, not stdout 2021-01-23 01:58:26 +01:00
Stefan Berger 1b8848bdae [LibOS] Align char msg[] in shim_ipc_msg to 16 bytes
The msg field of 'struct shim_ipc_msg' will for example be cast to
'struct shim_ipc_sysv_tellkey*' (in ipc_sysv_tellkey_callback()) and
needs to be properly aligned. There are also casts to other IPC-related
structures that also require alignment.
2021-01-20 23:57:08 +01:00
Paweł Marczewski 17ab04db59 [Pal,LibOS] New logging system
Instead of 'loader.debug_type', introduce 'loader.log_level'
and 'loader.log_file', along with a set of definitions for
logging at a chosen level.

For now, the call sites keep using the legacy macros (SGX_DBG and
debug()), because converting them all will conflict with other
big changes in the code base. The existing LibOS calls are
assumed to be at 'info' level.
2021-01-20 17:27:29 +01:00
Paweł Marczewski e395e0133e [Pal,LibOS] Fix GDB integration in case of removing maps
- The GDB command for removing a symbol file takes text address
  (or any address inside the mapped memory area), not load offset.
  (which might be before the area). Because of that, removing a
  map in GDB did not actually work, and displayed a warning.
- The remove_r_debug() function in LibOS did not actually remove
  the map from list in LibOS. As a result, LibOS attempted to
  report the removal to PAL more than once, causing a harmless but
  annoying warning message.
2021-01-19 21:41:16 +01:00
Stefan Berger 54ee076cf6 [LibOS] shim_poll.c: Make __fd_mask unsigned
There was a signed overflow in __FD_MASK().
The issue was found by UBSAN.
2021-01-19 20:13:39 +01:00
Stefan Berger f3c235ac09 [LibOS] Fix __rs_func type to not confuse UBSAN 2021-01-19 18:38:18 +01:00
Stefan Berger ab61796abf [LibOS] Fix pointer alignment issue related to populate_dirent
The issue was found by UBSAN.
2021-01-19 18:38:18 +01:00
Stefan Berger b025a13128 [LibOS] Fix a getdents-related pointer alignment issue
The issue was found by UBSAN.
2021-01-19 18:38:18 +01:00
Stefan Berger b187d1b1d8 [LibOS] Fix pointer alignment issue in __hash()
The issue was found by UBSAN.
2021-01-19 18:38:18 +01:00
Dmitrii Kuvaiskii e745802ac0 [LibOS] Remove native/ and benchmark/ tests
Applications under native/ and benchmark/ cannot be built after commit
"Introduce one, central manifest, zero-config children and constant
MRENCLAVE" (because of the missing `libos.entrypoint` and possibly
other issues). They are not tested and not used by anyone these days.
The `exec_fork` test that failed previously now works on master; other
tests are more or less duplicates of our regression/ tests.
2021-01-18 11:16:07 -08:00
Paweł Marczewski 5ef9bdc861 [Pal] Unify debug maps
- Use the same mechanism (debug_map) in Pal/Linux and Pal/Linux-SGX.
  Previously, Pal/Linux emulated the _r_debug structure, normally
  maintained by ld.so, but that cannot be done in SGX outer PAL,
  because it's loaded by ld.so already.
- Maintain the debug maps outside of SGX enclave. This allows
  initializing them before enclave start, and potentially makes
  them easier to use.
- Initialize PAL debug map before enclave start. Previously, this
  was done from inside the enclave, so you couldn't set a
  breakpoint too early (e.g. in pal_linux_main).
- Store only load address, without list of sections. This is to
  avoid parsing the list of sections just to report them to the
  debugger. Unfortunately, the GDB version that we support still
  needs these sections, but we can retrieve them in GDB plugin.
- Move Python GDB code related to debug maps to a common file.
2021-01-18 03:49:18 +01:00
Dmitrii Kuvaiskii ef5259a86f [Docs,LibOS] Move helloworld example from native/ to regression/
Applications under native/ cannot be run after commit "Introduce one,
central manifest, zero-config children and constant MRENCLAVE". Instead
of fixing native/, this commit simply moves helloworld and all its
mentions under regression/.
2021-01-16 12:38:29 -08:00
borysp 26134a9cff Make all exit calls return positive values 2021-01-15 16:35:03 +01:00
borysp 287762501b Add infinite loop behind each call to exit syscall
This commit additionally replaces all `while (true) {}` inf loops with
`die_or_inf_loop` which either crashes the process or loops infinitely
and is not an undefined behavior like the original one (C disallows inf
loops without side effects).
2021-01-15 16:35:03 +01:00
borysp 8737ff4afe Remove process start time from process_id/vmid
Previously Graphene ORed process start time with host-level pid to
create process id (which was used also as vmid). This could be
problematic as it might cause two process ids to be the same for two
different processes. Why it was actually done remains a mystery ...
2021-01-15 16:34:33 +01:00
Stefan Berger 5dace18916 [LibOS] Use PAGE_SIZE rather than hard-coded size that is wrong for other archs 2021-01-15 00:30:53 +01:00
borysp d2dea5f4ec [LibOS] Remove types from syscalls debug printing
This commit removes types from syscall argument printing functions as
a preparation for next changes. Now the table with syscall parsers have
all parsing functions embeded directly.
Also some minor cleanups in the same area.
2021-01-14 19:56:30 +01:00
borysp baf96961c9 [LibOS] Make all syscalls really return long
Fixes places missed by commit "[LibOS] Have all syscall functions return
long"
2021-01-14 19:56:30 +01:00
borysp 2f88a6cc8f [LibOS] Remove unused checkpointing functions
Commit "Introduce one, central manifest, zero-config children and
constant MRENCLAVE" removed execve-in-a-new-process, so execve specific
checkpointing functions are not needed anymore (pending_signals,
arguments, environ).
2021-01-13 19:44:18 +01:00
Michał Kowalczyk 3d31f2d18d Introduce one, central manifest, zero-config children and constant MRENCLAVE
This is the next part of the great loader rework, with a lot of breaking changes:

- Complete removal of the "trusted children" thing - now children
  processes can be spawned arbitrarily and from arbitrary mountpoint
  types, without any additional configuration needed.

- There's a new, required option in the manifest: `libos.entrypoint` - it
  specifies the URI to the entry binary in the first process. There's no
  need anymore to name the manifest and the first binary identically.

- On SGX, the main binary is not measured in MRENCLAVE anymore - only
  PAL, LibOS and the manifest are measured. This is enough to bind
  MRENCLAVE to a specific entrypoint user executable if wanted - it
  just has to be mounted as a trusted file.

- All Graphene SGX enclaves have now exactly the same MRENCLAVE. This is
  a hash of a "Graphene stub", which can "fork" into one of two states
  in runtime: initial process or child. The initial process creates a
  new "Graphene namespace" with a clean state, it can also be attested
  remotely (contrary to child processes). The initial process can spawn
  children processes by spawning a Graphene stub and directing it to
  start in the child mode. It then attests it locally, and if
  successful, establishes an encrypted pipe, "connects" to its own
  namespace and treats as trusted (including sending protected files
  key).

- Now, there's only one, central manifest describing the initial state
  of a Graphene instance which can be spawned from it (previously, each
  process required a separate manifest which could have different
  configuration - which wasn't actually supported and didn't make sense
  design-wise). One downside of central manifests is that all processes
  require the same enclave configuration (e.g. size), but that was
  already the case so far because of broken checkpointing code. Also,
  this is only a temporary problem, which will cease to exist after the
  introduction of EDMM.

- `sgx.static_address` was renamed to `sgx.nonpie_binary` and now has to
  be inserted manually by users (`sgx_sign` tools doesn't know about the
  binaries run inside, which can be even provided or generated in
  runtime by the user's workload).

- Caveat: the memory gap for non-PIE executables was removed because it
  requires adding a new option to the manifest to be cleanly
  implemented. This is left for some future loader rework PR.
2021-01-12 19:53:24 +01:00
Stefan Berger a396892060 [LibOS] Have all syscall functions return long
That's how all of them are defined on Linux.
2021-01-12 16:14:32 +01:00
Stefan Berger c1ea3d9321 [LibOS] Build glibc with the stack protector enabled 2021-01-12 08:23:43 -05:00
Stefan Berger 48eb5ce267 [LibOS] Remove unused #include "immintrin.h" that caused a GCC crash 2021-01-11 23:46:44 -08:00
borysp 303528131c [LibOS] Do not call test_user_memory on LibOS allocated memory
This commit additionally fixes bugs in shim_do_sendmmsg and
shim_do_recvmmsg - `vlen` argument is the number of items in the array,
not size (in bytes) of it, as previous code assumed.
2021-01-07 19:30:31 +01:00
Dmitrii Kuvaiskii 3cb2112b05 [LibOS,Pal] Use GCC's stack protector in LibOS and PAL functions
GCC (and other compilers, e.g. Clang) provide a stack protector
feature to detect stack corruptions. This is achieved by storing
a 64-bit canary value on the stack frame on function entry and
verifying this value on function exit. Previously, Graphene disabled
stack protector completely. This commit enables it in LibOS and PAL
code (only if `-mstack-protector` feature is supported by compiler).

The stack protector uses a random per-thread canary stored in the
TLS/TCB of each thread. Each PAL implementation must follow the
rule that TLS/TCB is accessed via the GS register and that the offset
of canary in TLS/TCB is 0x8. Since LibOS re-uses TLS/TCB of the PAL,
there is no need for additional enabling at the LibOS layer.

Since `-mstack-protector` feature is architecture-specific, it is
currently enabled only for x86-64 (and above rules on using gs:[0x8]
to access the canary apply only to x86-64).

Co-authored-by: Isaku Yamahata <isaku.yamahata@gmail.com>
2021-01-07 05:19:14 -08:00
Li, Xun 5a76c92465 [LibOS] Unlock before blocking accept() in shim_do_accept()
The accept() emulation locks the shim handle at the beginning of
shim_do_accept() and then proceeds to issue a blocking accept()
host-level syscall. This blocked lock may lead to deadlocks, e.g.
due to a fork in another thread (fork emulation must checkpoint the
shim handle, for which it needs to grab the lock but it is blocked).
This commit unlocks right before the blocking accept() syscall and
thus avoids the deadlock.
2021-01-05 09:25:23 -08:00
Rafał Wojdyła 345d271e66 [Pal/Linux-SGX] Test malicious modifications to protected files
This commit adds a new PF utility `pf_tamper` that tampers with
valid protected files and uses this utility to test that the PF
logic in Linux-SGX detects such malicious modifications.

This commit also moves out the PF-format macros and structs from
`protected_files_internal.h` to `protected_files_format.h` for
better readability.

Co-authored-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
2021-01-04 21:13:03 +01:00
Dmitrii Kuvaiskii 85d401a8cc [LibOS] Remove useless escape sequences of single quotes in shim_fs.c 2021-01-04 17:43:19 +01:00
Dmitrii Kuvaiskii 1b5a8f1411 [LibOS] Do not allow "." and ".." mount points in manifest 2021-01-04 17:43:19 +01:00
borysp 05ed29f52d [Pal] Remove empty DkExceptionReturn function
This function was empty and it is responsibility of the caller (Pal
level) of specific exception handling function (LibOS level) to return
from the exception.
2021-01-04 10:00:43 +01:00
borysp ae9b49ecb1 Remove parentheses from assert argument evaluation
This helps with catching errors like `assert(x = y)`.
2020-12-31 00:40:13 +01:00