523 Commits
Author SHA1 Message Date
Paweł Marczewski 2cfdd510dc [LibOS] Remove dynamic linking
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>
2021-02-18 02:48:02 +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
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
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
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
Li, Xun 1ddfd0e36f [LibOS] Allow but ignore MSG_WAITALL flag in recv 2021-02-03 01:16:43 +01: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
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
Paweł Marczewski 8ca27bd3c4 [Pal] Log to stderr, not stdout 2021-01-23 01:58:26 +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
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
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
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
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
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
Rafał WojdyłaandDmitrii Kuvaiskii 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 0c3324aa06 [Pal/{Linux,Linux-SGX}] Allow communication with host devices
Previously, Graphene supported only /dev/tty (stdin/stdout terminal)
device. This commit introduces support for other, arbitrary host
devices. The devices must be explicitly allowed in the manifest via
a mount point like this:

  fs.mount.devkmsg.type = chroot
  fs.mount.devkmsg.path = /dev/kmsg
  fs.mount.devkmsg.uri  = dev:/dev/kmsg

Currently only open/read/write/close/fstat are supported. lseek is
supported only with offset 0 (and it is not device-specific). Support
for IOCTLs will be introduced in future commits. A simple test is
added to LibOS regression tests.
2020-12-01 07:24:42 -08:00
Paweł Marczewski 6c8321b1ca [LibOS] test/regression: Fix exit_group test
The exit code of the test was a random number between 0 and 4,
which gave no guarantee that the right code from exit() will
actually reach the user.

Instead of testing a race between threads, make it possible to
call exit() in a chosen thread, and verify that it always works.

In addition, propagate the exit code from a forked process. That
use case was broken recently and has been fixed in the commit
titled 'Rework threads implementation'.
2020-11-20 16:35:16 +01:00
borysp 8ff79072f5 [LTP] Enable passing tests 2020-11-19 18:35:27 +01:00
borysp 2a95cd5f25 [LibOS] Rework threads implementation
Most important differences from the old version:
- strip global process information from the thread struct into a
  dedicated one,
- a parent is informed about the child death when the whole process
  (the last thread) dies (not on each thread exit),
- all threads have the same parent (spawning thread is NOT the parent of
  the spawned thread),
- a thread is able to wait on children created by another thread,
- a process is able to wait for exited children after execve,
- rewritten `waitid` implementation (no more gotos, supports __WCLONE
  and friends flags),
- added option for syscall restarting, for now used only in `waitid`.

Additionally various bugfixes, cleanups and missing locks added.
2020-11-19 18:35:27 +01:00
Paweł Marczewski e5988071ba [Pal,LibOS] tests: Remove unnecessary usage of get_manifest() 2020-11-18 00:29:43 +01:00
Paweł Marczewski 38bf50c4c5 [Pal,LibOS] Fix loader.debug_type = file
Logging to file was broken, because the PAL file write operation
required the user to provide an absolute offset, and LibOS always
provided an offset of 0. This worked when logging to stdout, but
in case of a regular file, it kept overwriting the beginning of
file.

To fix that, we introduce a a special DkDebugLog call. This is a
better solution than tracking the file offset manually, because
the offset would need to be synchronized across different threads
and processes, and debug logs should be as simple as possible. At
the same time, we don't want PAL to provide a generic "append to
a file" mechanism, because it makes I/O less deterministic.
2020-11-17 23:56:28 +01:00
Paweł Marczewski 1d25612006 [CI] Enable pylint unconditionally, fix violations
Pylint output was filtered so that many files with existing pylint
violations were allowed to stay broken.

I made sure all files pass pylint, but whitelisted some rules that
we commonly disable:

* missing docstrings: most of the code is tests/internal anyway
* invalid-name: too many violations, and we commonly use one- or
  two-character names (like "a, b" or "t1, t2") which is
  disallowed by this rule; we could tweak it and then fix
  remaining violations such as camel-case or lowercase constants
* fixme: we leave TODOs as a matter of practice, same as in C
* high-level style rules like too-few-* and too-many-*,
  no-self-use

Hopefully that will make using pylint less annoying, while also
catching serious issues (such as unused variables or imports).
2020-11-17 13:45:09 -08:00
Paweł Marczewski 5ba470800d [CI] Add back gitignore-test to all configurations
Removed by mistake in "[LibOS] test/ltp: Upgrade LTP to 20200930".

Also add two files that have been merged without gitignore in the
meantime.
2020-11-17 05:28:56 -08:00
Dmitrii Kuvaiskii c5f010b9e0 [Pal/{Linux,Linux-SGX}] Refactor "device" PAL handles 2020-11-16 01:08:13 -08:00
Dmitrii Kuvaiskii 8eee4a4742 [LibOS,Pal,Examples,GSC,Docs] Move manifest parsing to TOML
The manifest syntax stays exactly the same, including 0 and 1
integers to denote boolean values (this is done for ease of porting
and can be fixed in future commits). The only visible change is
surrounding strings in the manifest with quotes (requirement of
TOML). All manifests and Makefiles of our tests and example apps are
ported to the new TOML syntax. Documentation is updated.
2020-11-12 05:45:07 -08:00
Paweł Marczewski a353f54296 [LibOS] Fix fcntl(F_DUPFD) hang
The operation loops indefinitely on error. Instead, it should find
the first free FD, and then try allocating it.

