This commit improves the emulation of recvfrom/sendfrom,
recvmsg/sendmsg, and recvmmsg/sendmmsg system calls. In particular,
MSG_DONTWAIT flag is allowed though not really emulated (benign in
most cases). Also, it is possible now to send/receive FDs via
SCM_RIGHTS on a UNIX domain socket (only send/recv of pipes and UNIX
domain sockets is currently supported). Corresponding LibOS test
is added.
This contains two socket-related changes, which would be hard to factor
out into two commits: (because of compilation warnings)
- Making ocalls use size_t in their interface. It's not the same as
Linux syscall interface anyway, so why not make it sane?
- Fixing sycalls arguments types to match the ones use by kernel.
Note: there's no such type as "socklen_t" in the kernel, so it got
removed.
Introduce PAL_ERROR_CONNFAILED_PIPE and treat EPIPE separately
from ECONNRESET.
The effects of this patch on LTP are:
from:
writev01.c:139: FAIL: write to closed pipe, expected: -1 (EPIPE), got: -1 (ECONNRESET)
to:
writev01.c:139: PASS: write to closed pipe, expected: -1 (EPIPE), got: -1 (EPIPE)
AND:
from:
write05.c:82: FAIL: write() failed unexpectedly, expected EPIPE: ECONNRESET
to:
write05.c:87: FAIL: sigpipe_cnt = 0
writev01 now works correctly, so this commit enables it.
LibOS events create_event() / set_event() / wait_event() are emulated
as reads/writes on a private pipe. On the other hand, PAL API
DkSynchronizationObjectWait() works only on event/mutex objects, not
on pipes. So wait_event(), which previously used this API, failed
on assert because it provided a pipe object. This bug manifests
only in rare circumstances (I found it with Erlang workload) because
wait_event() is called very rarely, on data-race path of epoll wait.
This commit simply removes DkSynchronizationObjectWait() call, so
that the event is awaited via reading from the pipe.
Previously, Graphene returned -EINVAL for select() with all zeroes.
This behavior was chosen due to man page of select: "Some code calls
select() with all three sets empty, nfds zero, and a non-NULL
timeout" (notice "non-NULL timeout"). In reality, Linux allows to
specify timeout as NULL, which leads to indefinite sleep, same as
pause(). This commit forces select() with all zeroes to perform
shim_do_pause() to comply with Linux behavior.
Also, adapt the Makefiles to add the arch specific directory to the CFLAGS.
The Linux-SGX sysdep-x86_64.h was identical and could therefore be removed.
This commit adds support for FIFOs and the corresponding syscalls
mknod() and mknodat(). Internally, FIFOs are emulated as pseudo-
files in chroot mount points (not visible in host FS). FIFOs'
read/write operations are emulated via pipes at PAL level (this
means that they are transparently encrypted under SGX PAL).
Generally, emulation of FIFOs is similar to emulation of named
UNIX domain sockets, i.e., they are "ephemeral" and only allow
communication between two related processes.
New LibOS test is added: multi-process `mkfifo`.
This commit completely reworks VMA subsystem along with its usages.
New version should be: cleaner (easier to maintain), faster and allow
for bookkeeping requests from Pal.
It also fixes some bugs and inconsistencies found in the process and
changes brk and mmap/munmap implementations (at least partially).
Clear Linux ships with Glibc built with `-Wp,-DFORTIFY_SOURCE=2`.
This overwrites Graphene's `-UFORTIFY_SOURCE` because of the quirk
in how GCC applies arguments (first without Wp, then with Wp).
This commit updates Makefiles to use `-Wp,-UFORTIFY_SOURCE`.
GCC 9.3 adds more static checks on C headers and sources. This
commit fixes all detected issues (mainly possible NULL pointer
dereferences and VLAs on stack).
Extend Makefile.configs and define several variables for make to use
derived from 'gcc -dumpmachine'. In particular:
- ARCH as the architecture, e.g., x86_64
- ARCH_LONG as the long version of the architecture, e.g., x86_64-linux-gnu
- ARCH_LIBDIR as the directory where libraries are located,
e.g., /lib/x86_64-linux-gnu
In Makefiles and manifest templates, replace the hard-coded
x86_64-linux_gnu and /lib/x86_64-linux-gnu through these variables.
Extend the already existing sed scripts to replace the necessary
variables.
Currently various flags in file and memory syscalls work mostly by an
accident, because values of some of them align with corresponding Linux
syscall flags. Some APIs weren't that lucky though - e.g.
DkStreamOpen(..., /*options=*/PAL_OPTION_CLOEXEC) deletes file contents
(sic!) intead of opening it with O_CLOEXEC. This is because
PAL_OPTION_CLOEXEC == O_TRUNC.
This commit fixes all this mess and also adds asserts to check validity
of flags passed to Dk* handlers.
This commit adds a new subdirectory in the /dev pseudo-FS and
new pseudo-files to allow applications and helper libraries on
top of Graphene to perform attestation. The currently exposed
primitives are tailored to the Intel SGX local and remote EPID
attestation. App developer writes attestation logic against
this pseudo-FS interface by opening and reading/writing the
following files:
- /dev/attestation/user_report_data: write user-provided report
data used in `report` and `quote` pseudo-files
- /dev/attestation/target_info: write target info used in
`report` and `quote` pseudo-files
- /dev/attestation/my_target_info: read this enclave's target info
- /dev/attestation/report: read report (for local attestation)
- /dev/attestation/quote: read quote (for remote attestation)
This commit also adds a corresponding LibOS test `attestation`.
Current implementation isn't finished, doesn't have a single test and
has quite bad code quality. If we decide we want to implement this
feature, it will be easier to just implement it from scratch.
Previously, Linux-SGX PAL did not encrypt pipe/socketpair
communication (only process checkpoint send/receive was encrypted).
This commit encrypts all pipe/socketpair IPC between threads of
the same enclave and between enclave processes. In particular, all
offsprings of the "first" enclave inherit the same master key and
derive IPC session keys from this master key based on pipe name.
When two pipe/socketpair endpoints are first created, they establish
a TLS-PSK session via intra-enclave handshake (requires a spawn of
an intermediate enclave thread). During clone/fork/exec, endpoints'
TLS contexts are serialized and sent to the child that deserializes
them (using mbedtls_ssl_context_{save,load} functions).
Note that multicast pipes (with more than two communicating entities)
are not supported since TLS protocol doesn't support it.
This commit modifies the PAL `SendHandle` test to correctly test
pipe communication, as well as adds the LibOS `pipe` test.
This patch fixes occasional hangs at termination of programs with threads.
These hangs occurred since the async helper thread did not properly account
for installed cleanup events but exited instead due to its idle counter
reaching the limit. This happened occasionally.
When the cleanup function wasn't called, a thread's clear_tid pointer
wasn't reset and the futex wasn't WAKE'ed and then the main thread would
end up WAITing on the futex (which still had the original thread id as its
value) and then never received the WAKE.
This patch addresses github issue 1416:
https://github.com/oscarlab/graphene/issues/1416
Previously, Graphene used the notation "pipe:<uint32_t>" to emulate
pipes, socketpairs, and UNIX domain sockets. In particular, pipes
and socketpairs received random integer IDs, and sockets received
deterministic integer IDs. However, 32-bit randomly generated IDs
may collide quite often. Since pipe IDs/names should *not* repeat
(otherwise e.g. derived crypto keys will be reused), this commit
changes pipe IDs (pipeid) from uint32_t to char[96], and pipe IDs
(names) become 256-bit random sequences.