diff --git a/.ci/docs.jenkinsfile b/.ci/docs.jenkinsfile
index 5f5904e785..31c5c6fb01 100644
--- a/.ci/docs.jenkinsfile
+++ b/.ci/docs.jenkinsfile
@@ -1,6 +1,6 @@
pipeline {
agent {
- dockerfile { filename '.ci/ubuntu18.04.dockerfile' }
+ dockerfile { filename '.ci/ubuntu20.04.dockerfile' }
}
stages {
stage('build') {
diff --git a/.ci/ubuntu20.04.dockerfile b/.ci/ubuntu20.04.dockerfile
index 791d461b93..07a3bcbd0a 100644
--- a/.ci/ubuntu20.04.dockerfile
+++ b/.ci/ubuntu20.04.dockerfile
@@ -99,6 +99,7 @@ RUN python3 -m pip install -U \
'tomli>=1.1.0' \
'tomli-w>=0.4.0' \
'meson>=0.56,<0.57' \
+ 'recommonmark' \
'docutils>=0.17,<0.18'
CMD ["bash"]
diff --git a/Documentation/conf.py b/Documentation/conf.py
index 126e12a816..cdec511840 100644
--- a/Documentation/conf.py
+++ b/Documentation/conf.py
@@ -20,10 +20,12 @@
import pathlib
import subprocess
+import recommonmark.parser
+
# -- Project information -----------------------------------------------------
project = 'Gramine'
-copyright = '2022, Gramine Contributors'
+copyright = '2023, Gramine Contributors'
author = 'Gramine Contributors'
# The short X.Y version
@@ -42,6 +44,7 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
+ 'recommonmark',
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.napoleon',
@@ -55,6 +58,8 @@
# The suffix(es) of source filenames.
source_suffix = {
'.rst': 'restructuredtext',
+ '.md': 'markdown',
+ '.markdown': 'markdown',
}
# The master toctree document.
diff --git a/Documentation/devel/features.md b/Documentation/devel/features.md
index 6748d5e7dd..a29d7edbad 100644
--- a/Documentation/devel/features.md
+++ b/Documentation/devel/features.md
@@ -2,10 +2,9 @@
# Gramine features
-> :warning: This is a highly technical document, intended for software engineers with knowledge of
-> OS kernels.
+> ⚠ Highly technical document intended for software engineers with knowledge of OS kernels.
-> :construction: This is a living document. The last major update happened in **Feb 2023**.
+> ⛏ This is a living document. The last major update happened in **Feb 2023**.
Gramine strives to **support native, unmodified Linux applications** on any platform. The SGX
backend additionally strives to **provide security guarantees**, in particular, protect against a
@@ -78,9 +77,9 @@ Similarly to Linux, Gramine provides two interfaces to user applications:
Legend:
-- :white_check_mark: implemented (no serious limitations)
-- :ballot_box_with_check: partially implemented (serious limitations or quirks)
-- :x: not implemented
+- ☑ implemented (no serious limitations)
+- ☐ partially implemented (serious limitations or quirks)
+- ☒ not implemented
## List of system calls
@@ -96,45 +95,45 @@ world workloads.
The below list is generated from the [syscall table of Linux
6.0](https://github.com/torvalds/linux/blob/v6.0/arch/x86/entry/syscalls/syscall_64.tbl).
-:blue_book: Status of system call support in Gramine
+Status of system call support in Gramine
-- :white_check_mark: `read()`
+- ☑ `read()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
[5](#event-notifications-eventfd)
-- :white_check_mark: `write()`
+- ☑ `write()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
[5](#event-notifications-eventfd)
-- :ballot_box_with_check: `open()`
+- ☐ `open()`
[1](#file-system-operations)
-- :white_check_mark: `close()`
+- ☑ `close()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
[5](#event-notifications-eventfd)
-- :ballot_box_with_check: `stat()`
+- ☐ `stat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `fstat()`
+- ☐ `fstat()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
-- :ballot_box_with_check: `lstat()`
+- ☐ `lstat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `poll()`
+- ☐ `poll()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -142,63 +141,63 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :ballot_box_with_check: `lseek()`
+- ☐ `lseek()`
[1](#file-system-operations)
-- :ballot_box_with_check: `mmap()`
+- ☐ `mmap()`
[1](#memory-management)
[2](#file-system-operations)
-- :ballot_box_with_check: `mprotect()`
+- ☐ `mprotect()`
[1](#memory-management)
-- :white_check_mark: `munmap()`
+- ☑ `munmap()`
[1](#memory-management)
-- :white_check_mark: `brk()`
+- ☑ `brk()`
[1](#memory-management)
[2](#system-information-and-resource-accounting)
-- :white_check_mark: `rt_sigaction()`
+- ☑ `rt_sigaction()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `rt_sigprocmask()`
+- ☑ `rt_sigprocmask()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `rt_sigreturn()`
+- ☑ `rt_sigreturn()`
[1](#signals-and-process-state-changes)
-- :ballot_box_with_check: `ioctl()`
+- ☐ `ioctl()`
[1](#pipes-and-fifos-named-pipes)
[2](#tcpip-and-udpip-sockets)
[3](#unix-domain-sockets)
[4](#ioctls)
-- :white_check_mark: `pread64()`
+- ☑ `pread64()`
[1](#file-system-operations)
-- :white_check_mark: `pwrite64()`
+- ☑ `pwrite64()`
[1](#file-system-operations)
-- :white_check_mark: `readv()`
+- ☑ `readv()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
-- :white_check_mark: `writev()`
+- ☑ `writev()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
-- :ballot_box_with_check: `access()`
+- ☐ `access()`
[1](#file-system-operations)
-- :white_check_mark: `pipe()`
+- ☑ `pipe()`
[1](#pipes-and-fifos-named-pipes)
-- :ballot_box_with_check: `select()`
+- ☐ `select()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -206,599 +205,599 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :white_check_mark: `sched_yield()`
+- ☑ `sched_yield()`
[1](#scheduling)
-- :x: `mremap()`
+- ☒ `mremap()`
[1](#memory-management)
-- :ballot_box_with_check: `msync()`
+- ☐ `msync()`
[1](#memory-management)
[2](#file-system-operations)
-- :ballot_box_with_check: `mincore()`
+- ☐ `mincore()`
[1](#memory-management)
-- :ballot_box_with_check: `madvise()`
+- ☐ `madvise()`
[1](#memory-management)
-- :x: `shmget()`
+- ☒ `shmget()`
[1](#shared-memory)
-- :x: `shmat()`
+- ☒ `shmat()`
[1](#shared-memory)
-- :x: `shmctl()`
+- ☒ `shmctl()`
[1](#shared-memory)
-- :white_check_mark: `dup()`
+- ☑ `dup()`
[1](#misc)
-- :white_check_mark: `dup2()`
+- ☑ `dup2()`
[1](#misc)
-- :white_check_mark: `pause()`
+- ☑ `pause()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `nanosleep()`
+- ☑ `nanosleep()`
[1](#sleeps-timers-and-alarms)
-- :ballot_box_with_check: `getitimer()`
+- ☐ `getitimer()`
[1](#sleeps-timers-and-alarms)
-- :white_check_mark: `alarm()`
+- ☑ `alarm()`
[1](#sleeps-timers-and-alarms)
-- :ballot_box_with_check: `setitimer()`
+- ☐ `setitimer()`
[1](#sleeps-timers-and-alarms)
-- :white_check_mark: `getpid()`
+- ☑ `getpid()`
[1](#process-and-thread-identifiers)
-- :ballot_box_with_check: `sendfile()`
+- ☐ `sendfile()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
-- :ballot_box_with_check: `socket()`
+- ☐ `socket()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `connect()`
+- ☑ `connect()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `accept()`
+- ☑ `accept()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :ballot_box_with_check: `sendto()`
+- ☐ `sendto()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :ballot_box_with_check: `recvfrom()`
+- ☐ `recvfrom()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :ballot_box_with_check: `sendmsg()`
+- ☐ `sendmsg()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :ballot_box_with_check: `recvmsg()`
+- ☐ `recvmsg()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `shutdown()`
+- ☑ `shutdown()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `bind()`
+- ☑ `bind()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `listen()`
+- ☑ `listen()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `getsockname()`
+- ☑ `getsockname()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `getpeername()`
+- ☑ `getpeername()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `socketpair()`
+- ☑ `socketpair()`
[1](#unix-domain-sockets)
-- :white_check_mark: `setsockopt()`
+- ☑ `setsockopt()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `getsockopt()`
+- ☑ `getsockopt()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :white_check_mark: `clone()`
+- ☑ `clone()`
[1](#processes)
[2](#threads)
-- :white_check_mark: `fork()`
+- ☑ `fork()`
[1](#processes)
-- :white_check_mark: `vfork()`
+- ☑ `vfork()`
[1](#processes)
-- :white_check_mark: `execve()`
+- ☑ `execve()`
[1](#processes)
-- :white_check_mark: `exit()`
+- ☑ `exit()`
[1](#processes)
[2](#threads)
-- :ballot_box_with_check: `wait4()`
+- ☐ `wait4()`
[1](#signals-and-process-state-changes)
-- :ballot_box_with_check: `kill()`
+- ☐ `kill()`
[1](#signals-and-process-state-changes)
-- :ballot_box_with_check: `uname()`
+- ☐ `uname()`
[1](#system-information-and-resource-accounting)
-- :x: `semget()`
+- ☒ `semget()`
[1](#semaphores)
-- :x: `semop()`
+- ☒ `semop()`
[1](#semaphores)
-- :x: `semctl()`
+- ☒ `semctl()`
[1](#semaphores)
-- :x: `shmdt()`
+- ☒ `shmdt()`
[1](#shared-memory)
-- :x: `msgget()`
+- ☒ `msgget()`
[1](#message-queues)
-- :x: `msgsnd()`
+- ☒ `msgsnd()`
[1](#message-queues)
-- :x: `msgrcv()`
+- ☒ `msgrcv()`
[1](#message-queues)
-- :x: `msgctl()`
+- ☒ `msgctl()`
[1](#message-queues)
-- :ballot_box_with_check: `fcntl()`
+- ☐ `fcntl()`
[1](#file-locking)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
[4](#unix-domain-sockets)
[5](#misc)
-- :x: `flock()`
+- ☒ `flock()`
[1](#file-locking)
-- :white_check_mark: `fsync()`
+- ☑ `fsync()`
[1](#file-system-operations)
-- :white_check_mark: `fdatasync()`
+- ☑ `fdatasync()`
[1](#file-system-operations)
-- :ballot_box_with_check: `truncate()`
+- ☐ `truncate()`
[1](#file-system-operations)
-- :ballot_box_with_check: `ftruncate()`
+- ☐ `ftruncate()`
[1](#file-system-operations)
-- :white_check_mark: `getdents()`
+- ☑ `getdents()`
[1](#file-system-operations)
-- :white_check_mark: `getcwd()`
+- ☑ `getcwd()`
[1](#file-system-operations)
-- :white_check_mark: `chdir()`
+- ☑ `chdir()`
[1](#file-system-operations)
-- :white_check_mark: `fchdir()`
+- ☑ `fchdir()`
[1](#file-system-operations)
-- :ballot_box_with_check: `rename()`
+- ☐ `rename()`
[1](#file-system-operations)
-- :white_check_mark: `mkdir()`
+- ☑ `mkdir()`
[1](#file-system-operations)
-- :white_check_mark: `rmdir()`
+- ☑ `rmdir()`
[1](#file-system-operations)
-- :white_check_mark: `creat()`
+- ☑ `creat()`
[1](#file-system-operations)
-- :x: `link()`
+- ☒ `link()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :white_check_mark: `unlink()`
+- ☑ `unlink()`
[1](#file-system-operations)
-- :x: `symlink()`
+- ☒ `symlink()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :ballot_box_with_check: `readlink()`
+- ☐ `readlink()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :white_check_mark: `chmod()`
+- ☑ `chmod()`
[1](#file-system-operations)
-- :white_check_mark: `fchmod()`
+- ☑ `fchmod()`
[1](#file-system-operations)
-- :ballot_box_with_check: `chown()`
+- ☐ `chown()`
[1](#file-system-operations)
-- :ballot_box_with_check: `fchown()`
+- ☐ `fchown()`
[1](#file-system-operations)
-- :x: `lchown()`
+- ☒ `lchown()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :white_check_mark: `umask()`
+- ☑ `umask()`
[1](#file-system-operations)
-- :white_check_mark: `gettimeofday()`
+- ☑ `gettimeofday()`
[1](#date-and-time)
[2](#misc)
-- :ballot_box_with_check: `getrlimit()`
+- ☐ `getrlimit()`
[1](#system-information-and-resource-accounting)
-- :x: `getrusage()`
+- ☒ `getrusage()`
[1](#system-information-and-resource-accounting)
-- :ballot_box_with_check: `sysinfo()`
+- ☐ `sysinfo()`
[1](#system-information-and-resource-accounting)
-- :x: `times()`
+- ☒ `times()`
[1](#date-and-time)
-- :x: `ptrace()`
+- ☒ `ptrace()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `getuid()`
+- ☐ `getuid()`
[1](#user-and-group-identifiers)
-- :x: `syslog()`
+- ☒ `syslog()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `getgid()`
+- ☐ `getgid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `setuid()`
+- ☐ `setuid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `setgid()`
+- ☐ `setgid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `geteuid()`
+- ☐ `geteuid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `getegid()`
+- ☐ `getegid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `setpgid()`
+- ☐ `setpgid()`
[1](#user-and-group-identifiers)
-- :white_check_mark: `getppid()`
+- ☑ `getppid()`
[1](#process-and-thread-identifiers)
-- :ballot_box_with_check: `getpgrp()`
+- ☐ `getpgrp()`
[1](#process-and-thread-identifiers)
-- :x: `setsid()`
+- ☒ `setsid()`
[1](#advanced-unimplemented-features)
-- :x: `setreuid()`
+- ☒ `setreuid()`
[1](#user-and-group-identifiers)
-- :x: `setregid()`
+- ☒ `setregid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `getgroups()`
+- ☐ `getgroups()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `setgroups()`
+- ☐ `setgroups()`
[1](#user-and-group-identifiers)
-- :x: `setresuid()`
+- ☒ `setresuid()`
[1](#user-and-group-identifiers)
-- :x: `getresuid()`
+- ☒ `getresuid()`
[1](#user-and-group-identifiers)
-- :x: `setresgid()`
+- ☒ `setresgid()`
[1](#user-and-group-identifiers)
-- :x: `getresgid()`
+- ☒ `getresgid()`
[1](#user-and-group-identifiers)
-- :ballot_box_with_check: `getpgid()`
+- ☐ `getpgid()`
[1](#process-and-thread-identifiers)
-- :x: `setfsuid()`
+- ☒ `setfsuid()`
[1](#user-and-group-identifiers)
-- :x: `setfsgid()`
+- ☒ `setfsgid()`
[1](#user-and-group-identifiers)
-- :x: `getsid()`
+- ☒ `getsid()`
[1](#advanced-unimplemented-features)
-- :x: `capget()`
+- ☒ `capget()`
[1](#advanced-unimplemented-features)
-- :x: `capset()`
+- ☒ `capset()`
[1](#advanced-unimplemented-features)
-- :white_check_mark: `rt_sigpending()`
+- ☑ `rt_sigpending()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `rt_sigtimedwait()`
+- ☑ `rt_sigtimedwait()`
[1](#signals-and-process-state-changes)
-- :x: `rt_sigqueueinfo()`
+- ☒ `rt_sigqueueinfo()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `rt_sigsuspend()`
+- ☑ `rt_sigsuspend()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `sigaltstack()`
+- ☑ `sigaltstack()`
[1](#signals-and-process-state-changes)
-- :x: `utime()`
+- ☒ `utime()`
[1](#file-system-operations)
-- :ballot_box_with_check: `mknod()`
+- ☐ `mknod()`
[1](#pipes-and-fifos-named-pipes)
-- :x: `uselib()`
+- ☒ `uselib()`
[1](#advanced-unimplemented-features)
-- :x: `personality()`
+- ☒ `personality()`
[1](#advanced-unimplemented-features)
-- :x: `ustat()`
+- ☒ `ustat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `statfs()`
+- ☐ `statfs()`
[1](#file-system-operations)
-- :ballot_box_with_check: `fstatfs()`
+- ☐ `fstatfs()`
[1](#file-system-operations)
-- :x: `sysfs()`
+- ☒ `sysfs()`
[1](#file-system-operations)
-- :ballot_box_with_check: `getpriority()`
+- ☐ `getpriority()`
[1](#scheduling)
-- :ballot_box_with_check: `setpriority()`
+- ☐ `setpriority()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_setparam()`
+- ☐ `sched_setparam()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_getparam()`
+- ☐ `sched_getparam()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_setscheduler()`
+- ☐ `sched_setscheduler()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_getscheduler()`
+- ☐ `sched_getscheduler()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_get_priority_max()`
+- ☐ `sched_get_priority_max()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_get_priority_min()`
+- ☐ `sched_get_priority_min()`
[1](#scheduling)
-- :ballot_box_with_check: `sched_rr_get_interval()`
+- ☐ `sched_rr_get_interval()`
[1](#scheduling)
-- :ballot_box_with_check: `mlock()`
+- ☐ `mlock()`
[1](#memory-management)
-- :ballot_box_with_check: `munlock()`
+- ☐ `munlock()`
[1](#memory-management)
-- :ballot_box_with_check: `mlockall()`
+- ☐ `mlockall()`
[1](#memory-management)
-- :ballot_box_with_check: `munlockall()`
+- ☐ `munlockall()`
[1](#memory-management)
-- :x: `vhangup()`
+- ☒ `vhangup()`
[1](#advanced-unimplemented-features)
-- :x: `modify_ldt()`
+- ☒ `modify_ldt()`
[1](#advanced-unimplemented-features)
-- :x: `pivot_root()`
+- ☒ `pivot_root()`
[1](#file-system-operations)
-- :x: `_sysctl()`
+- ☒ `_sysctl()`
[1](#advanced-unimplemented-features)
-- :x: `prctl()`
+- ☒ `prctl()`
[1](#threads)
-- :ballot_box_with_check: `arch_prctl()`
+- ☐ `arch_prctl()`
[1](#threads)
-- :x: `adjtimex()`
+- ☒ `adjtimex()`
[1](#date-and-time)
-- :ballot_box_with_check: `setrlimit()`
+- ☐ `setrlimit()`
[1](#system-information-and-resource-accounting)
-- :white_check_mark: `chroot()`
+- ☑ `chroot()`
[1](#file-system-operations)
-- :x: `sync()`
+- ☒ `sync()`
[1](#file-system-operations)
-- :x: `acct()`
+- ☒ `acct()`
[1](#advanced-unimplemented-features)
-- :x: `settimeofday()`
+- ☒ `settimeofday()`
[1](#date-and-time)
-- :x: `mount()`
+- ☒ `mount()`
[1](#file-system-operations)
-- :x: `umount2()`
+- ☒ `umount2()`
[1](#file-system-operations)
-- :x: `swapon()`
+- ☒ `swapon()`
[1](#advanced-unimplemented-features)
-- :x: `swapoff()`
+- ☒ `swapoff()`
[1](#advanced-unimplemented-features)
-- :x: `reboot()`
+- ☒ `reboot()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `sethostname()`
+- ☐ `sethostname()`
[1](#system-information-and-resource-accounting)
-- :ballot_box_with_check: `setdomainname()`
+- ☐ `setdomainname()`
[1](#system-information-and-resource-accounting)
-- :x: `iopl()`
+- ☒ `iopl()`
[1](#advanced-unimplemented-features)
-- :x: `ioperm()`
+- ☒ `ioperm()`
[1](#advanced-unimplemented-features)
-- :x: `create_module()`
+- ☒ `create_module()`
[1](#advanced-unimplemented-features)
-- :x: `init_module()`
+- ☒ `init_module()`
[1](#advanced-unimplemented-features)
-- :x: `delete_module()`
+- ☒ `delete_module()`
[1](#advanced-unimplemented-features)
-- :x: `get_kernel_syms()`
+- ☒ `get_kernel_syms()`
[1](#advanced-unimplemented-features)
-- :x: `query_module()`
+- ☒ `query_module()`
[1](#advanced-unimplemented-features)
-- :x:`quotactl()`
+- ☒`quotactl()`
[1](#advanced-unimplemented-features)
-- :x: `nfsservctl()`
+- ☒ `nfsservctl()`
[1](#advanced-unimplemented-features)
-- :x: `getpmsg()`
+- ☒ `getpmsg()`
[1](#advanced-unimplemented-features)
-- :x: `putpmsg()`
+- ☒ `putpmsg()`
[1](#advanced-unimplemented-features)
-- :x: `afs_syscall()`
+- ☒ `afs_syscall()`
[1](#advanced-unimplemented-features)
-- :x: `tuxcall()`
+- ☒ `tuxcall()`
[1](#advanced-unimplemented-features)
-- :x: `security()`
+- ☒ `security()`
[1](#advanced-unimplemented-features)
-- :white_check_mark: `gettid()`
+- ☑ `gettid()`
[1](#process-and-thread-identifiers)
-- :x: `readahead()`
+- ☒ `readahead()`
[1](#advanced-unimplemented-features)
-- :x: `setxattr()`
+- ☒ `setxattr()`
[1](#advanced-unimplemented-features)
-- :x: `lsetxattr()`
+- ☒ `lsetxattr()`
[1](#advanced-unimplemented-features)
-- :x: `fsetxattr()`
+- ☒ `fsetxattr()`
[1](#advanced-unimplemented-features)
-- :x: `getxattr()`
+- ☒ `getxattr()`
[1](#advanced-unimplemented-features)
-- :x: `lgetxattr()`
+- ☒ `lgetxattr()`
[1](#advanced-unimplemented-features)
-- :x: `fgetxattr()`
+- ☒ `fgetxattr()`
[1](#advanced-unimplemented-features)
-- :x: `listxattr()`
+- ☒ `listxattr()`
[1](#advanced-unimplemented-features)
-- :x: `llistxattr()`
+- ☒ `llistxattr()`
[1](#advanced-unimplemented-features)
-- :x: `flistxattr()`
+- ☒ `flistxattr()`
[1](#advanced-unimplemented-features)
-- :x: `removexattr()`
+- ☒ `removexattr()`
[1](#advanced-unimplemented-features)
-- :x: `lremovexattr()`
+- ☒ `lremovexattr()`
[1](#advanced-unimplemented-features)
-- :x: `fremovexattr()`
+- ☒ `fremovexattr()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `tkill()`
+- ☐ `tkill()`
[1](#signals-and-process-state-changes)
-- :white_check_mark: `time()`
+- ☑ `time()`
[1](#date-and-time)
-- :ballot_box_with_check: `futex()`
+- ☐ `futex()`
[1](#memory-synchronization-futexes)
-- :white_check_mark: `sched_setaffinity()`
+- ☑ `sched_setaffinity()`
[1](#scheduling)
-- :white_check_mark: `sched_getaffinity()`
+- ☑ `sched_getaffinity()`
[1](#scheduling)
-- :x: `set_thread_area()`
+- ☒ `set_thread_area()`
[1](#threads)
-- :x: `io_setup()`
+- ☒ `io_setup()`
[1](#asynchronous-io)
-- :x: `io_destroy()`
+- ☒ `io_destroy()`
[1](#asynchronous-io)
-- :x: `io_getevents()`
+- ☒ `io_getevents()`
[1](#asynchronous-io)
-- :x: `io_submit()`
+- ☒ `io_submit()`
[1](#asynchronous-io)
-- :x: `io_cancel()`
+- ☒ `io_cancel()`
[1](#asynchronous-io)
-- :x: `get_thread_area()`
+- ☒ `get_thread_area()`
[1](#threads)
-- :x: `lookup_dcookie()`
+- ☒ `lookup_dcookie()`
[1](#advanced-unimplemented-features)
-- :white_check_mark: `epoll_create()`
+- ☑ `epoll_create()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -806,55 +805,55 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :x: `remap_file_pages()`
+- ☒ `remap_file_pages()`
[1](#memory-management)
-- :white_check_mark: `getdents64()`
+- ☑ `getdents64()`
[1](#file-system-operations)
-- :white_check_mark: `set_tid_address()`
+- ☑ `set_tid_address()`
[1](#process-and-thread-identifiers)
-- :x: `restart_syscall()`
+- ☒ `restart_syscall()`
[1](#advanced-unimplemented-features)
-- :x: `semtimedop()`
+- ☒ `semtimedop()`
[1](#semaphores)
-- :ballot_box_with_check: `fadvise64()`
+- ☐ `fadvise64()`
[1](#file-system-operations)
-- :x: `timer_create()`
+- ☒ `timer_create()`
[1](#sleeps-timers-and-alarms)
-- :x: `timer_settime()`
+- ☒ `timer_settime()`
[1](#sleeps-timers-and-alarms)
-- :x: `timer_gettime()`
+- ☒ `timer_gettime()`
[1](#sleeps-timers-and-alarms)
-- :x: `timer_getoverrun()`
+- ☒ `timer_getoverrun()`
[1](#sleeps-timers-and-alarms)
-- :x: `timer_delete()`
+- ☒ `timer_delete()`
[1](#sleeps-timers-and-alarms)
-- :x: `clock_settime()`
+- ☒ `clock_settime()`
[1](#date-and-time)
-- :ballot_box_with_check: `clock_gettime()`
+- ☐ `clock_gettime()`
[1](#date-and-time)
-- :ballot_box_with_check: `clock_getres()`
+- ☐ `clock_getres()`
[1](#date-and-time)
-- :ballot_box_with_check: `clock_nanosleep()`
+- ☐ `clock_nanosleep()`
[1](#sleeps-timers-and-alarms)
-- :white_check_mark: `exit_group()`
+- ☑ `exit_group()`
[1](#processes)
-- :white_check_mark: `epoll_wait()`
+- ☑ `epoll_wait()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -862,7 +861,7 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :white_check_mark: `epoll_ctl()`
+- ☑ `epoll_ctl()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -870,115 +869,115 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :white_check_mark: `tgkill()`
+- ☑ `tgkill()`
[1](#signals-and-process-state-changes)
-- :x: `utimes()`
+- ☒ `utimes()`
[1](#file-system-operations)
-- :x: `vserver()`
+- ☒ `vserver()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `mbind()`
+- ☐ `mbind()`
[1](#memory-management)
-- :x: `set_mempolicy()`
+- ☒ `set_mempolicy()`
[1](#memory-management)
-- :x: `get_mempolicy()`
+- ☒ `get_mempolicy()`
[1](#memory-management)
-- :x: `mq_open()`
+- ☒ `mq_open()`
[1](#message-queues)
-- :x: `mq_unlink()`
+- ☒ `mq_unlink()`
[1](#message-queues)
-- :x: `mq_timedsend()`
+- ☒ `mq_timedsend()`
[1](#message-queues)
-- :x: `mq_timedreceive()`
+- ☒ `mq_timedreceive()`
[1](#message-queues)
-- :x: `mq_notify()`
+- ☒ `mq_notify()`
[1](#message-queues)
-- :x: `mq_getsetattr()`
+- ☒ `mq_getsetattr()`
[1](#message-queues)
-- :x: `kexec_load()`
+- ☒ `kexec_load()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `waitid()`
+- ☐ `waitid()`
[1](#signals-and-process-state-changes)
-- :x: `add_key()`
+- ☒ `add_key()`
[1](#advanced-unimplemented-features)
-- :x: `request_key()`
+- ☒ `request_key()`
[1](#advanced-unimplemented-features)
-- :x: `keyctl()`
+- ☒ `keyctl()`
[1](#advanced-unimplemented-features)
-- :x: `ioprio_set()`
+- ☒ `ioprio_set()`
[1](#scheduling)
-- :x: `ioprio_get()`
+- ☒ `ioprio_get()`
[1](#scheduling)
-- :x: `inotify_init()`
+- ☒ `inotify_init()`
[1](#monitoring-filesystem-events-inotify-fanotify)
-- :x: `inotify_add_watch()`
+- ☒ `inotify_add_watch()`
[1](#monitoring-filesystem-events-inotify-fanotify)
-- :x: `inotify_rm_watch()`
+- ☒ `inotify_rm_watch()`
[1](#monitoring-filesystem-events-inotify-fanotify)
-- :x: `migrate_pages()`
+- ☒ `migrate_pages()`
[1](#memory-management)
-- :ballot_box_with_check: `openat()`
+- ☐ `openat()`
[1](#file-system-operations)
-- :white_check_mark: `mkdirat()`
+- ☑ `mkdirat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `mknodat()`
+- ☐ `mknodat()`
[1](#pipes-and-fifos-named-pipes)
-- :ballot_box_with_check: `fchownat()`
+- ☐ `fchownat()`
[1](#file-system-operations)
-- :x: `futimesat()`
+- ☒ `futimesat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `newfstatat()`
+- ☐ `newfstatat()`
[1](#file-system-operations)
-- :white_check_mark: `unlinkat()`
+- ☑ `unlinkat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `renameat()`
+- ☐ `renameat()`
[1](#file-system-operations)
-- :x: `linkat()`
+- ☒ `linkat()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :x: `symlinkat()`
+- ☒ `symlinkat()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :ballot_box_with_check: `readlinkat()`
+- ☐ `readlinkat()`
[1](#hard-links-and-soft-links-symbolic-links)
-- :white_check_mark: `fchmodat()`
+- ☑ `fchmodat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `faccessat()`
+- ☐ `faccessat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `pselect6()`
+- ☐ `pselect6()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -986,7 +985,7 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :ballot_box_with_check: `ppoll()`
+- ☐ `ppoll()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -994,35 +993,35 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :x: `unshare()`
+- ☒ `unshare()`
[1](#processes)
[2](#advanced-unimplemented-features)
-- :white_check_mark: `set_robust_list()`
+- ☑ `set_robust_list()`
[1](#memory-synchronization-futexes)
-- :white_check_mark: `get_robust_list()`
+- ☑ `get_robust_list()`
[1](#memory-synchronization-futexes)
-- :x: `splice()`
+- ☒ `splice()`
[1](#advanced-unimplemented-features)
-- :x: `tee()`
+- ☒ `tee()`
[1](#advanced-unimplemented-features)
-- :x: `sync_file_range()`
+- ☒ `sync_file_range()`
[1](#file-system-operations)
-- :x: `vmsplice()`
+- ☒ `vmsplice()`
[1](#advanced-unimplemented-features)
-- :x: `move_pages()`
+- ☒ `move_pages()`
[1](#memory-management)
-- :x: `utimensat()`
+- ☒ `utimensat()`
[1](#file-system-operations)
-- :ballot_box_with_check: `epoll_pwait()`
+- ☐ `epoll_pwait()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -1030,35 +1029,35 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :x: `signalfd()`
+- ☒ `signalfd()`
[1](#signals-and-process-state-changes)
-- :x: `timerfd_create()`
+- ☒ `timerfd_create()`
[1](#sleeps-timers-and-alarms)
-- :ballot_box_with_check: `eventfd()`
+- ☐ `eventfd()`
[1](#event-notifications-eventfd)
-- :ballot_box_with_check: `fallocate()`
+- ☐ `fallocate()`
[1](#file-system-operations)
-- :x: `timerfd_settime()`
+- ☒ `timerfd_settime()`
[1](#sleeps-timers-and-alarms)
-- :x: `timerfd_gettime()`
+- ☒ `timerfd_gettime()`
[1](#sleeps-timers-and-alarms)
-- :white_check_mark: `accept4()`
+- ☑ `accept4()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :x: `signalfd4()`
+- ☒ `signalfd4()`
[1](#signals-and-process-state-changes)
-- :ballot_box_with_check: `eventfd2()`
+- ☐ `eventfd2()`
[1](#event-notifications-eventfd)
-- :white_check_mark: `epoll_create1()`
+- ☑ `epoll_create1()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -1066,192 +1065,192 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :white_check_mark: `dup3()`
+- ☑ `dup3()`
[1](#misc)
-- :ballot_box_with_check: `pipe2()`
+- ☐ `pipe2()`
[1](#pipes-and-fifos-named-pipes)
-- :x: `inotify_init1()`
+- ☒ `inotify_init1()`
[1](#monitoring-filesystem-events-inotify-fanotify)
-- :white_check_mark: `preadv()`
+- ☑ `preadv()`
[1](#file-system-operations)
-- :white_check_mark: `pwritev()`
+- ☑ `pwritev()`
[1](#file-system-operations)
-- :x: `rt_tgsigqueueinfo()`
+- ☒ `rt_tgsigqueueinfo()`
[1](#signals-and-process-state-changes)
-- :x: `perf_event_open()`
+- ☒ `perf_event_open()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `recvmmsg()`
+- ☐ `recvmmsg()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :x: `fanotify_init()`
+- ☒ `fanotify_init()`
[1](#monitoring-filesystem-events-inotify-fanotify)
-- :x: `fanotify_mark()`
+- ☒ `fanotify_mark()`
[1](#monitoring-filesystem-events-inotify-fanotify)
-- :ballot_box_with_check: `prlimit64()`
+- ☐ `prlimit64()`
[1](#system-information-and-resource-accounting)
-- :x: `name_to_handle_at()`
+- ☒ `name_to_handle_at()`
[1](#file-system-operations)
-- :x: `open_by_handle_at()`
+- ☒ `open_by_handle_at()`
[1](#file-system-operations)
-- :x: `clock_adjtime()`
+- ☒ `clock_adjtime()`
[1](#date-and-time)
-- :x: `syncfs()`
+- ☒ `syncfs()`
[1](#file-system-operations)
-- :ballot_box_with_check: `sendmmsg()`
+- ☐ `sendmmsg()`
[1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
-- :x: `setns()`
+- ☒ `setns()`
[1](#advanced-unimplemented-features)
-- :ballot_box_with_check: `getcpu()`
+- ☐ `getcpu()`
[1](#scheduling)
[2](#misc)
-- :x: `process_vm_readv()`
+- ☒ `process_vm_readv()`
[1](#advanced-unimplemented-features)
-- :x: `process_vm_writev()`
+- ☒ `process_vm_writev()`
[1](#advanced-unimplemented-features)
-- :x: `kcmp()`
+- ☒ `kcmp()`
[1](#processes)
-- :x: `finit_module()`
+- ☒ `finit_module()`
[1](#advanced-unimplemented-features)
-- :x: `sched_setattr()`
+- ☒ `sched_setattr()`
[1](#scheduling)
-- :x: `sched_getattr()`
+- ☒ `sched_getattr()`
[1](#scheduling)
-- :x: `renameat2()`
+- ☒ `renameat2()`
[1](#file-system-operations)
-- :x: `seccomp()`
+- ☒ `seccomp()`
[1](#advanced-unimplemented-features)
-- :white_check_mark: `getrandom()`
+- ☑ `getrandom()`
[1](#randomness)
-- :x: `memfd_create()`
+- ☒ `memfd_create()`
[1](#memory-management)
-- :x: `kexec_file_load()`
+- ☒ `kexec_file_load()`
[1](#advanced-unimplemented-features)
-- :x: `bpf()`
+- ☒ `bpf()`
[1](#advanced-unimplemented-features)
-- :x: `execveat()`
+- ☒ `execveat()`
[1](#processes)
-- :x: `userfaultfd()`
+- ☒ `userfaultfd()`
[1](#signals-and-process-state-changes)
-- :x: `membarrier()`
+- ☒ `membarrier()`
[1](#memory-management)
-- :ballot_box_with_check: `mlock2()`
+- ☐ `mlock2()`
[1](#memory-management)
-- :x: `copy_file_range()`
+- ☒ `copy_file_range()`
[1](#advanced-unimplemented-features)
-- :x: `preadv2()`
+- ☒ `preadv2()`
[1](#file-system-operations)
-- :x: `pwritev2()`
+- ☒ `pwritev2()`
[1](#file-system-operations)
-- :x: `pkey_mprotect()`
+- ☒ `pkey_mprotect()`
[1](#advanced-unimplemented-features)
-- :x: `pkey_alloc()`
+- ☒ `pkey_alloc()`
[1](#advanced-unimplemented-features)
-- :x: `pkey_free()`
+- ☒ `pkey_free()`
[1](#advanced-unimplemented-features)
-- :x: `statx()`
+- ☒ `statx()`
[1](#file-system-operations)
-- :x: `io_pgetevents()`
+- ☒ `io_pgetevents()`
[1](#advanced-unimplemented-features)
-- :x: `rseq()`
+- ☒ `rseq()`
[1](#advanced-unimplemented-features)
-- :x: `pidfd_send_signal()`
+- ☒ `pidfd_send_signal()`
[1](#signals-and-process-state-changes)
-- :x: `io_uring_setup()`
+- ☒ `io_uring_setup()`
[1](#asynchronous-io)
-- :x: `io_uring_enter()`
+- ☒ `io_uring_enter()`
[1](#asynchronous-io)
-- :x: `io_uring_register()`
+- ☒ `io_uring_register()`
[1](#asynchronous-io)
-- :x: `open_tree()`
+- ☒ `open_tree()`
[1](#advanced-unimplemented-features)
-- :x: `move_mount()`
+- ☒ `move_mount()`
[1](#file-system-operations)
-- :x: `fsopen()`
+- ☒ `fsopen()`
[1](#advanced-unimplemented-features)
-- :x: `fsconfig()`
+- ☒ `fsconfig()`
[1](#advanced-unimplemented-features)
-- :x: `fsmount()`
+- ☒ `fsmount()`
[1](#advanced-unimplemented-features)
-- :x: `fspick()`
+- ☒ `fspick()`
[1](#advanced-unimplemented-features)
-- :x: `pidfd_open()`
+- ☒ `pidfd_open()`
[1](#signals-and-process-state-changes)
-- :x: `clone3()`
+- ☒ `clone3()`
[1](#processes)
[2](#threads)
-- :x: `close_range()`
+- ☒ `close_range()`
[1](#advanced-unimplemented-features)
-- :x: `openat2()`
+- ☒ `openat2()`
[1](#file-system-operations)
-- :x: `pidfd_getfd()`
+- ☒ `pidfd_getfd()`
[1](#signals-and-process-state-changes)
-- :x: `faccessat2()`
+- ☒ `faccessat2()`
[1](#file-system-operations)
-- :x: `process_madvise()`
+- ☒ `process_madvise()`
[1](#memory-management)
[2](#signals-and-process-state-changes)
-- :x: `epoll_pwait2()`
+- ☒ `epoll_pwait2()`
[1](#file-system-operations)
[2](#pipes-and-fifos-named-pipes)
[3](#tcpip-and-udpip-sockets)
@@ -1259,35 +1258,35 @@ The below list is generated from the [syscall table of Linux
[5](#io-multiplexing)
[6](#event-notifications-eventfd)
-- :x: `mount_setattr()`
+- ☒ `mount_setattr()`
[1](#file-system-operations)
-- :x: `quotactl_fd()`
+- ☒ `quotactl_fd()`
[1](#advanced-unimplemented-features)
-- :x: `landlock_create_ruleset()`
+- ☒ `landlock_create_ruleset()`
[1](#advanced-unimplemented-features)
-- :x: `landlock_add_rule()`
+- ☒ `landlock_add_rule()`
[1](#advanced-unimplemented-features)
-- :x: `landlock_restrict_self()`
+- ☒ `landlock_restrict_self()`
[1](#advanced-unimplemented-features)
-- :x: `memfd_secret()`
+- ☒ `memfd_secret()`
[1](#memory-management)
-- :x: `process_mrelease()`
+- ☒ `process_mrelease()`
[1](#memory-management)
[2](#signals-and-process-state-changes)
-- :x: `futex_waitv()`
+- ☒ `futex_waitv()`
[1](#memory-synchronization-futexes)
-- :x: `set_mempolicy_home_node()`
+- ☒ `set_mempolicy_home_node()`
[1](#memory-management)
-
+
## List of pseudo-files
@@ -1296,149 +1295,149 @@ Gramine partially emulates Linux pseudo-filesystems: `/dev`, `/proc` and `/sys`.
Only a subset of most widely used pseudo-files is implemented. The list of implemented pseudo-files
grows with time, as Gramine adds functionality required by real world workloads.
-:page_facing_up: List of all pseudo-files in Gramine
+List of all pseudo-files in Gramine
-- :white_check_mark: `/dev/` [1](#hard-links-and-soft-links-symbolic-links)
+- ☑ `/dev/` [1](#hard-links-and-soft-links-symbolic-links)
[2](#semaphores) [3](#shared-memory) [4](#attestation)
- - :white_check_mark: `/dev/attestation/` [1](#attestation)
- - :white_check_mark: `/dev/attestation/attestation_type` [1](#attestation)
- - :white_check_mark: `/dev/attestation/user_report_data` [1](#attestation)
- - :white_check_mark: `/dev/attestation/target_info` [1](#attestation)
- - :white_check_mark: `/dev/attestation/my_target_info` [1](#attestation)
- - :white_check_mark: `/dev/attestation/report` [1](#attestation)
- - :white_check_mark: `/dev/attestation/keys` [1](#attestation)
- - :white_check_mark: `/dev/attestation/keys/` [1](#attestation)
- - :ballot_box_with_check: `/dev/attestation/protected_files_key`
+ - ☑ `/dev/attestation/` [1](#attestation)
+ - ☑ `/dev/attestation/attestation_type` [1](#attestation)
+ - ☑ `/dev/attestation/user_report_data` [1](#attestation)
+ - ☑ `/dev/attestation/target_info` [1](#attestation)
+ - ☑ `/dev/attestation/my_target_info` [1](#attestation)
+ - ☑ `/dev/attestation/report` [1](#attestation)
+ - ☑ `/dev/attestation/keys` [1](#attestation)
+ - ☑ `/dev/attestation/keys/` [1](#attestation)
+ - ☐ `/dev/attestation/protected_files_key`
[1](#attestation)
- - :white_check_mark: `/dev/null` [1](#misc)
- - :white_check_mark: `/dev/zero` [1](#misc)
- - :white_check_mark: `/dev/random` [1](#randomness)
- - :white_check_mark: `/dev/urandom` [1](#randomness)
- - :x: `/dev/shm` [1](#semaphores) [2](#shared-memory)
- - :white_check_mark: `/dev/stdin` [1](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/dev/stdout` [1](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/dev/stderr` [1](#hard-links-and-soft-links-symbolic-links)
-
-- :ballot_box_with_check: `/proc/`
+ - ☑ `/dev/null` [1](#misc)
+ - ☑ `/dev/zero` [1](#misc)
+ - ☑ `/dev/random` [1](#randomness)
+ - ☑ `/dev/urandom` [1](#randomness)
+ - ☒ `/dev/shm` [1](#semaphores) [2](#shared-memory)
+ - ☑ `/dev/stdin` [1](#hard-links-and-soft-links-symbolic-links)
+ - ☑ `/dev/stdout` [1](#hard-links-and-soft-links-symbolic-links)
+ - ☑ `/dev/stderr` [1](#hard-links-and-soft-links-symbolic-links)
+
+- ☐ `/proc/`
[1](#process-and-thread-identifiers)
[2](#user-and-group-identifiers)
[3](#hard-links-and-soft-links-symbolic-links)
[4](#system-information-and-resource-accounting)
[5](#tcpip-and-udpip-sockets) [6](#unix-domain-sockets)
- - :ballot_box_with_check: `/proc/[this-pid]/` (aka `/proc/self/`)
+ - ☐ `/proc/[this-pid]/` (aka `/proc/self/`)
[1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/proc/[this-pid]/cmdline` [1](#process-and-thread-identifiers)
- - :white_check_mark: `/proc/[this-pid]/cwd` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/cmdline` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/cwd` [1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/proc/[this-pid]/exe` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/exe` [1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/proc/[this-pid]/fd` [1](#process-and-thread-identifiers)
- - :white_check_mark: `/proc/[this-pid]/maps` [1](#process-and-thread-identifiers)
- - :white_check_mark: `/proc/[this-pid]/root` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/fd` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/maps` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/root` [1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :ballot_box_with_check: `/proc/[this-pid]/stat`
+ - ☐ `/proc/[this-pid]/stat`
[1](#process-and-thread-identifiers)
- - :ballot_box_with_check: `/proc/[this-pid]/statm`
+ - ☐ `/proc/[this-pid]/statm`
[1](#process-and-thread-identifiers)
- - :ballot_box_with_check: `/proc/[this-pid]/status`
+ - ☐ `/proc/[this-pid]/status`
[1](#process-and-thread-identifiers)
[2](#user-and-group-identifiers)
- - :white_check_mark: `/proc/[this-pid]/task` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[this-pid]/task` [1](#process-and-thread-identifiers)
- - :ballot_box_with_check: `/proc/[remote-pid]/`
+ - ☐ `/proc/[remote-pid]/`
[1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/proc/[remote-pid]/cwd` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[remote-pid]/cwd` [1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/proc/[remote-pid]/exe` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[remote-pid]/exe` [1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :white_check_mark: `/proc/[remote-pid]/root` [1](#process-and-thread-identifiers)
+ - ☑ `/proc/[remote-pid]/root` [1](#process-and-thread-identifiers)
[2](#hard-links-and-soft-links-symbolic-links)
- - :ballot_box_with_check: `/proc/[local-tid]/`
+ - ☐ `/proc/[local-tid]/`
[1](#process-and-thread-identifiers)
- - :x: `/proc/[remote-tid]/` [1](#process-and-thread-identifiers)
+ - ☒ `/proc/[remote-tid]/` [1](#process-and-thread-identifiers)
- - :ballot_box_with_check: `/proc/cpuinfo`
+ - ☐ `/proc/cpuinfo`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/proc/meminfo`
+ - ☐ `/proc/meminfo`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/proc/stat`
+ - ☐ `/proc/stat`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/proc/sys/`
+ - ☐ `/proc/sys/`
[1](#process-and-thread-identifiers)
[2](#tcpip-and-udpip-sockets) [3](#unix-domain-sockets)
- - :ballot_box_with_check: `/proc/sys/kernel/`
+ - ☐ `/proc/sys/kernel/`
[1](#process-and-thread-identifiers)
- - :white_check_mark: `/proc/sys/kernel/pid_max`
+ - ☑ `/proc/sys/kernel/pid_max`
[1](#process-and-thread-identifiers)
- - :x: `/proc/sys/net/` [1](#tcpip-and-udpip-sockets)
+ - ☒ `/proc/sys/net/` [1](#tcpip-and-udpip-sockets)
[2](#unix-domain-sockets)
- - :x: `/proc/sys/net/core/` [1](#tcpip-and-udpip-sockets)
- - :x: `/proc/sys/net/ipv4/` [1](#tcpip-and-udpip-sockets)
- - :x: `/proc/sys/net/ipv6/` [1](#tcpip-and-udpip-sockets)
- - :x: `/proc/sys/net/unix/` [1](#unix-domain-sockets)
+ - ☒ `/proc/sys/net/core/` [1](#tcpip-and-udpip-sockets)
+ - ☒ `/proc/sys/net/ipv4/` [1](#tcpip-and-udpip-sockets)
+ - ☒ `/proc/sys/net/ipv6/` [1](#tcpip-and-udpip-sockets)
+ - ☒ `/proc/sys/net/unix/` [1](#unix-domain-sockets)
-- :ballot_box_with_check: `/sys/devices/system/`
+- ☐ `/sys/devices/system/`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/cpu/`
+ - ☐ `/sys/devices/system/cpu/`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/cpu/cpu[x]/`
+ - ☐ `/sys/devices/system/cpu/cpu[x]/`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/`
+ - ☐ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/coherency_line_size`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/coherency_line_size`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/level`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/level`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/number_of_sets`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/number_of_sets`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/physical_line_partition`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/physical_line_partition`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/shared_cpu_map`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/shared_cpu_map`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/size`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/size`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/type`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/type`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/online`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/online`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/cpu/cpu[x]/topology/`
+ - ☐ `/sys/devices/system/cpu/cpu[x]/topology/`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/core_id`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/core_id`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/core_siblings`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/core_siblings`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/physical_package_id`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/physical_package_id`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/thread_siblings`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/thread_siblings`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/online`
+ - ☑ `/sys/devices/system/cpu/online`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/cpu/possible`
+ - ☑ `/sys/devices/system/cpu/possible`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/node/`
+ - ☐ `/sys/devices/system/node/`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/node/node[x]/`
+ - ☐ `/sys/devices/system/node/node[x]/`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/node/node[x]/cpumap`
+ - ☑ `/sys/devices/system/node/node[x]/cpumap`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/node/node[x]/distance`
+ - ☑ `/sys/devices/system/node/node[x]/distance`
[1](#system-information-and-resource-accounting)
- - :white_check_mark: `/sys/devices/system/node/node[x]/hugepages/`
+ - ☑ `/sys/devices/system/node/node[x]/hugepages/`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check:
+ - ☐
`/sys/devices/system/node/node[x]/hugepages/hugepages-[y]/nr_hugepages`
[1](#system-information-and-resource-accounting)
- - :ballot_box_with_check: `/sys/devices/system/node/node[x]/meminfo`
+ - ☐ `/sys/devices/system/node/node[x]/meminfo`
[1](#system-information-and-resource-accounting)
-
+
## Linux features
@@ -1475,27 +1474,27 @@ ignored.
Gramine does *not* support disassociating parts of the process execution context (via `unshare()`
system call). Gramine does *not* support comparing two processes (via `kcmp()`).
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `execve()`
-- :x: `execveat()`: not used by applications
-- :white_check_mark: `clone()`: except exotic combination `CLONE_VM & !CLONE_THREAD`
-- :white_check_mark: `fork()`
-- :white_check_mark: `vfork()`: with the same semantics as `fork()`
-- :white_check_mark: `exit()`
-- :white_check_mark: `exit_group()`
-- :x: `clone3()`: not used by applications
-- :x: `unshare()`: not used by applications
-- :x: `kcmp()`: not used by applications
+- ☑ `execve()`
+- ☒ `execveat()`: not used by applications
+- ☑ `clone()`: except exotic combination `CLONE_VM & !CLONE_THREAD`
+- ☑ `fork()`
+- ☑ `vfork()`: with the same semantics as `fork()`
+- ☑ `exit()`
+- ☑ `exit_group()`
+- ☒ `clone3()`: not used by applications
+- ☒ `unshare()`: not used by applications
+- ☒ `kcmp()`: not used by applications
-:speech_balloon: Additional materials
+Additional materials
- `LD_LIBRARY_PATH` environment variable is always propagated into new process, see
https://github.com/gramineproject/graphene/issues/2081.
-
+
### Threads
@@ -1519,7 +1518,7 @@ arch-specific (x86-specific) thread state via `arch_prctl(ARCH_GET_FS)` and
`arch_prctl(ARCH_SET_FS)`. Note that Gramine does *not* allow `arch_prctl(ARCH_GET_GS)` and
`arch_prctl(ARCH_SET_GS)` -- the GS register is reserved for Gramine internal usage.
-:warning: Note on thread's stack size
+Note on thread's stack size
Gramine sets the same stack size for each thread. In other words, Gramine does *not* support
dynamically-growing stacks (as Linux does). The stack size in Gramine can be configured via the
@@ -1528,21 +1527,21 @@ option](https://gramine.readthedocs.io/en/stable/manifest-syntax.html#stack-size
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `clone()`: must have combination `CLONE_VM | CLONE_THREAD`
-- :white_check_mark: `exit()`
-- :x: `get_thread_area()`: not used by applications
-- :x: `set_thread_area()`: not used by applications
-- :x: `prctl()`: not used by applications
-- :ballot_box_with_check: `arch_prctl()`: only x86-specific subset of flags
- - :white_check_mark: `ARCH_GET_FS`
- - :white_check_mark: `ARCH_SET_FS`
- - :x: `ARCH_GET_GS`
- - :x: `ARCH_SET_GS`
-- :x: `clone3()`: not used by applications
+- ☑ `clone()`: must have combination `CLONE_VM | CLONE_THREAD`
+- ☑ `exit()`
+- ☒ `get_thread_area()`: not used by applications
+- ☒ `set_thread_area()`: not used by applications
+- ☒ `prctl()`: not used by applications
+- ☐ `arch_prctl()`: only x86-specific subset of flags
+ - ☑ `ARCH_GET_FS`
+ - ☑ `ARCH_SET_FS`
+ - ☒ `ARCH_GET_GS`
+ - ☒ `ARCH_SET_GS`
+- ☒ `clone3()`: not used by applications
-
+
### Process and thread identifiers
@@ -1561,54 +1560,54 @@ Gramine implements a subset of pseudo-files under `/proc/[pid]`: more pseudo-fil
process (aka `/proc/self`) and its threads, less pseudo-files for remote processes (e.g. children),
and no pseudo-files for remote threads. See the list under "Related pseudo-files".
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `getpid()`
-- :white_check_mark: `getppid()`
-- :white_check_mark: `gettid()`
-- :white_check_mark: `set_tid_address()`
+- ☑ `getpid()`
+- ☑ `getppid()`
+- ☑ `gettid()`
+- ☑ `set_tid_address()`
-- :ballot_box_with_check: `getpgid()`: dummy, see above
-- :ballot_box_with_check: `setpgid()`: dummy, see above
-- :ballot_box_with_check: `getpgrp()`: dummy, see above
+- ☐ `getpgid()`: dummy, see above
+- ☐ `setpgid()`: dummy, see above
+- ☐ `getpgrp()`: dummy, see above
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :ballot_box_with_check: `/proc/[this-pid]/` (aka `/proc/self/`):
+- ☐ `/proc/[this-pid]/` (aka `/proc/self/`):
only most important files implemented
- - :white_check_mark: `/proc/[this-pid]/cmdline`
- - :white_check_mark: `/proc/[this-pid]/cwd`
- - :white_check_mark: `/proc/[this-pid]/exe`
- - :white_check_mark: `/proc/[this-pid]/fd`
- - :white_check_mark: `/proc/[this-pid]/maps`
- - :white_check_mark: `/proc/[this-pid]/root`
- - :ballot_box_with_check: `/proc/[this-pid]/stat`: partially implemented
- - :white_check_mark: `pid`, `comm`, `ppid`, `pgrp`, `num_threads`, `vsize`, `rss`
- - :ballot_box_with_check: `state`: always indicates "R" (running)
- - :ballot_box_with_check: `flags`: indicates only `PF_RANDOMIZE`
- - :x: rest fields: always zero
- - :ballot_box_with_check: `/proc/[this-pid]/statm`: partially implemented
- - :white_check_mark: `size`/`VmSize`, `resident`/`VmRSS`
- - :x: rest fields: always zero
- - :ballot_box_with_check: `/proc/[this-pid]/status`: partially implemented
- - :white_check_mark: `VmPeak`
- - :x: rest fields: not printed
- - :white_check_mark: `/proc/[this-pid]/task`
-
-- :ballot_box_with_check: `/proc/[remote-pid]/`: minimally implemented
- - :white_check_mark: `/proc/[remote-pid]/cwd`
- - :white_check_mark: `/proc/[remote-pid]/exe`
- - :white_check_mark: `/proc/[remote-pid]/root`
-
-- :ballot_box_with_check: `/proc/[local-tid]/`: same as `/proc/[this-pid]`
-
-- :x: `/proc/[remote-tid]/`: not used by applications
-
-- :white_check_mark: `/proc/sys/kernel/pid_max`
-
-
+ - ☑ `/proc/[this-pid]/cmdline`
+ - ☑ `/proc/[this-pid]/cwd`
+ - ☑ `/proc/[this-pid]/exe`
+ - ☑ `/proc/[this-pid]/fd`
+ - ☑ `/proc/[this-pid]/maps`
+ - ☑ `/proc/[this-pid]/root`
+ - ☐ `/proc/[this-pid]/stat`: partially implemented
+ - ☑ `pid`, `comm`, `ppid`, `pgrp`, `num_threads`, `vsize`, `rss`
+ - ☐ `state`: always indicates "R" (running)
+ - ☐ `flags`: indicates only `PF_RANDOMIZE`
+ - ☒ rest fields: always zero
+ - ☐ `/proc/[this-pid]/statm`: partially implemented
+ - ☑ `size`/`VmSize`, `resident`/`VmRSS`
+ - ☒ rest fields: always zero
+ - ☐ `/proc/[this-pid]/status`: partially implemented
+ - ☑ `VmPeak`
+ - ☒ rest fields: not printed
+ - ☑ `/proc/[this-pid]/task`
+
+- ☐ `/proc/[remote-pid]/`: minimally implemented
+ - ☑ `/proc/[remote-pid]/cwd`
+ - ☑ `/proc/[remote-pid]/exe`
+ - ☑ `/proc/[remote-pid]/root`
+
+- ☐ `/proc/[local-tid]/`: same as `/proc/[this-pid]`
+
+- ☒ `/proc/[remote-tid]/`: not used by applications
+
+- ☑ `/proc/sys/kernel/pid_max`
+
+
### Scheduling
@@ -1631,31 +1630,31 @@ To support CPU affinity masks and expose NUMA/CPU topology, Gramine implements
`/sys/devices/system/cpu/` and `/sys/devices/system/node/` pseudo-files. See the list in the
["System information and resource accounting" section](#system-information-and-resource-accounting).
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `sched_yield()`
-- :white_check_mark: `sched_getaffinity()`
-- :white_check_mark: `sched_setaffinity()`
+- ☑ `sched_yield()`
+- ☑ `sched_getaffinity()`
+- ☑ `sched_setaffinity()`
-- :ballot_box_with_check: `getcpu()`: dummy, returns a random allowed CPU
-- :ballot_box_with_check: `getpriority()`: dummy, returns default value
-- :ballot_box_with_check: `setpriority()`: dummy, does nothing
-- :ballot_box_with_check: `sched_getparam()`: dummy, returns default values
-- :ballot_box_with_check: `sched_setparam()`: dummy, does nothing
-- :ballot_box_with_check: `sched_getscheduler()`: dummy, returns default value
-- :ballot_box_with_check: `sched_setscheduler()`: dummy, does nothing
-- :ballot_box_with_check: `sched_get_priority_max()`: dummy, returns default
+- ☐ `getcpu()`: dummy, returns a random allowed CPU
+- ☐ `getpriority()`: dummy, returns default value
+- ☐ `setpriority()`: dummy, does nothing
+- ☐ `sched_getparam()`: dummy, returns default values
+- ☐ `sched_setparam()`: dummy, does nothing
+- ☐ `sched_getscheduler()`: dummy, returns default value
+- ☐ `sched_setscheduler()`: dummy, does nothing
+- ☐ `sched_get_priority_max()`: dummy, returns default
value
-- :ballot_box_with_check: `sched_get_priority_min()`: dummy, returns default
-- :ballot_box_with_check: `sched_rr_get_interval()`: dummy, returns default
+- ☐ `sched_get_priority_min()`: dummy, returns default
+- ☐ `sched_rr_get_interval()`: dummy, returns default
value
-- :x: `sched_getattr()`: not used by applications
-- :x: `sched_setattr()`: not used by applications
-- :x: `ioprio_get()`: not used by applications
-- :x: `ioprio_set()`: not used by applications
+- ☒ `sched_getattr()`: not used by applications
+- ☒ `sched_setattr()`: not used by applications
+- ☒ `ioprio_get()`: not used by applications
+- ☒ `ioprio_set()`: not used by applications
-
+
### Memory synchronization (futexes)
@@ -1675,15 +1674,15 @@ Gramine supports the following futex operations: `FUTEX_WAIT`, `FUTEX_WAIT_BITSE
Gramine implements getting/setting the list of robust futexes, via `get_robust_list()` and
`set_robust_list()` system calls.
-:blue_book: Related system calls
+Related system calls
-- :ballot_box_with_check: `futex()`: see notes above
-- :white_check_mark: `get_robust_list()`
-- :white_check_mark: `set_robust_list()`
+- ☐ `futex()`: see notes above
+- ☑ `get_robust_list()`
+- ☑ `set_robust_list()`
-- :x: `futex_waitv()`: not used by applications
+- ☒ `futex_waitv()`: not used by applications
-
+
### Memory management
@@ -1737,50 +1736,50 @@ Quick summary of other memory-management system calls:
As can be seen from above, many performance-improving system calls, flags and features are currently
*not* implemented by Gramine. Keep it in mind when you observe application performance degradation.
-:blue_book: Related system calls
-
-- :white_check_mark: `brk()`
-- :ballot_box_with_check: `mmap()`: see above for notes
-- :ballot_box_with_check: `mprotect()`: see above for notes
-- :white_check_mark: `munmap()`
-
-- :ballot_box_with_check: `msync()`: does not implement `MS_INVALIDATE`
-- :ballot_box_with_check: `madvise()`: see above for notes
-- :ballot_box_with_check: `mbind()`: dummy
-- :ballot_box_with_check: `mincore()`: dummy
-- :ballot_box_with_check: `mlock()`: dummy
-- :ballot_box_with_check: `munlock()`: dummy
-- :ballot_box_with_check: `mlockall()`: dummy
-- :ballot_box_with_check: `munlockall()`: dummy
-- :ballot_box_with_check: `mlock2()`: dummy
-
-- :x: `mremap()`: not used by applications
-- :x: `remap_file_pages()`: not used by applications
-- :x: `set_mempolicy()`: may be implemented in future
-- :x: `get_mempolicy()`: may be implemented in future
-- :x: `memfd_create()`: may be implemented in future
-- :x: `memfd_secret()`: not used by applications
-- :x: `membarrier()`: may be implemented in future
-- :x: `move_pages()`: not used by applications
-- :x: `migrate_pages()`: not used by applications
-- :x: `process_madvise()`: not used by applications
-- :x: `process_mrelease()`: not used by applications
-- :x: `set_mempolicy_home_node()`: not used by applications
-
-
+Related system calls
+
+- ☑ `brk()`
+- ☐ `mmap()`: see above for notes
+- ☐ `mprotect()`: see above for notes
+- ☑ `munmap()`
+
+- ☐ `msync()`: does not implement `MS_INVALIDATE`
+- ☐ `madvise()`: see above for notes
+- ☐ `mbind()`: dummy
+- ☐ `mincore()`: dummy
+- ☐ `mlock()`: dummy
+- ☐ `munlock()`: dummy
+- ☐ `mlockall()`: dummy
+- ☐ `munlockall()`: dummy
+- ☐ `mlock2()`: dummy
+
+- ☒ `mremap()`: not used by applications
+- ☒ `remap_file_pages()`: not used by applications
+- ☒ `set_mempolicy()`: may be implemented in future
+- ☒ `get_mempolicy()`: may be implemented in future
+- ☒ `memfd_create()`: may be implemented in future
+- ☒ `memfd_secret()`: not used by applications
+- ☒ `membarrier()`: may be implemented in future
+- ☒ `move_pages()`: not used by applications
+- ☒ `migrate_pages()`: not used by applications
+- ☒ `process_madvise()`: not used by applications
+- ☒ `process_mrelease()`: not used by applications
+- ☒ `set_mempolicy_home_node()`: not used by applications
+
+
### Overview of Inter-Process Communication (IPC)
Gramine implements most of the Linux IPC mechanisms. In particular:
-- :white_check_mark: Signals and process state changes
-- :white_check_mark: Pipes
-- :white_check_mark: FIFOs (named pipes)
-- :ballot_box_with_check: UNIX domain sockets
-- :ballot_box_with_check: File locking
-- :x: Message queues
-- :x: Semaphores
-- :x: Shared memory
+- ☑ Signals and process state changes
+- ☑ Pipes
+- ☑ FIFOs (named pipes)
+- ☐ UNIX domain sockets
+- ☐ File locking
+- ☒ Message queues
+- ☒ Semaphores
+- ☒ Shared memory
Gramine implements pipes, FIFOs and UNIX domain sockets (UDSes) via host-OS pipes. In case of SGX
backend, all pipe, FIFO and UDS communication is transparently encrypted.
@@ -1806,7 +1805,7 @@ to the complexity of message-passing implementation.
To learn more about Gramine support for each of the Linux IPC mechanisms, refer to corresponding
sections below.
-:speech_balloon: Additional materials
+Additional materials
- For Linux IPC overview, we recommend reading [Beej's Guide to Unix
IPC](https://beej.us/guide/bgipc/html/single/bgipc.html).
@@ -1816,7 +1815,7 @@ sections below.
new Gramine instance. Before establishing any pipe/IPC communication, two Gramine processes (e.g.,
parent and child) verify each other's trustworthiness using SGX local attestation.
-
+
### Signals and process state changes
@@ -1862,36 +1861,36 @@ Gramine has limited support for pseudo-files that describe the state of remote p
(files under `/proc/[remote-pid]/` and `/proc/[remote-tid]/`). For details, refer to "Related
pseudo-files" in the ["Process and thread identifiers" section](#process-and-thread-identifiers).
-:blue_book: Related system calls
-
-- :white_check_mark: `pause()`
-- :white_check_mark: `rt_sigaction()`
-- :white_check_mark: `rt_sigpending()`
-- :white_check_mark: `rt_sigprocmask()`
-- :white_check_mark: `rt_sigreturn()`
-- :white_check_mark: `rt_sigsuspend()`
-- :white_check_mark: `rt_sigtimedwait()`
-- :white_check_mark: `sigaltstack()`
-
-- :x: `rt_sigqueueinfo()`: not used by applications
-- :x: `rt_tgsigqueueinfo()`: not used by applications
-- :x: `signalfd()`: not used by applications
-- :x: `signalfd4()`: not used by applications
-- :x: `pidfd_open()`: not used by applications
-- :x: `pidfd_getfd()`: not used by applications
-- :x: `pidfd_send_signal()`: not used by applications
-- :x: `process_madvise()`: not used by applications
-- :x: `process_mrelease()`: not used by applications
-- :x: `userfaultfd()`: not used by applications
-
-- :ballot_box_with_check: `kill()`: process groups not supported
-- :ballot_box_with_check: `tkill()`: remote threads not supported
-- :white_check_mark: `tgkill()`
-
-- :ballot_box_with_check: `wait4()`: `WSTOPPED` and `WCONTINUED` not supported
-- :ballot_box_with_check: `waitid()`: `WSTOPPED` and `WCONTINUED` not supported
-
-
+Related system calls
+
+- ☑ `pause()`
+- ☑ `rt_sigaction()`
+- ☑ `rt_sigpending()`
+- ☑ `rt_sigprocmask()`
+- ☑ `rt_sigreturn()`
+- ☑ `rt_sigsuspend()`
+- ☑ `rt_sigtimedwait()`
+- ☑ `sigaltstack()`
+
+- ☒ `rt_sigqueueinfo()`: not used by applications
+- ☒ `rt_tgsigqueueinfo()`: not used by applications
+- ☒ `signalfd()`: not used by applications
+- ☒ `signalfd4()`: not used by applications
+- ☒ `pidfd_open()`: not used by applications
+- ☒ `pidfd_getfd()`: not used by applications
+- ☒ `pidfd_send_signal()`: not used by applications
+- ☒ `process_madvise()`: not used by applications
+- ☒ `process_mrelease()`: not used by applications
+- ☒ `userfaultfd()`: not used by applications
+
+- ☐ `kill()`: process groups not supported
+- ☐ `tkill()`: remote threads not supported
+- ☑ `tgkill()`
+
+- ☐ `wait4()`: `WSTOPPED` and `WCONTINUED` not supported
+- ☐ `waitid()`: `WSTOPPED` and `WCONTINUED` not supported
+
+
### User and group identifiers
@@ -1929,33 +1928,33 @@ Currently, there are only two usages of user/group IDs in Gramine:
Gramine does *not* currently implement user/group ID fields in the `/proc/[pid]/status` pseudo-file.
-:blue_book: Related system calls
-
-- :ballot_box_with_check: `getuid()`: dummy
-- :ballot_box_with_check: `getgid()`: dummy
-- :ballot_box_with_check: `setuid()`: dummy
-- :ballot_box_with_check: `setgid()`: dummy
-- :ballot_box_with_check: `geteuid()`: dummy
-- :ballot_box_with_check: `getegid()`: dummy
-- :ballot_box_with_check: `getgroups()`: dummy
-- :ballot_box_with_check: `setgroups()`: dummy
-
-- :x: `setreuid()`: not used by applications, may be implemented in future
-- :x: `setregid()`: not used by applications, may be implemented in future
-- :x: `getresuid()`: not used by applications, may be implemented in future
-- :x: `setresuid()`: not used by applications, may be implemented in future
-- :x: `getresgid()`: not used by applications, may be implemented in future
-- :x: `setresgid()`: not used by applications, may be implemented in future
-- :x: `setfsuid()`: not used by applications
-- :x: `setfsgid()`: not used by applications
+Related system calls
+
+- ☐ `getuid()`: dummy
+- ☐ `getgid()`: dummy
+- ☐ `setuid()`: dummy
+- ☐ `setgid()`: dummy
+- ☐ `geteuid()`: dummy
+- ☐ `getegid()`: dummy
+- ☐ `getgroups()`: dummy
+- ☐ `setgroups()`: dummy
+
+- ☒ `setreuid()`: not used by applications, may be implemented in future
+- ☒ `setregid()`: not used by applications, may be implemented in future
+- ☒ `getresuid()`: not used by applications, may be implemented in future
+- ☒ `setresuid()`: not used by applications, may be implemented in future
+- ☒ `getresgid()`: not used by applications, may be implemented in future
+- ☒ `setresgid()`: not used by applications, may be implemented in future
+- ☒ `setfsuid()`: not used by applications
+- ☒ `setfsgid()`: not used by applications
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :x: `/proc/[this-pid]/status`: fields `Uid`, `Gid`, `Groups` are not implemented
+- ☒ `/proc/[this-pid]/status`: fields `Uid`, `Gid`, `Groups` are not implemented
-
+
### File systems
@@ -2012,7 +2011,7 @@ General FS limitations in Gramine include:
- tmpfs mounts (in-memory file systems) are not shared by Gramine processes;
- File timestamps (access, modified, change timestamps) are not set/updated.
-:speech_balloon: Additional materials
+Additional materials
A mechanism for FS synchronization, as well as a general redesign of certain FS components, is a
task Gramine will tackle in the future. Below are some discussions and RFCs:
@@ -2022,7 +2021,7 @@ task Gramine will tackle in the future. Below are some discussions and RFCs:
- https://github.com/gramineproject/gramine/issues/584
- https://github.com/gramineproject/gramine/issues/578
-
+
#### File system operations
@@ -2102,101 +2101,101 @@ all have hard-coded values.
Gramine currently does *not* support changing file access/modification times, via `utime()`,
`utimes()`, `futimesat()`, `utimensat()` system calls.
-:blue_book: Related system calls
-
-- :ballot_box_with_check: `open()`: implemented, with limitations
-- :ballot_box_with_check: `openat()`: implemented, with limitations
-- :white_check_mark: `close()`
-- :white_check_mark: `creat()`
-- :white_check_mark: `mkdir()`
-- :white_check_mark: `mkdirat()`
-- :white_check_mark: `getdents()`
-- :white_check_mark: `getdents64()`
-- :white_check_mark: `unlink()`
-- :white_check_mark: `unlinkat()`
-- :white_check_mark: `rmdir()`
-- :ballot_box_with_check: `rename()`: cannot rename across mounts
-- :ballot_box_with_check: `renameat()`: cannot rename across mounts
-
-- :white_check_mark: `read()`
-- :white_check_mark: `pread64()`
-- :white_check_mark: `readv()`
-- :white_check_mark: `preadv()`
-- :white_check_mark: `write()`
-- :white_check_mark: `pwrite64()`
-- :white_check_mark: `writev()`
-- :white_check_mark: `pwritev()`
-
-- :ballot_box_with_check: `lseek()`: see note above
-- :ballot_box_with_check: `mmap()`: see notes above
-- :ballot_box_with_check: `msync()`: see notes above
-- :ballot_box_with_check: `select()`: dummy
-- :ballot_box_with_check: `pselect6()`: dummy
-- :ballot_box_with_check: `poll()`: dummy
-- :ballot_box_with_check: `ppoll()`: dummy
-- :white_check_mark: `fsync()`
-- :white_check_mark: `fdatasync()`
-- :ballot_box_with_check: `truncate()`: see note above
-- :ballot_box_with_check: `ftruncate()`: see note above
-- :ballot_box_with_check: `fallocate()`: dummy
-- :ballot_box_with_check: `fadvise64()`: dummy
-
-- :white_check_mark: `chmod()`
-- :white_check_mark: `fchmod()`
-- :white_check_mark: `fchmodat()`
-- :ballot_box_with_check: `chown()`: dummy
-- :ballot_box_with_check: `fchown()`: dummy
-- :ballot_box_with_check: `fchownat()`: dummy
-- :ballot_box_with_check: `access()`: dummy
-- :ballot_box_with_check: `faccessat()`: dummy
-- :white_check_mark: `umask()`
-
-- :ballot_box_with_check: `sendfile()`: unoptimized
-
-- :white_check_mark: `chdir()`
-- :white_check_mark: `fchdir()`
-- :white_check_mark: `getcwd()`
-
-- :ballot_box_with_check: `stat()`: partially dummy
-- :ballot_box_with_check: `fstat()`: partially dummy
-- :ballot_box_with_check: `lstat()`: partially dummy, always resolves to actual
+Related system calls
+
+- ☐ `open()`: implemented, with limitations
+- ☐ `openat()`: implemented, with limitations
+- ☑ `close()`
+- ☑ `creat()`
+- ☑ `mkdir()`
+- ☑ `mkdirat()`
+- ☑ `getdents()`
+- ☑ `getdents64()`
+- ☑ `unlink()`
+- ☑ `unlinkat()`
+- ☑ `rmdir()`
+- ☐ `rename()`: cannot rename across mounts
+- ☐ `renameat()`: cannot rename across mounts
+
+- ☑ `read()`
+- ☑ `pread64()`
+- ☑ `readv()`
+- ☑ `preadv()`
+- ☑ `write()`
+- ☑ `pwrite64()`
+- ☑ `writev()`
+- ☑ `pwritev()`
+
+- ☐ `lseek()`: see note above
+- ☐ `mmap()`: see notes above
+- ☐ `msync()`: see notes above
+- ☐ `select()`: dummy
+- ☐ `pselect6()`: dummy
+- ☐ `poll()`: dummy
+- ☐ `ppoll()`: dummy
+- ☑ `fsync()`
+- ☑ `fdatasync()`
+- ☐ `truncate()`: see note above
+- ☐ `ftruncate()`: see note above
+- ☐ `fallocate()`: dummy
+- ☐ `fadvise64()`: dummy
+
+- ☑ `chmod()`
+- ☑ `fchmod()`
+- ☑ `fchmodat()`
+- ☐ `chown()`: dummy
+- ☐ `fchown()`: dummy
+- ☐ `fchownat()`: dummy
+- ☐ `access()`: dummy
+- ☐ `faccessat()`: dummy
+- ☑ `umask()`
+
+- ☐ `sendfile()`: unoptimized
+
+- ☑ `chdir()`
+- ☑ `fchdir()`
+- ☑ `getcwd()`
+
+- ☐ `stat()`: partially dummy
+- ☐ `fstat()`: partially dummy
+- ☐ `lstat()`: partially dummy, always resolves to actual
file
-- :ballot_box_with_check: `newfstatat()`: partially dummy
-- :ballot_box_with_check: `statfs()`: partially dummy
-- :ballot_box_with_check: `fstatfs()`: partially dummy
-
-- :white_check_mark: `chroot()`
-
-- :x: `name_to_handle_at()`: not used by applications
-- :x: `open_by_handle_at()`: not used by applications
-- :x: `openat2()`: not used by applications
-- :x: `renameat2()`: not used by applications
-- :x: `preadv2()`: not used by applications
-- :x: `pwritev2()`: not used by applications
-- :x: `epoll_create()`: not used by applications
-- :x: `epoll_create1()`: not used by applications
-- :x: `epoll_wait()`: not used by applications
-- :x: `epoll_pwait()`: not used by applications
-- :x: `epoll_pwait2()`: not used by applications
-- :x: `epoll_ctl()`: not used by applications
-- :x: `sync()`: not used by applications
-- :x: `syncfs()`: not used by applications
-- :x: `sync_file_range()`: not used by applications
-- :x: `faccessat2()`: not used by applications
-- :x: `statx()`: not used by applications
-- :x: `sysfs()`: not used by applications
-- :x: `ustat()`: not used by applications
-- :x: `mount()`: not used by applications
-- :x: `move_mount()`: not used by applications
-- :x: `umount2()`: not used by applications
-- :x: `mount_setattr()`: not used by applications
-- :x: `pivot_root()`: not used by applications
-- :x: `utime()`: may be implemented in future
-- :x: `utimes()`: may be implemented in future
-- :x: `futimesat()`: may be implemented in future
-- :x: `utimensat()`: may be implemented in future
-
-
+- ☐ `newfstatat()`: partially dummy
+- ☐ `statfs()`: partially dummy
+- ☐ `fstatfs()`: partially dummy
+
+- ☑ `chroot()`
+
+- ☒ `name_to_handle_at()`: not used by applications
+- ☒ `open_by_handle_at()`: not used by applications
+- ☒ `openat2()`: not used by applications
+- ☒ `renameat2()`: not used by applications
+- ☒ `preadv2()`: not used by applications
+- ☒ `pwritev2()`: not used by applications
+- ☒ `epoll_create()`: not used by applications
+- ☒ `epoll_create1()`: not used by applications
+- ☒ `epoll_wait()`: not used by applications
+- ☒ `epoll_pwait()`: not used by applications
+- ☒ `epoll_pwait2()`: not used by applications
+- ☒ `epoll_ctl()`: not used by applications
+- ☒ `sync()`: not used by applications
+- ☒ `syncfs()`: not used by applications
+- ☒ `sync_file_range()`: not used by applications
+- ☒ `faccessat2()`: not used by applications
+- ☒ `statx()`: not used by applications
+- ☒ `sysfs()`: not used by applications
+- ☒ `ustat()`: not used by applications
+- ☒ `mount()`: not used by applications
+- ☒ `move_mount()`: not used by applications
+- ☒ `umount2()`: not used by applications
+- ☒ `mount_setattr()`: not used by applications
+- ☒ `pivot_root()`: not used by applications
+- ☒ `utime()`: may be implemented in future
+- ☒ `utimes()`: may be implemented in future
+- ☒ `futimesat()`: may be implemented in future
+- ☒ `utimensat()`: may be implemented in future
+
+
#### File locking
@@ -2220,32 +2219,32 @@ The current implementation has the following caveats:
Gramine does *not* currently implement the `flock()` system call.
-:blue_book: Related system calls
+Related system calls
-- :ballot_box_with_check: `fcntl()`
- - :ballot_box_with_check: `F_SETLK`: see notes above
- - :ballot_box_with_check: `F_SETLKW`: see notes above
- - :ballot_box_with_check: `F_GETLK`: see notes above
+- ☐ `fcntl()`
+ - ☐ `F_SETLK`: see notes above
+ - ☐ `F_SETLKW`: see notes above
+ - ☐ `F_GETLK`: see notes above
-- :x: `flock()`: may be implemented in future
+- ☒ `flock()`: may be implemented in future
-
+
#### Monitoring filesystem events (inotify, fanotify)
Gramine does *not* currently implement inotify and fanotify APIs. Gramine could implement them in
the future, if need arises.
-:blue_book: Related system calls
+Related system calls
-- :x: `inotify_init()`
-- :x: `inotify_init1()`
-- :x: `inotify_add_watch()`
-- :x: `inotify_rm_watch()`
-- :x: `fanotify_init()`
-- :x: `fanotify_mark()`
+- ☒ `inotify_init()`
+- ☒ `inotify_init1()`
+- ☒ `inotify_add_watch()`
+- ☒ `inotify_rm_watch()`
+- ☒ `fanotify_init()`
+- ☒ `fanotify_mark()`
-
+
#### Hard links and soft links (symbolic links)
@@ -2261,36 +2260,36 @@ The above means that Gramine does not implement `link()` and `symlink()` system
Gramine may implement hard and soft links in the future.
-:blue_book: Related system calls
+Related system calls
-- :x: `link()`
-- :x: `symlink()`
-- :ballot_box_with_check: `readlink()`: see note above
-- :x: `linkat()`
-- :x: `symlinkat()`
-- :ballot_box_with_check: `readlinkat()`: see note above
-- :x: `lchown()`
+- ☒ `link()`
+- ☒ `symlink()`
+- ☐ `readlink()`: see note above
+- ☒ `linkat()`
+- ☒ `symlinkat()`
+- ☐ `readlinkat()`: see note above
+- ☒ `lchown()`
-:page_facing_up: Related pseudo-files
+Related pseudo-files
The following pseudo-files are symlinks. See also "Related pseudo-files" in the ["Process and thread
identifiers" section](#process-and-thread-identifiers).
-- :white_check_mark: `/dev/`
- - :white_check_mark: `/dev/stdin`
- - :white_check_mark: `/dev/stdout`
- - :white_check_mark: `/dev/stderr`
+- ☑ `/dev/`
+ - ☑ `/dev/stdin`
+ - ☑ `/dev/stdout`
+ - ☑ `/dev/stderr`
-- :white_check_mark: `/proc/self/`
+- ☑ `/proc/self/`
-- :white_check_mark: `/proc/[pid]/`
- - :white_check_mark: `/proc/[pid]/cwd`
- - :white_check_mark: `/proc/[pid]/exe`
- - :white_check_mark: `/proc/[pid]/root`
+- ☑ `/proc/[pid]/`
+ - ☑ `/proc/[pid]/cwd`
+ - ☑ `/proc/[pid]/exe`
+ - ☑ `/proc/[pid]/root`
-
+
### Pipes and FIFOs (named pipes)
@@ -2324,45 +2323,45 @@ Gramine supports getting and setting pipe/FIFO status flags via `fcntl(F_GETFL)`
`fcntl(F_SETFL)`. The only currently supported flag is `O_NONBLOCK`; `O_ASYNC` is not supported.
Gramine also supports setting blocking/non-blocking mode via `ioctl(FIONBIO)`.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `pipe()`
-- :ballot_box_with_check: `pipe2()`: `O_DIRECT` flag is ignored
-- :ballot_box_with_check: `mknod()`: `S_ISFIFO` type is supported
-- :ballot_box_with_check: `mknodat()`: `S_ISFIFO` type is supported
-- :white_check_mark: `close()`
+- ☑ `pipe()`
+- ☐ `pipe2()`: `O_DIRECT` flag is ignored
+- ☐ `mknod()`: `S_ISFIFO` type is supported
+- ☐ `mknodat()`: `S_ISFIFO` type is supported
+- ☑ `close()`
-- :white_check_mark: `fstat()`
+- ☑ `fstat()`
-- :white_check_mark: `read()`
-- :white_check_mark: `readv()`
-- :white_check_mark: `write()`
-- :white_check_mark: `writev()`
+- ☑ `read()`
+- ☑ `readv()`
+- ☑ `write()`
+- ☑ `writev()`
-- :white_check_mark: `select()`
-- :white_check_mark: `pselect6()`
-- :white_check_mark: `poll()`
-- :white_check_mark: `ppoll()`
-- :white_check_mark: `epoll_create()`
-- :white_check_mark: `epoll_create1()`
-- :white_check_mark: `epoll_wait()`
-- :white_check_mark: `epoll_pwait()`
-- :white_check_mark: `epoll_ctl()`
-- :x: `epoll_pwait2()`: not used by applications
+- ☑ `select()`
+- ☑ `pselect6()`
+- ☑ `poll()`
+- ☑ `ppoll()`
+- ☑ `epoll_create()`
+- ☑ `epoll_create1()`
+- ☑ `epoll_wait()`
+- ☑ `epoll_pwait()`
+- ☑ `epoll_ctl()`
+- ☒ `epoll_pwait2()`: not used by applications
-- :ballot_box_with_check: `sendfile()`: unoptimized
+- ☐ `sendfile()`: unoptimized
-- :ballot_box_with_check: `fcntl()`
- - :ballot_box_with_check: `F_GETFL`: only `O_NONBLOCK`
- - :ballot_box_with_check: `F_SETFL`: only `O_NONBLOCK`
- - :x: `F_GETPIPE_SZ`: not used by applications
- - :x: `F_SETPIPE_SZ`: not used by applications
+- ☐ `fcntl()`
+ - ☐ `F_GETFL`: only `O_NONBLOCK`
+ - ☐ `F_SETFL`: only `O_NONBLOCK`
+ - ☒ `F_GETPIPE_SZ`: not used by applications
+ - ☒ `F_SETPIPE_SZ`: not used by applications
-- :ballot_box_with_check: `ioctl()`
- - :white_check_mark: `FIONREAD`
- - :white_check_mark: `FIONBIO`
+- ☐ `ioctl()`
+ - ☑ `FIONREAD`
+ - ☑ `FIONBIO`
-
+
### Networking (sockets)
@@ -2416,7 +2415,7 @@ TCP and UDP sockets support the following socket options:
TCP sockets additionally support the following socket options: `TCP_CORK`, `TCP_KEEPIDLE`,
`TCP_KEEPINTVL`, `TCP_KEEPCNT`, `TCP_NODELAY` and `TCP_USER_TIMEOUT`.
-:speech_balloon: Note on domain names configuration
+Note on domain names configuration
- To use name-resolving Berkeley socket APIs like `gethostbyname()`, `gethostbyaddr()`,
`getaddrinfo`, one must enable the [`sys.enable_extra_runtime_domain_names_conf` manifest
@@ -2424,68 +2423,68 @@ TCP sockets additionally support the following socket options: `TCP_CORK`, `TCP_
-:blue_book: Related system calls
-
-- :ballot_box_with_check: `socket()`: see notes above
-- :white_check_mark: `bind()`
-- :white_check_mark: `listen()`
-- :white_check_mark: `accept()`
-- :white_check_mark: `accept4()`
-- :white_check_mark: `connect()`
-- :white_check_mark: `close()`
-- :white_check_mark: `shutdown()`
-
-- :white_check_mark: `getsockname()`
-- :white_check_mark: `getpeername()`
-- :white_check_mark: `getsockopt()`
-- :white_check_mark: `setsockopt()`
-
-- :white_check_mark: `fstat()`
-
-- :white_check_mark: `read()`
-- :white_check_mark: `readv()`
-- :white_check_mark: `write()`
-- :white_check_mark: `writev()`
-
-- :ballot_box_with_check: `recv()`: see supported flags above
-- :ballot_box_with_check: `recvfrom()`: see supported flags above
-- :ballot_box_with_check: `recvmsg()`: see supported flags above
-- :ballot_box_with_check: `recvmmsg()`: see supported flags above
-- :ballot_box_with_check: `send()`: see supported flags above
-- :ballot_box_with_check: `sendto()`: see supported flags above
-- :ballot_box_with_check: `sendmsg()`: see supported flags above
-- :ballot_box_with_check: `sendmmsg()`: see supported flags above
-
-- :white_check_mark: `select()`
-- :white_check_mark: `pselect6()`
-- :white_check_mark: `poll()`
-- :white_check_mark: `ppoll()`
-- :white_check_mark: `epoll_create()`
-- :white_check_mark: `epoll_create1()`
-- :white_check_mark: `epoll_wait()`
-- :white_check_mark: `epoll_pwait()`
-- :white_check_mark: `epoll_ctl()`
-- :x: `epoll_pwait2()`: not used by applications
-
-- :ballot_box_with_check: `sendfile()`: unoptimized
-
-- :ballot_box_with_check: `fcntl()`
- - :ballot_box_with_check: `F_GETFL`: only `O_NONBLOCK`
- - :ballot_box_with_check: `F_SETFL`: only `O_NONBLOCK`
-
-- :ballot_box_with_check: `ioctl()`
- - :white_check_mark: `FIONREAD`
- - :white_check_mark: `FIONBIO`
+Related system calls
+
+- ☐ `socket()`: see notes above
+- ☑ `bind()`
+- ☑ `listen()`
+- ☑ `accept()`
+- ☑ `accept4()`
+- ☑ `connect()`
+- ☑ `close()`
+- ☑ `shutdown()`
+
+- ☑ `getsockname()`
+- ☑ `getpeername()`
+- ☑ `getsockopt()`
+- ☑ `setsockopt()`
+
+- ☑ `fstat()`
+
+- ☑ `read()`
+- ☑ `readv()`
+- ☑ `write()`
+- ☑ `writev()`
+
+- ☐ `recv()`: see supported flags above
+- ☐ `recvfrom()`: see supported flags above
+- ☐ `recvmsg()`: see supported flags above
+- ☐ `recvmmsg()`: see supported flags above
+- ☐ `send()`: see supported flags above
+- ☐ `sendto()`: see supported flags above
+- ☐ `sendmsg()`: see supported flags above
+- ☐ `sendmmsg()`: see supported flags above
+
+- ☑ `select()`
+- ☑ `pselect6()`
+- ☑ `poll()`
+- ☑ `ppoll()`
+- ☑ `epoll_create()`
+- ☑ `epoll_create1()`
+- ☑ `epoll_wait()`
+- ☑ `epoll_pwait()`
+- ☑ `epoll_ctl()`
+- ☒ `epoll_pwait2()`: not used by applications
+
+- ☐ `sendfile()`: unoptimized
+
+- ☐ `fcntl()`
+ - ☐ `F_GETFL`: only `O_NONBLOCK`
+ - ☐ `F_SETFL`: only `O_NONBLOCK`
+
+- ☐ `ioctl()`
+ - ☑ `FIONREAD`
+ - ☑ `FIONBIO`
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :x: `/proc/sys/net/core/`
-- :x: `/proc/sys/net/ipv4/`
-- :x: `/proc/sys/net/ipv6/`
+- ☒ `/proc/sys/net/core/`
+- ☒ `/proc/sys/net/ipv4/`
+- ☒ `/proc/sys/net/ipv6/`
-
+
#### UNIX domain sockets
@@ -2523,28 +2522,28 @@ UDSes support the following socket options:
- `SO_ACCEPTCONN`, `SO_DOMAIN`, `SO_TYPE`, `SO_PROTOCOL`, `SO_ERROR` (all read-only),
- `SO_REUSEADDR` (ignored, same as in Linux).
-:speech_balloon: Note on named UDSes
+Note on named UDSes
- There is an effort to make named UDSes visible on the Gramine filesystem, see
https://github.com/gramineproject/gramine/pull/1021.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `socketpair()`
+- ☑ `socketpair()`
- For other system calls, see ["TCP/IP and UDP/IP sockets" subsection](#tcpip-and-udpip-sockets)
above.
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :x: `/proc/sys/net/unix/`
+- ☒ `/proc/sys/net/unix/`
- For other pseudo-files, see ["TCP/IP and UDP/IP sockets" subsection](#tcpip-and-udpip-sockets)
above.
-
+
### I/O multiplexing
@@ -2572,27 +2571,27 @@ Epoll family of system calls has the following limitations:
- Adding an epoll to another epoll instance is not currently supported.
- `EPOLLRDHUP` is not reported and `EPOLLHUP` is always reported together with `EPOLLERR`.
-:construction: Note on EPOLLERR/EPOLLHUP/EPOLLRDHUP
+Note on EPOLLERR/EPOLLHUP/EPOLLRDHUP
There is a pending [GitHub pull request](https://github.com/gramineproject/gramine/pull/1073) to
distinguish between the three error conditions.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `select()`
-- :white_check_mark: `pselect6()`
-- :white_check_mark: `poll()`
-- :white_check_mark: `ppoll()`
-- :ballot_box_with_check: `epoll_create()`: see notes above
-- :ballot_box_with_check: `epoll_create1()`: see notes above
-- :ballot_box_with_check: `epoll_wait()`: see notes above
-- :ballot_box_with_check: `epoll_pwait()`: see notes above
-- :ballot_box_with_check: `epoll_ctl()`: see notes above
-- :x: `epoll_pwait2()`: not used by applications
+- ☑ `select()`
+- ☑ `pselect6()`
+- ☑ `poll()`
+- ☑ `ppoll()`
+- ☐ `epoll_create()`: see notes above
+- ☐ `epoll_create1()`: see notes above
+- ☐ `epoll_wait()`: see notes above
+- ☐ `epoll_pwait()`: see notes above
+- ☐ `epoll_ctl()`: see notes above
+- ☒ `epoll_pwait2()`: not used by applications
-
+
### Asynchronous I/O
@@ -2606,19 +2605,19 @@ future, if need arises.
Note that AIO provided in userspace by glibc (`aio_read()`, `aio_write()`, etc.) does not depend on
Gramine and is supported.
-:blue_book: Related system calls
+Related system calls
-- :x: `io_setup()`
-- :x: `io_destroy()`
-- :x: `io_getevents()`
-- :x: `io_submit()`
-- :x: `io_cancel()`
+- ☒ `io_setup()`
+- ☒ `io_destroy()`
+- ☒ `io_getevents()`
+- ☒ `io_submit()`
+- ☒ `io_cancel()`
-- :x: `io_uring_setup()`
-- :x: `io_uring_enter()`
-- :x: `io_uring_register()`
+- ☒ `io_uring_setup()`
+- ☒ `io_uring_enter()`
+- ☒ `io_uring_register()`
-
+
### Event notifications (eventfd)
@@ -2633,27 +2632,27 @@ Gramine supports polling on eventfd via `poll()`, `ppoll()`, `select()`, `epoll_
Gramine may implement a secure version of `eventfd()` for communication between Gramine processes in
the future. Such secure version will *not* be able to receive events from the host OS.
-:blue_book: Related system calls
+Related system calls
-- :ballot_box_with_check: `eventfd()`: insecure implementation
-- :ballot_box_with_check: `eventfd2()`: insecure implementation
-- :white_check_mark: `close()`
+- ☐ `eventfd()`: insecure implementation
+- ☐ `eventfd2()`: insecure implementation
+- ☑ `close()`
-- :white_check_mark: `read()`
-- :white_check_mark: `write()`
+- ☑ `read()`
+- ☑ `write()`
-- :white_check_mark: `select()`
-- :white_check_mark: `pselect6()`
-- :white_check_mark: `poll()`
-- :white_check_mark: `ppoll()`
-- :white_check_mark: `epoll_create()`
-- :white_check_mark: `epoll_create1()`
-- :white_check_mark: `epoll_wait()`
-- :white_check_mark: `epoll_pwait()`
-- :white_check_mark: `epoll_ctl()`
-- :x: `epoll_pwait2()`: not used by applications
+- ☑ `select()`
+- ☑ `pselect6()`
+- ☑ `poll()`
+- ☑ `ppoll()`
+- ☑ `epoll_create()`
+- ☑ `epoll_create1()`
+- ☑ `epoll_wait()`
+- ☑ `epoll_pwait()`
+- ☑ `epoll_ctl()`
+- ☒ `epoll_pwait2()`: not used by applications
-
+
### Semaphores
@@ -2667,20 +2666,20 @@ POSIX shared memory functionality of Linux (i.e., via `/dev/shm` pseudo-filesyst
Gramine does *not* currently implement either of these APIs. Gramine could implement them in
the future, if need arises.
-:blue_book: Related system calls
+Related system calls
-- :x: `semget()`
-- :x: `semop()`
-- :x: `semtimedop()`
-- :x: `semctl()`
+- ☒ `semget()`
+- ☒ `semop()`
+- ☒ `semtimedop()`
+- ☒ `semctl()`
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :x: `/dev/shm`
+- ☒ `/dev/shm`
-
+
### Message queues
@@ -2691,21 +2690,21 @@ There are two message-queue APIs in Linux kernel:
Gramine does *not* currently implement either of these APIs. Gramine could implement them in
the future, if need arises.
-:blue_book: Related system calls
+Related system calls
-- :x: `msgget()`
-- :x: `msgctl()`
-- :x: `msgrcv()`
-- :x: `msgsnd()`
+- ☒ `msgget()`
+- ☒ `msgctl()`
+- ☒ `msgrcv()`
+- ☒ `msgsnd()`
-- :x: `mq_open()`
-- :x: `mq_getsetattr()`
-- :x: `mq_notify()`
-- :x: `mq_timedreceive()`
-- :x: `mq_timedsend()`
-- :x: `mq_unlink()`
+- ☒ `mq_open()`
+- ☒ `mq_getsetattr()`
+- ☒ `mq_notify()`
+- ☒ `mq_timedreceive()`
+- ☒ `mq_timedsend()`
+- ☒ `mq_unlink()`
-
+
### Shared memory
@@ -2719,7 +2718,7 @@ In case of SGX backend, implementation of shared memory would be *insecure*, as
design would be allocated in untrusted non-enclave memory, and there is no way for Gramine to
intercept memory accesses to shared memory regions (to provide some security guarantees).
-:construction: Adding limited POSIX shared memory support
+Adding limited POSIX shared memory support
There is an effort to add limited support for POSIX shared memory, targeted for special use cases
like communication with hardware accelerators (e.g. GPUs):
@@ -2729,27 +2728,27 @@ like communication with hardware accelerators (e.g. GPUs):
-:blue_book: Related system calls
+Related system calls
-- :x: `shmget()`
-- :x: `shmat()`
-- :x: `shmctl()`
-- :x: `shmdt()`
+- ☒ `shmget()`
+- ☒ `shmat()`
+- ☒ `shmctl()`
+- ☒ `shmdt()`
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :x: `/dev/shm`: may be implemented in future (in a limited insecure way, see note above)
+- ☒ `/dev/shm`: may be implemented in future (in a limited insecure way, see note above)
-
+
### IOCTLs
Gramine currently implements only a minimal set of IOCTL request codes. See the list under
"Related system calls".
-:construction: Adding support for arbitrary IOCTLs
+Adding support for arbitrary IOCTLs
There is an effort to add support for specifying arbitrary IOCTLs (with arbitrary request codes and
corresponding IOCTL data structures), targeted for special use cases like communication with
@@ -2760,17 +2759,17 @@ hardware accelerators (e.g. GPUs):
-:blue_book: Related system calls
+Related system calls
-- :ballot_box_with_check: `ioctl()`
- - :ballot_box_with_check: `TIOCGPGRP`: dummy
- - :white_check_mark: `FIONBIO`
- - :white_check_mark: `FIONCLEX`
- - :white_check_mark: `FIOCLEX`
- - :white_check_mark: `FIOASYNC`
- - :white_check_mark: `FIONREAD`
+- ☐ `ioctl()`
+ - ☐ `TIOCGPGRP`: dummy
+ - ☑ `FIONBIO`
+ - ☑ `FIONCLEX`
+ - ☑ `FIOCLEX`
+ - ☑ `FIOASYNC`
+ - ☑ `FIONREAD`
-
+
### Date and time
@@ -2785,29 +2784,29 @@ Gramine does *not* support setting or adjusting date/time: `settimeofday()`, `cl
Gramine does *not* currently support getting process times (like user time, system time): `times()`.
-:warning: Note on trustworthiness of date/time on SGX
+Note on trustworthiness of date/time on SGX
In case of SGX backend, date/time cannot be trusted because it is queried from the possibly
malicious host OS. There is currently no solution to this limitation.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `gettimeofday()`
-- :white_check_mark: `time()`
-- :ballot_box_with_check: `clock_gettime()`: all clocks emulated via
+- ☑ `gettimeofday()`
+- ☑ `time()`
+- ☐ `clock_gettime()`: all clocks emulated via
`CLOCK_REALTIME`
-- :ballot_box_with_check: `clock_getres()`: all clocks emulated via
+- ☐ `clock_getres()`: all clocks emulated via
`CLOCK_REALTIME`
-- :x: `settimeofday()`: not used by applications
-- :x: `clock_settime()`: not used by applications
-- :x: `adjtimex()`: not used by applications
-- :x: `clock_adjtime()`: not used by applications
-- :x: `times()`: may be implemented in future
+- ☒ `settimeofday()`: not used by applications
+- ☒ `clock_settime()`: not used by applications
+- ☒ `adjtimex()`: not used by applications
+- ☒ `clock_adjtime()`: not used by applications
+- ☒ `times()`: may be implemented in future
-
+
### Sleeps, timers and alarms
@@ -2824,26 +2823,26 @@ Gramine does *not* currently implement the POSIX per-process timer: `timer_creat
also does not currently implement timers that notify via file descriptors. Gramine could implement
these timers in the future, if need arises.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `nanosleep()`
-- :ballot_box_with_check: `clock_nanosleep()`: all clocks emulated via
+- ☑ `nanosleep()`
+- ☐ `clock_nanosleep()`: all clocks emulated via
`CLOCK_REALTIME`
-- :ballot_box_with_check: `getitimer()`: only `ITIMER_REAL`
-- :ballot_box_with_check: `setitimer()`: only `ITIMER_REAL`
-- :white_check_mark: `alarm()`
+- ☐ `getitimer()`: only `ITIMER_REAL`
+- ☐ `setitimer()`: only `ITIMER_REAL`
+- ☑ `alarm()`
-- :x: `timer_create()`: may be implemented in future
-- :x: `timer_settime()`: may be implemented in future
-- :x: `timer_gettime()`: may be implemented in future
-- :x: `timer_getoverrun()`: may be implemented in future
-- :x: `timer_delete()`: may be implemented in future
+- ☒ `timer_create()`: may be implemented in future
+- ☒ `timer_settime()`: may be implemented in future
+- ☒ `timer_gettime()`: may be implemented in future
+- ☒ `timer_getoverrun()`: may be implemented in future
+- ☒ `timer_delete()`: may be implemented in future
-- :x: `timerfd_create()`: may be implemented in future
-- :x: `timerfd_settime()`: may be implemented in future
-- :x: `timerfd_gettime()`: may be implemented in future
+- ☒ `timerfd_create()`: may be implemented in future
+- ☒ `timerfd_settime()`: may be implemented in future
+- ☒ `timerfd_gettime()`: may be implemented in future
-
+
### Randomness
@@ -2854,18 +2853,18 @@ Gramine implements obtaining random bytes via two Linux APIs:
In case of SGX backend, Gramine always uses only one source of random bytes: the RDRAND x86
instruction. This is a secure source of randomness.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `getrandom()`
+- ☑ `getrandom()`
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :white_check_mark: `/dev/random`
-- :white_check_mark: `/dev/urandom`
+- ☑ `/dev/random`
+- ☑ `/dev/urandom`
-
+
### System information and resource accounting
@@ -2910,77 +2909,77 @@ information. In addition, Gramine supports CPU- and NUMA-node-specific pseudo-fi
pseudo-files". For additional pseudo-files containing process-specific information, see the
["Process and thread identifiers" section](#process-and-thread-identifiers).
-:blue_book: Related system calls
+Related system calls
-- :x: `getrusage()`
-- :ballot_box_with_check: `sysinfo()`: only `totalram`, `totalhigh`, `freeram`
+- ☒ `getrusage()`
+- ☐ `sysinfo()`: only `totalram`, `totalhigh`, `freeram`
and `freehigh`
-- :ballot_box_with_check: `uname()`: only `sysname`, `nodename`, `release`,
+- ☐ `uname()`: only `sysname`, `nodename`, `release`,
`version`, `machine` and `domainname`
-- :ballot_box_with_check: `sethostname()`: dummy
-- :ballot_box_with_check: `setdomainname()`: dummy
-- :ballot_box_with_check: `getrlimit()`: see notes above
-- :ballot_box_with_check: `setrlimit()`: see notes above
-- :ballot_box_with_check: `prlimit64()`: see notes above
+- ☐ `sethostname()`: dummy
+- ☐ `setdomainname()`: dummy
+- ☐ `getrlimit()`: see notes above
+- ☐ `setrlimit()`: see notes above
+- ☐ `prlimit64()`: see notes above
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :ballot_box_with_check: `/proc/cpuinfo`: partially implemented
- - :white_check_mark: `processor`, `vendor_id`, `cpu family`, `model`, `model name`, `stepping`,
+- ☐ `/proc/cpuinfo`: partially implemented
+ - ☑ `processor`, `vendor_id`, `cpu family`, `model`, `model name`, `stepping`,
`physical id`, `core id`, `cpu cores`, `bogomips`
- - :white_check_mark: `flags`: all known CPU flags
-
-- :ballot_box_with_check: `/proc/meminfo`: partially implemented
- - :white_check_mark: `MemTotal`, `MemFree`, `MemAvailable`, `Committed_AS`, `VmallocTotal`
- - :x: rest fields: always zero
-
-- :ballot_box_with_check: `/proc/stat`: dummy
- - :ballot_box_with_check: `cpu` line: all fields are zeros
- - :ballot_box_with_check: `cpuX` lines: all fields are zeros
- - :ballot_box_with_check: `ctxt` line: always zero
- - :ballot_box_with_check: `btime` line: always zero
- - :ballot_box_with_check: `processes` line: always one
- - :ballot_box_with_check: `procs_running` line: always one
- - :ballot_box_with_check: `procs_blocked` line: always zero
- - :x: `intr` line
- - :x: `softirq` line
-
-- :ballot_box_with_check: `/sys/devices/system/cpu/`: only most important files
+ - ☑ `flags`: all known CPU flags
+
+- ☐ `/proc/meminfo`: partially implemented
+ - ☑ `MemTotal`, `MemFree`, `MemAvailable`, `Committed_AS`, `VmallocTotal`
+ - ☒ rest fields: always zero
+
+- ☐ `/proc/stat`: dummy
+ - ☐ `cpu` line: all fields are zeros
+ - ☐ `cpuX` lines: all fields are zeros
+ - ☐ `ctxt` line: always zero
+ - ☐ `btime` line: always zero
+ - ☐ `processes` line: always one
+ - ☐ `procs_running` line: always one
+ - ☐ `procs_blocked` line: always zero
+ - ☒ `intr` line
+ - ☒ `softirq` line
+
+- ☐ `/sys/devices/system/cpu/`: only most important files
implemented
- - :ballot_box_with_check: `/sys/devices/system/cpu/cpu[x]/`
- - :ballot_box_with_check: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/coherency_line_size`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/level`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/number_of_sets`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/physical_line_partition`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/shared_cpu_map`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/size`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/cache/index[x]/type`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/online`
- - :ballot_box_with_check: `/sys/devices/system/cpu/cpu[x]/topology/`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/core_id`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/core_siblings`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/physical_package_id`
- - :white_check_mark: `/sys/devices/system/cpu/cpu[x]/topology/thread_siblings`
- - :white_check_mark: `/sys/devices/system/cpu/online`
- - :white_check_mark: `/sys/devices/system/cpu/possible`
-
-- :ballot_box_with_check: `/sys/devices/system/node/`: only most important files
+ - ☐ `/sys/devices/system/cpu/cpu[x]/`
+ - ☐ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/coherency_line_size`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/level`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/number_of_sets`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/physical_line_partition`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/shared_cpu_map`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/size`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/cache/index[x]/type`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/online`
+ - ☐ `/sys/devices/system/cpu/cpu[x]/topology/`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/core_id`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/core_siblings`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/physical_package_id`
+ - ☑ `/sys/devices/system/cpu/cpu[x]/topology/thread_siblings`
+ - ☑ `/sys/devices/system/cpu/online`
+ - ☑ `/sys/devices/system/cpu/possible`
+
+- ☐ `/sys/devices/system/node/`: only most important files
implemented
- - :ballot_box_with_check: `/sys/devices/system/node/node[x]/`
- - :white_check_mark: `/sys/devices/system/node/node[x]/cpumap`
- - :white_check_mark: `/sys/devices/system/node/node[x]/distance`
- - :white_check_mark: `/sys/devices/system/node/node[x]/hugepages/`
- - :ballot_box_with_check:
+ - ☐ `/sys/devices/system/node/node[x]/`
+ - ☑ `/sys/devices/system/node/node[x]/cpumap`
+ - ☑ `/sys/devices/system/node/node[x]/distance`
+ - ☑ `/sys/devices/system/node/node[x]/hugepages/`
+ - ☐
`/sys/devices/system/node/node[x]/hugepages/hugepages-[y]/nr_hugepages`: always zero
- - :ballot_box_with_check: `/sys/devices/system/node/node[x]/meminfo`:
+ - ☐ `/sys/devices/system/node/node[x]/meminfo`:
partially implemented
- - :white_check_mark: `MemTotal`, `MemFree`, `MemUsed`
- - :x: rest fields: always zero
+ - ☑ `MemTotal`, `MemFree`, `MemUsed`
+ - ☒ rest fields: always zero
-
+
### Misc
@@ -3000,37 +2999,37 @@ Gramine implements several arch-specific (x86-64) operations:
Gramine implements the `/dev/null` and `/dev/zero` pseudo-files.
-:blue_book: Related system calls
+Related system calls
-- :white_check_mark: `gettimeofday()`: implemented in vDSO
-- :ballot_box_with_check: `clock_gettime()`: implemented in vDSO
-- :white_check_mark: `time()`: implemented in vDSO
-- :ballot_box_with_check: `getcpu()`: implemented in vDSO
+- ☑ `gettimeofday()`: implemented in vDSO
+- ☐ `clock_gettime()`: implemented in vDSO
+- ☑ `time()`: implemented in vDSO
+- ☐ `getcpu()`: implemented in vDSO
-- :white_check_mark: `dup()`
-- :white_check_mark: `dup2()`
-- :white_check_mark: `dup3()`
+- ☑ `dup()`
+- ☑ `dup2()`
+- ☑ `dup3()`
-- :ballot_box_with_check: `fcntl()`
- - :white_check_mark: `F_DUPFD`
- - :white_check_mark: `F_DUPFD_CLOEXEC`
- - :white_check_mark: `F_GETFD`
- - :white_check_mark: `F_SETFD`
+- ☐ `fcntl()`
+ - ☑ `F_DUPFD`
+ - ☑ `F_DUPFD_CLOEXEC`
+ - ☑ `F_GETFD`
+ - ☑ `F_SETFD`
-- :ballot_box_with_check: `arch_prctl()`
- - :white_check_mark: `ARCH_GET_XCOMP_SUPP`
- - :white_check_mark: `ARCH_GET_XCOMP_PERM`
- - :white_check_mark: `ARCH_REQ_XCOMP_PERM`
+- ☐ `arch_prctl()`
+ - ☑ `ARCH_GET_XCOMP_SUPP`
+ - ☑ `ARCH_GET_XCOMP_PERM`
+ - ☑ `ARCH_REQ_XCOMP_PERM`
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :white_check_mark: `/dev/`
- - :white_check_mark: `/dev/null`
- - :white_check_mark: `/dev/zero`
+- ☑ `/dev/`
+ - ☑ `/dev/null`
+ - ☑ `/dev/zero`
-
+
### Advanced (unimplemented) features
@@ -3062,88 +3061,88 @@ codebase of Gramine minimal.
`putpmsg()`, `afs_syscall()`, `tuxcall()`, `security()`, `lookup_dcookie()`, `restart_syscall()`,
`vserver()`, `io_pgetevents()`, `rseq()`, `open_tree()`, `close_range()`
-:blue_book: Related system calls
-
-- :x: `_sysctl()`
-- :x: `acct()`
-- :x: `add_key()`
-- :x: `afs_syscall()`
-- :x: `bpf()`
-- :x: `capget()`
-- :x: `capset()`
-- :x: `close_range()`
-- :x: `copy_file_range()`
-- :x: `create_module()`
-- :x: `delete_module()`
-- :x: `fgetxattr()`
-- :x: `finit_module()`
-- :x: `flistxattr()`
-- :x: `fremovexattr()`
-- :x: `fsconfig()`
-- :x: `fsetxattr()`
-- :x: `fsmount()`
-- :x: `fsopen()`
-- :x: `fspick()`
-- :x: `get_kernel_syms()`
-- :x: `getpmsg()`
-- :x: `getsid()`
-- :x: `getxattr()`
-- :x: `init_module()`
-- :x: `io_pgetevents()`
-- :x: `ioperm()`
-- :x: `iopl()`
-- :x: `kexec_file_load()`
-- :x: `kexec_load()`
-- :x: `keyctl()`
-- :x: `landlock_add_rule()`
-- :x: `landlock_create_ruleset()`
-- :x: `landlock_restrict_self()`
-- :x: `lgetxattr()`
-- :x: `listxattr()`
-- :x: `llistxattr()`
-- :x: `lookup_dcookie()`
-- :x: `lremovexattr()`
-- :x: `lsetxattr()`
-- :x: `modify_ldt()`
-- :x: `nfsservctl()`
-- :x: `nfsservctl()`
-- :x: `open_tree()`
-- :x: `perf_event_open()`
-- :x: `personality()`
-- :x: `pkey_alloc()`
-- :x: `pkey_free()`
-- :x: `pkey_mprotect()`
-- :x: `process_vm_readv()`
-- :x: `process_vm_writev()`
-- :x: `ptrace()`
-- :x: `putpmsg()`
-- :x: `query_module()`
-- :x: `quotactl()`
-- :x: `quotactl_fd()`
-- :x: `readahead()`
-- :x: `reboot()`
-- :x: `removexattr()`
-- :x: `request_key()`
-- :x: `restart_syscall()`
-- :x: `rseq()`
-- :x: `seccomp()`
-- :x: `security()`
-- :x: `setns()`
-- :x: `setsid()`
-- :x: `setxattr()`
-- :x: `splice()`
-- :x: `swapoff()`
-- :x: `swapon()`
-- :x: `syslog()`
-- :x: `tee()`
-- :x: `tuxcall()`
-- :x: `unshare()`
-- :x: `uselib()`
-- :x: `vhangup()`
-- :x: `vmsplice()`
-- :x: `vserver()`
-
-
+Related system calls
+
+- ☒ `_sysctl()`
+- ☒ `acct()`
+- ☒ `add_key()`
+- ☒ `afs_syscall()`
+- ☒ `bpf()`
+- ☒ `capget()`
+- ☒ `capset()`
+- ☒ `close_range()`
+- ☒ `copy_file_range()`
+- ☒ `create_module()`
+- ☒ `delete_module()`
+- ☒ `fgetxattr()`
+- ☒ `finit_module()`
+- ☒ `flistxattr()`
+- ☒ `fremovexattr()`
+- ☒ `fsconfig()`
+- ☒ `fsetxattr()`
+- ☒ `fsmount()`
+- ☒ `fsopen()`
+- ☒ `fspick()`
+- ☒ `get_kernel_syms()`
+- ☒ `getpmsg()`
+- ☒ `getsid()`
+- ☒ `getxattr()`
+- ☒ `init_module()`
+- ☒ `io_pgetevents()`
+- ☒ `ioperm()`
+- ☒ `iopl()`
+- ☒ `kexec_file_load()`
+- ☒ `kexec_load()`
+- ☒ `keyctl()`
+- ☒ `landlock_add_rule()`
+- ☒ `landlock_create_ruleset()`
+- ☒ `landlock_restrict_self()`
+- ☒ `lgetxattr()`
+- ☒ `listxattr()`
+- ☒ `llistxattr()`
+- ☒ `lookup_dcookie()`
+- ☒ `lremovexattr()`
+- ☒ `lsetxattr()`
+- ☒ `modify_ldt()`
+- ☒ `nfsservctl()`
+- ☒ `nfsservctl()`
+- ☒ `open_tree()`
+- ☒ `perf_event_open()`
+- ☒ `personality()`
+- ☒ `pkey_alloc()`
+- ☒ `pkey_free()`
+- ☒ `pkey_mprotect()`
+- ☒ `process_vm_readv()`
+- ☒ `process_vm_writev()`
+- ☒ `ptrace()`
+- ☒ `putpmsg()`
+- ☒ `query_module()`
+- ☒ `quotactl()`
+- ☒ `quotactl_fd()`
+- ☒ `readahead()`
+- ☒ `reboot()`
+- ☒ `removexattr()`
+- ☒ `request_key()`
+- ☒ `restart_syscall()`
+- ☒ `rseq()`
+- ☒ `seccomp()`
+- ☒ `security()`
+- ☒ `setns()`
+- ☒ `setsid()`
+- ☒ `setxattr()`
+- ☒ `splice()`
+- ☒ `swapoff()`
+- ☒ `swapon()`
+- ☒ `syslog()`
+- ☒ `tee()`
+- ☒ `tuxcall()`
+- ☒ `unshare()`
+- ☒ `uselib()`
+- ☒ `vhangup()`
+- ☒ `vmsplice()`
+- ☒ `vserver()`
+
+
## Gramine-specific features
@@ -3158,25 +3157,25 @@ exposes pseudo-files to set encryption keys (in particular, for encrypted files)
For detailed information, refer to the ["Attestation and Secret Provisioning" documentation of
Gramine](https://gramine.readthedocs.io/en/stable/attestation.html#low-level-dev-attestation-interface).
-:page_facing_up: Related pseudo-files
+Related pseudo-files
-- :white_check_mark: `/dev/attestation/`
- - :white_check_mark: `/dev/attestation/attestation_type`
- - :white_check_mark: `/dev/attestation/user_report_data`
- - :white_check_mark: `/dev/attestation/target_info`
- - :white_check_mark: `/dev/attestation/my_target_info`
- - :white_check_mark: `/dev/attestation/report`
- - :white_check_mark: `/dev/attestation/quote`
+- ☑ `/dev/attestation/`
+ - ☑ `/dev/attestation/attestation_type`
+ - ☑ `/dev/attestation/user_report_data`
+ - ☑ `/dev/attestation/target_info`
+ - ☑ `/dev/attestation/my_target_info`
+ - ☑ `/dev/attestation/report`
+ - ☑ `/dev/attestation/quote`
- - :white_check_mark: `/dev/attestation/keys`
- - :white_check_mark: `/dev/attestation/keys/`
- - :ballot_box_with_check: `/dev/attestation/protected_files_key`: deprecated
+ - ☑ `/dev/attestation/keys`
+ - ☑ `/dev/attestation/keys/`
+ - ☐ `/dev/attestation/protected_files_key`: deprecated
-
+
## Notes on System V ABI
-> :warning: Below description assumes x86-64 architecture.
+> ⚠ Below description assumes x86-64 architecture.
Gramine implements the system-call entry point (analogous to the `SYSCALL` x86 instruction).
Instead of performing a context switch from userland (ring-3) to kernelspace (ring-0), Gramine
diff --git a/Documentation/index.rst b/Documentation/index.rst
index 15ff519256..24a0f05a5f 100644
--- a/Documentation/index.rst
+++ b/Documentation/index.rst
@@ -92,6 +92,7 @@ Table of Contents
:caption: Developing Gramine
:maxdepth: 1
+ devel/features
devel/building
devel/onboarding
devel/contributing
diff --git a/Documentation/requirements.txt b/Documentation/requirements.txt
index d33450f0be..626f296579 100644
--- a/Documentation/requirements.txt
+++ b/Documentation/requirements.txt
@@ -1,5 +1,6 @@
sphinx==1.8.0
breathe<4.13.0
+recommonmark
sphinx_rtd_theme<1
tomli>=1.1.0