An internal Graphene structure for GDB metadata limits the number of
enclave threads to MAX_DBG_THREADS. Previously, it was set to 64,
which was enough for typical platforms. However, powerful servers
have hundreds of logical cores. Graphene-SGX failed with error on such
servers. This commit increases the limit to 1024.
There was a bug in LibOS code which manifested in heisenbugs in our tests.
The bug happened because `shim_clone.c:clone_implementation_wrapper()` called
`object_wait_with_retry()/DkObjectClose()` before actually setting up a proper
in-enclave TCB. The root cause was:
1. The newly created thread has an in-enclave `FS segment register == 0`
because Graphene-SGX doesn't set up SGX's `TCS.OFSBASGX`, so in-enclave FS
register was equal to `%fs == TCS.OFSBASGX == 0`.
2. `object_wait_with_retry()` checks `PAL_NATIVE_ERRNO` which is implemented
via TCB's `mov %fs:<offset>`.
3. However, `%fs == 0` at this point so there was a SIGBUS while executing
`mov %fs:<offset>`.
The fix (in this commit) is to move `object_wait_with_retry()/DkObjectClose()`
after TCB set-up in `allocate_tls()`.
In certain cases (e.g, a container runtime for production), `make` and `gcc`
programs may be unavailable. In this case, detect `PAL_HOST` based on the
base name of libpal.
Graphene with SGX is currently experiencing random segfaults and the
testsuite is unstable. For now, the tests are still run, but the
returncode is ignored.
Also fixes Jenkins-SGX-18.04 pipeline, which was apparently broken but
its results are ignored and this problem was missed.
The new option specifies the file check policy, determining how and which files
can be opened. Previously, there were only two strict options: sgx.trusted_files
and sgx.allowed_files, but they are not flexible enough (e.g., unknown files are
never allowed).
This commit introduces two policies:
- allow_all_but_log allows files other than trusted/allowed files to be opened
but outputs a warning message. This is a convenient way to debug applications.
- strict disallows all files other than trusted/allowed files (just like the
previous logic).
Even though the SysV ABI does not specify the order of argv strings,
some applications (notably Node.js's libuv) assume the compact
encoding of argv where (1) all strings are located adjacently and
(2) in increasing order. This commit reorders argv strings in the
initial user stack in this way.
Previously, the FXSAVE extended state (ST, XMM, MXCSR registers) was not
cleared on EENTER (i.e., enclave-thread enter). This could lead to
maliciously crafted ST/XMM registers propagating into the enclave and
subverting execution. This commit resets FXSAVE on every EENTER to a
default mostly zero-byte state.
Note that this commit does not reset XSAVE state (YMM, ZMM registers).
This will be fixed in a future commit.
Before EEXIT, Graphene-SGX resets the extended state (XSAVE) area to the
default state (of mostly zero bytes). This prevents the leakage of
x87/SSE/AVX/MPX register values inside the enclave. However, the
previous default state had an incorrectly calculated offset of MXCSR. This
commit fixes the offset of MXCSR. (This particular error manifested in
spurious "Numeric underflow (#U)" SSE hardware exceptions on OpenVINO.)
This commit allows setting the AVX, AVX512, and MPX bits in SIGSTRUCT.xfrms
dynamically unless the features are specifically enabled in the manifest via
sgx.require_[avx|avx512|mpx]=1 options. If the bits are set in SIGSTRUCT.xfrms
but the CPU feature(s) are not available on the platform, the enclave
initialization (EINIT) should fail. In addition, the xfrms and xfrmmask fields
in the EINITTOKEN must match with SIGSTRUCT.
Previously, the "sgx.static_address" field was overwritten by the
pal-sgx-sign tool in the manifest, even if the manifest author
explicitly specified it as 0 or 1. Sometimes, it is important to keep
sgx.static_address as the manifest author intended. This commit adds a
check to overwrite sgx.static_address only if not specified in manifest.
Previously, *stubptr was not initialized to NULL in the corner case of a
file created from inside of the SGX enclave. This led to a subsequent
failure in logic which tried to mmap an empty file (because it observed
that *stubptr contained some value).
Applications like OpenVINO sometimes do open("") and expect ENOENT.
This corner case is correctly handled by Linux, so Graphene must have
the exact same semantics. Previously, open("") under Graphene resulted
in success, and subsequent read() failed.
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.
We don't need this micro-optimization which just obfuscates the sources
for negligible performance gains. (Un)likeliness of branches in almost
all cases should be derived from profiling, not from hand-written hints,
using profile-guided optimization.
Some hosts do not support IPv6 (e.g., Docker can be configured without
it). In this case, socket() host syscall will return EAFNOSUPPORT.
Some applications rely on this error code (e.g., Redis), so Graphene must
propagate this error code all the way to the application. This commit
makes LibOS and Linux/Linux-SGX PALs aware of this error code.
Previously, exit due to signal produced a return code of 0. This commit
correctly propagates the return code on exiting due to a signal. This
commit also adds two tests and updates graphene-tests submodule to
disable clone02 (this fix exposed an exotic unsupported combination of
clone flags).
_DkSystemTimeQuery() should return real time (CLOCK_REALTIME). The previously used
CLOCK_MONOTONIC returns time elapsed from an unspecified starting point
and is thus incorrect to use for system time.