A previous change in LibOS started storing fake syscall return
address in R14. This broke stack unwinding when the stack
contained both LibOS syscall and SGX OCALL, because we had no CFI
directives for recovering register values except for RBP, RSP and
RIP, and the value of R14 was lost.
This change adds proper CFI to enclave exit code, by making sure
callee-saved registers can be recovered.
Signed-off-by: Paweł Marczewski <pawel@invisiblethingslab.com>
After this change, LibOS will no longer perform dynamic linking.
The ELF loading code executes load commands and passes control to
interpreter (ld.so), which handles necessary relocations and
loading additional libraries. In this way, the code resembles what
Linux kernel does when executing a new program.
Before, dynamic linking was necessary for making LibOS entry point
(syscalldb function) available for applications. However, that meant
duplicating the work already done by ld.so, and introduced a lot of
unnecessary complexity. After changing LibOS entry API to use the
GS register, it's possible to omit dynamic linking entirely.
The main function (__load_elf_object()) still needs cleanup and
possibly rewriting from scratch. However, this change prepares
ground for that rewrite.
Summary of changes:
- Remove dynamic relocation step (DO_DYNAMIC_RELOCATE()).
- Don't call __load_elf_object() again for ELFs reported
via register_library(). We only need to notify GDB about these.
- Remove fields related to dynamic linking from link_map (dynamic
section address, hashes, etc.), and setup for these fields.
- need_interp(): To check if we need an interpreter, check only if
the binary requests one (PT_INTERP), instead of traversing the
dynamic section (before, we ignored dynamic dependencies on LibOS
itself, but now there shouldn't be any).
- RELOCATE(): always adjust addresses, instead of checking if
they're already inside the mapped range. I think the previous
behaviour was a workaround to make repeated relocations work.
- Get rid of load modes that are no longer used (OBJECT_REMAP,
OBJECT_USER).
- Remove the workaround for repeated relocation in glibc patches
(R_X86_64_NONE).
Signed-off-by: Paweł Marczewski <pawel@invisiblethingslab.com>
When an async exception triggers, LibOS needs to know whether it
happened while inside PAL code. Since Linux-PAL sometimes call VDSO
functions, they need to be accounted for as well.
Signed-off-by: Borys Popławski <borysp@invisiblethingslab.com>
This commit is a result of debugging a rare race condition during build
of some of our examples, which resulted in "enclave EINIT failed -
Invalid measurement" error.
It turns out that Make in versions that doesn't support the `&:`
operator ("Rules with Grouped Targets") silently ignores it and calls
the recipe for each target separately, without even a warning.
Signed-off-by: Michał Kowalczyk <mkow@invisiblethingslab.com>
Previously, some GSC templates and scripts that execute inside Docker
containers contained relative file paths. This led to failures if
a base Docker image contained WORKDIR different from root (`/`),
since all GSC scripts put Graphene-related files under root dir.
Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
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>
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>
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>
These macros were empty and not used anymore. Additionally there was
a bug: `LEAVE_PAL_CALL` actually did not perform `return` and the
execution continued after it.
Signed-off-by: borysp <borysp@invisiblethingslab.com>
Previously, the SGX-signing Python script had a hard-coded value of
1 page. However, the Linux-SGX runtime calculated the SSA frame size
based on the information from CPUID and XFRM. The SSA frame size is
a total of XSAVE area size + GPRs + MISC region, and on feature-rich
CPUs may exceed 1 page. Thus, the SSA frame size in the SIGSTRUCT
(during SGX signing) and in the SECS (during runtime) may mismatch on
such CPUs, and EINIT fails with SGX_INVALID_MEASUREMENT. This commit
simply hard-codes SSA frame size to overapproximated value of 4 pages.
Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
`Scripts/Makefile.rules` used MAKEFILE_LIST to obtain the current
makefile path, but it did so after including some other file, so it got
the included file path instead.
Signed-off-by: borysp <borysp@invisiblethingslab.com>
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.
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").
Commit "Introduce one, central manifest, zero-config children and
constant MRENCLAVE" broke GSC. This commit fixes GSC (mainly adjusts
it the single-manifest change in that commit). Also, significant
internal refactoring is done (no user-visible changes). Also, scripts
now explicitly use UTF-8 when reading/writing the manifest files because
they are written in TOML which forces UTF-8.
On certain servers the number of cache sets can be greater than
`1 << 16`. This patch increases the sanity check limit to `1 << 30`
to validate against such large number of cache sets.
Seems that no one has used this feature since its deprecation 1.5 year
ago. Let's not clutter the main readme with it.
Also dropped a section from building instructions, as it was quite
useless.
- Extract parts that are common for all hosts
- Remove some outdated/unnecessary options, we should now be
closer to default configuration
- Disable libthread_db loading (does not work and crashes GDB 9.2)
- Disable pagination when loading debug maps
Intel SGX driver was upstreamed in Linux version 5.11. There, the SGX
device is exposed as `/dev/sgx_enclave` instead of `/dev/sgx/enclave`.
This commit updates link-intel-driver.py to recognize this new name.
This section was quite useless, the manifest included there didn't
really allow to run any application. Better to just link to the complete
and up-to-date guide from our docs.
The generated-offsets headers have to depend on the code that
defines the relevant data structures. Otherwise, when the data
structures change, the code will get compiled with wrong offsets
and will crash.
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.
Replace the old SGX_DBG macro with new subsystem (log_* inside
enclave, urts_log_* outside enclave).
Adjust log levels of some messages, and remove some unnecessary
ones.
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.