In addition, the right error after exceeding the limit is EMFILE
(however, dup2() is still supposed to return EBADF if asking for
an out-of-range value, as checked by the dup201 LTP test).
2020-11-12 11:55:52 +01:00
Paweł Marczewski 193978193c [LibOS] test/ltp: Show all tests with make regression V=1 2020-11-12 11:55:52 +01:00
Paweł Marczewski a1f1cc4c50 [LibOS] Fix sethostname()/setdomainname()
The functions incorrectly pad the char array with zeroes.
2020-11-12 11:55:52 +01:00
Paweł Marczewski b8da38b945 [LibOS] Fix readv() on zero-length data 2020-11-12 11:55:52 +01:00
Paweł Marczewski 616816244e [LibOS] Fix truncate()/ftruncate() with negative lengths
There was no error checking before the value ultimately got passed
to an unsigned argument deep inside PAL.
2020-11-12 11:55:52 +01:00
Paweł Marczewski ebe7715d3a [LibOS] Fix execve() corner cases
- Return EACCES if the file has no execute permission
- Return ENOEXEC if the file is not recognized as either ELF or
  shebang script
2020-11-12 11:55:52 +01:00
Paweł Marczewski 7ef9601501 [LibOS] Fix clock corner cases
- return EINVAL for invalid clock type
- for clock_getres: allow null pointer as argument
- for nanosleep/clock_nanosleep: check timespec
2020-11-12 11:55:52 +01:00
Stefan Berger 6eff7da03e [LibOS] regression: Remove unnecessary asm from pthread_set_get_affinity 2020-11-09 23:46:39 -08:00
Vijay Dhanraj 96e8b05a64 [LibOS] Fix type field in dirent struct
Currently in Graphene, the type field in dirent struct is only updated
for parent directory and is set to DT_UNKNOWN type for its children.
But APIs like `sysconf(_SC_NPROCESSORS_CONF)` rely on type field to
identify the number of processors on the host by reading the number of
cpuX directories and ensuring their type is set to DT_DIR. This commit
addresses the issue by updating the dirent type appropriately even for
child directories or files.
2020-11-08 23:26:53 -08:00
Vijay DhanrajandGary 3fa93cc86f [LibOS,Pal] Add sched_setaffinity/sched_getaffinity syscall support
This patch adds syscall support for setting/getting cpu affinity
of threads.

Co-authored-by: Gary <gordon.king@intel.com>
2020-11-06 22:28:32 +01:00
Vijay Dhanraj cadcb2a6ee [LibOS] Fix absolute path handling in *at() syscalls
As per linux man-pages, dirfd can be ignored if an absolute path is
provided when invoking *at() calls. But in Graphene many of the *at()
calls require a valid dirfd even when an absolute path is provided. If
not, the call fails. This commit fixes the issue by ignoring dirfd if
absolute filepath is provided.
2020-11-05 18:20:00 +01:00
Dmitrii Kuvaiskii eb0e726625 [Pal/Linux-SGX] Allow EPID attestation even with DCAP SGX driver
Previously, Graphene assumed that if it was built with the DCAP
SGX driver or in-kernel SGX driver, then it should use DCAP/ECDSA
based attestation. In fact, the SGX driver has nothing to do with
the attestation scheme. This commit allows to use EPID based
attestation even when Graphene is built with the DCAP SGX driver.
2020-11-03 06:24:02 -08:00
Paweł Marczewski eeda995edc [LibOS] test/ltp: Update tests after LTP upgrade 2020-11-03 01:41:33 +01:00
Paweł Marczewski c581dc3248 [LibOS] test/ltp: Print number of passed tests
The XML output doesn't contain this information, but it's useful
for the user.
2020-11-03 01:41:33 +01:00
Paweł Marczewski 4873550097 [LibOS] test/ltp: Remove outdated tests from configuration 2020-11-03 01:41:33 +01:00
Paweł Marczewski abe3d77552 [LibOS] test/ltp: Upgrade LTP to 20200930
- Remove old LTP bug workaround from Jenkins files
- Add pkg-config as an explicit dependency (it wasn't installed on
  Ubuntu 16 and LTP won't build without it)
2020-11-03 01:41:33 +01:00
Paweł Marczewski b6b9a35f23 [LibOS] ltp: Document scripts in contrib/ 2020-10-29 17:52:28 +01:00
Paweł Marczewski 0d81e26b8f [LibOS] test/ltp: Document debugging the tests 2020-10-29 17:52:28 +01:00
Paweł Marczewski 3b14680da0 [LibOS] test/ltp: Partial cleanup of the test list
- Add short comments to tests that I've had time to investigate
- Collapse some test groups where we simply do not support the
  feature being tested (e.g. a syscall) using a wildcard. Until we
  implement it, we will not care about any new tests, and having
  all the tests separately is just noise.
- Unskip some tests that seem to pass now
2020-10-29 17:52:24 +01:00
Paweł Marczewski e972b45f35 [LibOS] test/ltp: Reduce ltp-sgx.cfg
Keep only sections that differ from ltp.cfg, so that the file is
easier to maintain. Done automatically using
contrib/conf_subtract.py.

(As far as I can tell, there are no tests disabled in Linux and
enabled in Linux-SGX, only the other way around).
2020-10-29 17:51:45 +01:00
Paweł Marczewski bfbcdd1bd2 [LibOS] test/ltp: Detect duplicate configuration sections 2020-10-29 17:51:45 +01:00
Paweł Marczewski 0c8bc35dab [LibOS] test/ltp: Use multiple configuration files
This is to make ltp-sgx.cfg an override for ltp.cfg, instead of
duplicating the content.

I'm also adding config/conf_subtract.py, a quick-and-dirty script
for reducing the ltp-sgx.cfg file (result committed separately).
2020-10-29 17:51:45 +01:00