[readthedocs] Update content for Occlum

This commit is contained in:
Qi Zheng 2023-07-07 15:32:45 +08:00 committed by volcano
parent 4966e473a2
commit 7ad72a4955
11 changed files with 119 additions and 175 deletions

@ -14,13 +14,12 @@ There are total three MACs which are all generated in building stage and verifie
* MAC of the configuration file. Both above MACs are filled into the configuration file. Thus the MAC of the configuration file reflects the differences of the two file systems to some extent. * MAC of the configuration file. Both above MACs are filled into the configuration file. Thus the MAC of the configuration file reflects the differences of the two file systems to some extent.
* **mrenclave**, it indicates the measurement of the Occlum LibOS.
## Boot flow ## Boot flow
1. To user, the entry point is the command `occlum run`. The steps behind the command are PAL APIs `occlum_pal_init` and `occlum_pal_create_process`. It launches the Occlum LibOS kernel in the Enclave. The kernel then loads the configuration file `.Occlum_sys.json.protected`, doing integrity check with the MAC saved in `KSS ISV FamilyID`. If pass, it uses the settings in the configuration file to do memory/process initialization. Then, it tries mount the init filesystem. It does integrity check again with MAC in the `.Occlum_sys.json.protected`. If pass, the first user space process `init` got launched. 1. To user, the entry point is the command `occlum run`. The steps behind the command are PAL APIs `occlum_pal_init` and `occlum_pal_create_process`. It launches the Occlum LibOS kernel in the Enclave. The kernel then loads the configuration file `.Occlum_sys.json.protected`, doing integrity check with the MAC saved in the LibOS section **builtin_config** (marked as `conf_mac` in the picture). If pass, it uses the settings in the configuration file to do memory/process initialization. Then, it tries mount the init filesystem. It does integrity check again with init FS MAC in the `.Occlum_sys.json.protected`. If pass, the first user space process `init` got launched.
2. There is a default minimal `init` provided. In this `init`, it calls the Occlum added syscall `SYS_MOUNT_FS` to mount the application file system. The syscall implementation in the Occlum kernel does integrity check again with MAC in the `.Occlum_sys.json.protected` to make sure expected application got launched. 2. There is a default minimal `init` provided. In this `init`, it calls the Occlum added syscall `SYS_MOUNT_FS` to mount the application file system. The syscall implementation in the Occlum kernel does integrity check again with root FS MAC in the `.Occlum_sys.json.protected` to make sure expected application got launched.
3. At this stage, the real user application got launched. 3. At this stage, the real user application got launched.

@ -51,7 +51,7 @@ The Occlum Dockerfile can be found at [here](https://github.com/occlum/occlum/tr
By default, the `occlum build` command builds and signs enclaves in debug mode. These SGX debug-mode enclaves are intended for development and testing purposes only. For production usage, the enclaves must be signed by a key acquired from Intel (a restriction that will be lifted in the future when Flexible Launch Control is ready) and run with SGX debug support disabled. By default, the `occlum build` command builds and signs enclaves in debug mode. These SGX debug-mode enclaves are intended for development and testing purposes only. For production usage, the enclaves must be signed by a key acquired from Intel (a restriction that will be lifted in the future when Flexible Launch Control is ready) and run with SGX debug support disabled.
Occlum has built-in support for both building and running enclaves in release mode. Occlum has built-in support for both building and running enclaves in release mode.
To do that, modify `Occlum.yaml` [metadata]-[debuggable] field to `false`. And then run the commands below: To do that, modify `Occlum.json` [metadata]-[debuggable] field to `false`. And then run the commands below:
``` ```
$ occlum build --sign-key <path_to/your_key.pem> $ occlum build --sign-key <path_to/your_key.pem>
$ occlum run <prog_path> <prog_args> $ occlum run <prog_path> <prog_args>

@ -137,7 +137,7 @@ The HostFS is used for convenient data exchange between the LibOS and the host O
## RamFS and other pseudo filesystems ## RamFS and other pseudo filesystems
The RamFS and other pseudo filesystems like ProcFS use the memory as the storage. So the data may lose if one terminates the enclave. The RamFS and other pseudo filesystems like ProcFS use the memory as the storage. So the data may lose if one terminates the enclave.
Please remember to enlarge the `kernel_space_heap_size` of Occlum.yaml if your app depends on RamFS. Please remember to enlarge the `kernel_space_heap_size` of Occlum.json if your app depends on RamFS.
## Q & A ## Q & A

@ -30,7 +30,7 @@ To mount an Occlum's secure FS image successfully, three conditions must be sati
With the three conditions satisfied, the mount command is able to start a Linux FUSE FS server. Any I/O operations on the FUSE FS mounted at the specified path will be redirected by Linux kernel as I/O requests to the FUSE server. The FUSE server is backed by a special enclave, which can encrypt or decrypt the content of the secure FS image on demand. With the three conditions satisfied, the mount command is able to start a Linux FUSE FS server. Any I/O operations on the FUSE FS mounted at the specified path will be redirected by Linux kernel as I/O requests to the FUSE server. The FUSE server is backed by a special enclave, which can encrypt or decrypt the content of the secure FS image on demand.
Please note that if the `autokey_policy` field of the configurations of FS is set in Occlum.yaml, the mount command will not work. This is because the MRENCLAVE is used as an input to generate the encryption key, and the mount tool cannot mimic it. Please note that if the `autokey_policy` field of the configurations of FS is set in Occlum.json, the mount command will not work. This is because the MRENCLAVE is used as an input to generate the encryption key, and the mount tool cannot mimic it.
The mount command **will not return** until the FUSE server is terminated in one of the two ways. The first one is to press ctrl+C. The second one is to use `umount` command. Both ways can terminate the server gracefully. The mount command **will not return** until the FUSE server is terminated in one of the two ways. The first one is to press ctrl+C. The second one is to use `umount` command. Both ways can terminate the server gracefully.
@ -49,7 +49,7 @@ After mounting the secure FS successfully, you can access and manipulate the FS
## Mount and Unmount Filesystems at Runtime ## Mount and Unmount Filesystems at Runtime
### Background ### Background
Users can specify the mount configuration in the `Occlum.yaml` file, then the file systems are mounted during the libOS startup phase. While this design provides a safe and simple way to access files, it is not as convenient as traditional Host OS. Apps are not allowed to mount and unmount file systems at runtime. Users can specify the mount configuration in the `Occlum.json` file, then the file systems are mounted during the libOS startup phase. While this design provides a safe and simple way to access files, it is not as convenient as traditional Host OS. Apps are not allowed to mount and unmount file systems at runtime.
### How to mount filesystems at runtime? ### How to mount filesystems at runtime?
Apps running inside Occlum can mount some specific file systems via the [mount()](https://man7.org/linux/man-pages/man2/mount.2.html) system call. This makes it flexible to mount and access files at runtime. Apps running inside Occlum can mount some specific file systems via the [mount()](https://man7.org/linux/man-pages/man2/mount.2.html) system call. This makes it flexible to mount and access files at runtime.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 93 KiB

@ -7,11 +7,6 @@ As a LibOS, it enables legacy applications to run on SGX with little or even no
.. image:: images/arch_overview.png .. image:: images/arch_overview.png
:alt: Occlum Arch Overview :alt: Occlum Arch Overview
.. note::
This project is under active development.
There is no guarantee that the content here are all up to date.
***************** *****************
Table of Contents Table of Contents
***************** *****************

@ -21,7 +21,7 @@ Initialize a directory as the Occlum instance.
```bash ```bash
occlum build [--sign-key <key_path>] [--sign-tool <tool_path>] [--image-key <key_path>] [-f/--force] occlum build [--sign-key <key_path>] [--sign-tool <tool_path>] [--image-key <key_path>] [-f/--force]
``` ```
Build and sign an Occlum SGX enclave (.so) and generate its associated secure FS image according to the user-provided image directory and Occlum.yaml config file. Build and sign an Occlum SGX enclave (.so) and generate its associated secure FS image according to the user-provided image directory and Occlum.json config file.
The whole building process is incremental: the building artifacts are built only The whole building process is incremental: the building artifacts are built only
when needed. when needed.
To force rebuilding all artifacts, give the [-f/--force] flag. To force rebuilding all artifacts, give the [-f/--force] flag.

@ -1,159 +1,112 @@
# Occlum Configuration # Occlum Configuration
Occlum can be configured easily via a configuration file named `Occlum.yaml`, which is generated by the `occlum init` command in the Occlum instance directory. The user can modify `Occlum.yaml` to configure Occlum. The template of `Occlum.yaml` is shown below. Occlum can be configured easily via a configuration file named `Occlum.json`, which is generated by the `occlum init` command in the Occlum instance directory. The user can modify `Occlum.json` to configure Occlum. The template of `Occlum.json` is shown below.
```yaml ```json
# All the settings below can only take effect after `occlum build`. {
resource_limits: // Resource limits
# The number of OS threads created for this instance. "resource_limits": {
num_of_cpus: 128 // The total size of enclave memory available to LibOS processes
# The stack size of LibOS kernel. "user_space_size": "256MB",
kernel_space_stack_size: 16MB // The heap size of LibOS kernel
# The heap size of LibOS kernel. "kernel_space_heap_size": "32MB",
# With EDMM support, choose "init" size based on the expected initialization time. And increase the "max" field if memory insufficiency occurs. // The stack size of LibOS kernel
# Without EDMM support, increase the "init" field if memory insufficiency occurs. And the "max" field is ignored. "kernel_space_stack_size": "1MB",
kernel_space_heap_size: // The max number of LibOS threads/processes
# Reserved and committed during the initialization stage. The more, the longer it takes to initialize. "max_num_of_threads": 32
init: 32MB },
# Only committed when necessary. Only valid with EDMM support. // Process
max: 512MB "process": {
# The total size of enclave memory available to the user applications running in LibOS. // The stack size of the "main" thread
# With EDMM support, choose "init" size based on the expected initialization time. And increase the "max" field if memory insufficiency occurs. "default_stack_size": "4MB",
# Without EDMM support, increase the "init" field if memory insufficiency occurs. And the "max" field is ignored. // The max size of memory allocated by brk syscall
user_space_size: "default_heap_size": "16MB",
# Reserved and committed during the initialization stage. The more, the longer it takes to initialize. // The max size of memory by mmap syscall (OBSOLETE. Users don't need to modify this field. Keep it only for compatibility)
init: 256MB "default_mmap_size": "32MB"
# Only committed when necessary. Only valid with EDMM support. },
max: 64GB // Entry points
process: //
# Default stack size for each process. If not sure, don't modify it. // Entry points specify all valid path prefixes for <path> in `occlum run
default_stack_size: 4MB // <path> <args>`. This prevents outside attackers from executing arbitrary
# Default heap size for each process. If not sure, don't modify it. // commands inside an Occlum-powered enclave.
default_heap_size: 32MB "entry_points": [
"/bin"
# Entry points ],
# Specify all valid absolute <path> in `occlum run <path> <args>`. // Environment variables
# This prevents outside attackers from executing arbitrary commands inside an //
# Occlum-powered enclave. // This gives a list of environment variables for the "root"
entry_points: // process started by `occlum exec` command.
- /bin "env": {
// The default env vars given to each "root" LibOS process. As these env vars
# Environment variables // are specified in this config file, they are considered trusted.
# "default": [
# This gives a list of environment variables for the "root" process started "OCCLUM=yes"
# by `occlum run` or `occlum exec` command. ],
env: // The untrusted env vars that are captured by Occlum from the host environment
# The default env vars given to each "root" LibOS process. As these env vars // and passed to the "root" LibOS processes. These untrusted env vars can
# are specified in this config file, they are considered trusted. // override the trusted, default envs specified above.
default: "untrusted": [
- OCCLUM=yes "EXAMPLE"
# The untrusted env vars that are captured by Occlum from the host environment ]
# and passed to the "root" LibOS processes. These untrusted env vars can },
# override the trusted, default envs specified above. // Enclave metadata
# For example, `OCCLUM=no occlum run xxx` can pass the env OCCLUM=no to the process "metadata": {
# running in LibOS with below settings. // Enclave signature structure's ISVPRODID field
# env: "product_id": 0,
# default: // Enclave signature structure's ISVSVN field
# - OCCLUM=yes "version_number": 0,
# untrusted: // Whether the enclave is debuggable through special SGX instructions.
# - OCCLUM // For production enclave, it is IMPORTANT to set this value to false.
untrusted: "debuggable": true,
- EXAMPLE // Whether to turn on PKU feature in Occlum
// Occlum uses PKU for isolation between LibOS and userspace program,
# Enclave metadata // It is useful for developers to detect potential bugs.
# If not sure, just keep them no change //
metadata: // "pkru" = 0: PKU feature must be disabled
# Enclave signature structure's ISVPRODID field // "pkru" = 1: PKU feature must be enabled
product_id: 0 // "pkru" = 2: PKU feature is enabled if the platform supports it
# Enclave signature structure's ISVSVN field "pkru": 0
version_number: 0 },
# Whether the enclave is debuggable through special SGX instructions. // Mount points and their file systems
# If set to false, no log could be output. //
# For production enclave, it is IMPORTANT to set this value to false. // The default configuration is shown below.
debuggable: true "mount": [
# SGX Key Separation and Sharing feature support. {
# Please always keep it as true. "target": "/",
enable_kss: true "type": "unionfs",
# Enclave signature structure's ISVEXTPRODID field. "options": {
# It is separated as two 16 bytes strings. "layers": [
ext_prod_id: {
high: '0x0' "target": "/",
low: '0x0' "type": "sefs",
# Whether to turn on PKU feature in Occlum "source": "./build/mount/__ROOT",
# Occlum uses PKU for isolation between LibOS and userspace program, "options": {
# It is useful for developers to detect potential bugs. "MAC": ""
# }
# "pkru" = 0: PKU feature must be disabled },
# "pkru" = 1: PKU feature must be enabled {
# "pkru" = 2: PKU feature is enabled if the platform supports it "target": "/",
pkru: 0 "type": "sefs",
"source": "./run/mount/__ROOT"
# Mount points and their file systems }
mount: ]
# RootFS mount point and file systems. }
# Generally, just don't change it. },
- target: / {
type: unionfs "target": "/host",
options: "type": "hostfs",
layers: "source": "."
# The read-only layer which is generated in `occlum build` },
- target: / {
type: sefs "target": "/proc",
source: ./build/mount/__ROOT "type": "procfs"
options: },
MAC: '' {
# The read-write layer whose content is produced when running the LibOS "target": "/dev",
- target: / "type": "devfs"
type: sefs }
source: ./run/mount/__ROOT ]
# options: }
# The SEFS just uses MRSIGNER to drived key by default, so the data can
# be shared between same enclave signer on the same machine.
# If you want more secure scheme, you can set the autokey_policy field
# to 1 to enforcing the key is derived by MRSIGNER|MRENCLAVE|ISVFAMILYID.
# So the data can only be accessed by the enclave itself.
# autokey_policy: 1
#
# HostFS mount
# It provides a channel to exchange files between Host FS and LibOS FS.
# Just note, with this mount, the files written to the target in the LibOS
# is recognizable to users in the Host thus may introduce security issue.
#
# For example, below section mount the occlum_instance directory in the Host FS
# to the path /host in the LibOS FS.
# It is disabled in default. Uncomment it if you are very sure about it.
# - target: /host
# type: hostfs
# source: .
#
# Async FS mount
# - target: /sfs
# type: async_sfs
# source: ./run/async_sfs_image
# options:
# total_size: 4GB
# Untrusted Unix domain socket
# Besides the common Unix domain socket support that both ends are created in the same
# Occlum instance, the Untrusted Unix domain socket can support cross-world connection by
# mapping a libos socket address with the host socket address. In this way, a Unix domain
# socket created in Occlum can communicate with a Unix domain socket in the host OS or in
# another Occlum instance.
# Uncomment and customize below if you are very sure about it.
#
# untrusted_unix_socks:
# The libos path and the host path correspond to the same host sock file.
# The host side should use the host path and libos side should use the libos path.
#
# Specify socket file in absolute path
# - host: /tmp/occlum/test.sock
# libos: /root/test.sock
# Or any files in the path
# - host: /tmp/root/
# libos: /root/
# Or the host path can be a relative path and is relative to the current Occlum instance dir.
# - host: ../test.sock
# libos: /tmp/test.sock
``` ```
## Runtime Resource Configuration for Occlum process ## Runtime Resource Configuration for Occlum process
@ -164,7 +117,7 @@ Occlum has enabled per process resource configuration via [prlimit](https://man7
#! /usr/bin/bash #! /usr/bin/bash
ulimit -a ulimit -a
# ulimit defined below will override configuration in Occlum.yaml # ulimit defined below will override configuration in Occlum.json
ulimit -Ss 10240 # stack size 10M ulimit -Ss 10240 # stack size 10M
ulimit -Sd 40960 # heap size 40M ulimit -Sd 40960 # heap size 40M
ulimit -Sv 102400 # virtual memory size 100M (including heap, stack, mmap size) ulimit -Sv 102400 # virtual memory size 100M (including heap, stack, mmap size)

@ -6,9 +6,9 @@
First, please make sure the baremetal or VM machine support SGX. Otherwise, users can only try SW simulation mode. First, please make sure the baremetal or VM machine support SGX. Otherwise, users can only try SW simulation mode.
From Occlum v1.0, only SGX2 or SGX1 with [FLC](https://www.intel.com/content/www/us/en/developer/articles/technical/an-update-on-3rd-party-attestation.html)(Flexible Launch Control) feature are supported. To have best user experience, SGX2 or SGX1 with [FLC](https://www.intel.com/content/www/us/en/developer/articles/technical/an-update-on-3rd-party-attestation.html)(Flexible Launch Control) feature are required.
Users can use command `cpuid` to detect if the HW satisfy Occlum v1.0 requirements. Users can use command `cpuid` to detect if the HW satisfy Occlum requirements.
* SGX2, ```cpuid | grep SGX2``` * SGX2, ```cpuid | grep SGX2```
* FLC, ```cpuid | grep SGX_LC``` * FLC, ```cpuid | grep SGX_LC```
@ -17,7 +17,7 @@ Users can use command `cpuid` to detect if the HW satisfy Occlum v1.0 requiremen
#### Kernel Version #### Kernel Version
From Occlum v1.0, the `io_uring` is used to enhance the IO performance. The `io_uring` is first introduced in Linux kernel 5.1 and still fast growing. To make Occlum v1.0 works well with `io_uring` and also the SGX in-tree driver, Linux kernel 5.10+ is expected. To use SGX in-tree driver, Linux kernel 5.10+ is expected.
For example, in the Ubuntu 20.04 OS (Occlum default development OS), users could update the kernel with below command to get all Occlum required kernel features. For example, in the Ubuntu 20.04 OS (Occlum default development OS), users could update the kernel with below command to get all Occlum required kernel features.
``` ```

@ -55,13 +55,10 @@ ISVEXTPRODID, 16 bytes
CONFIG ID, 64 bytes CONFIG ID, 64 bytes
CONFIG SVN, 16 bits CONFIG SVN, 16 bits
``` ```
Occlum can support both above by either modifying the fields in `Occlum.yaml` (for `Signning stage`) or using Occlum run arguments `"--config-id"` or `"--config-svn"` (for `Running stage`). Occlum can support both above by either modifying the fields in `Occlum.json` (for `Signning stage`) or using Occlum run arguments `"--config-id"` or `"--config-svn"` (for `Running stage`).
* Note: `ISVFAMILYID` is reserved for saving the MAC of the configuration file.
Details please refer to the [RFC](https://github.com/occlum/occlum/issues/589). Details please refer to the [RFC](https://github.com/occlum/occlum/issues/589).
## References ## References
- [DCAP Quick Install Guide](https://software.intel.com/content/www/us/en/develop/articles/intel-software-guard-extensions-data-center-attestation-primitives-quick-install-guide.html) - [DCAP Quick Install Guide](https://software.intel.com/content/www/us/en/develop/articles/intel-software-guard-extensions-data-center-attestation-primitives-quick-install-guide.html)

@ -3,7 +3,7 @@
For every application to be running in Occlum (TEE env), all the running required files, libraries and binaries have to be put into Occlum file system. Here is the tree view of one Occlum instance. For every application to be running in Occlum (TEE env), all the running required files, libraries and binaries have to be put into Occlum file system. Here is the tree view of one Occlum instance.
``` ```
./occlum_instance/ ./occlum_instance/
|-- Occlum.yaml |-- Occlum.json
|-- build |-- build
|-- image // Occlum root file system |-- image // Occlum root file system
| |-- bin | |-- bin