Add "occlum mount" command to mount the secure FS

This commit is contained in:
LI Qing 2020-09-01 18:56:25 +08:00 committed by Tate, Hongliang Tian
parent 292fc28340
commit ec9ffed1b0
7 changed files with 118 additions and 8 deletions

@ -41,9 +41,14 @@ submodule: githooks
@rm -rf build build_sim @rm -rf build build_sim
@$(MAKE) SGX_MODE=SIM --no-print-directory -C tools @$(MAKE) SGX_MODE=SIM --no-print-directory -C tools
@$(MAKE) --no-print-directory -C deps/sefs/sefs-cli clean @$(MAKE) --no-print-directory -C deps/sefs/sefs-cli clean
@$(MAKE) SGX_MODE=SIM --no-print-directory -C deps/sefs/sefs-cli @$(MAKE) --no-print-directory -C deps/sefs/sefs-cli no_sign SGX_MODE=HW
@cp deps/sefs/sefs-cli/bin/sefs-cli build/bin @cp deps/sefs/sefs-cli/bin/sefs-cli build/bin
@cp deps/sefs/sefs-cli/lib/libsefs-cli.so build/lib
@$(MAKE) --no-print-directory -C deps/sefs/sefs-cli SGX_MODE=SIM
@cp deps/sefs/sefs-cli/bin/sefs-cli_sim build/bin
@cp deps/sefs/sefs-cli/lib/libsefs-cli_sim.so build/lib
@cp deps/sefs/sefs-cli/lib/libsefs-cli.signed.so build/lib @cp deps/sefs/sefs-cli/lib/libsefs-cli.signed.so build/lib
@cp deps/sefs/sefs-cli/enclave/Enclave.config.xml build/sefs-cli.Enclave.xml
src: src:
@$(MAKE) --no-print-directory -C src @$(MAKE) --no-print-directory -C src
@ -74,6 +79,8 @@ install: $(OCCLUM_PREFIX)/sgxsdk-tools/lib64/libsgx_uae_service_sim.so
@mkdir -p $(OCCLUM_PREFIX)/etc/template/ @mkdir -p $(OCCLUM_PREFIX)/etc/template/
@cp etc/template/* $(OCCLUM_PREFIX)/etc/template @cp etc/template/* $(OCCLUM_PREFIX)/etc/template
@chmod 444 $(OCCLUM_PREFIX)/etc/template/* @chmod 444 $(OCCLUM_PREFIX)/etc/template/*
@cp build/sefs-cli.Enclave.xml $(OCCLUM_PREFIX)/build
@chmod 644 $(OCCLUM_PREFIX)/build/sefs-cli.Enclave.xml
@echo "Installation is done." @echo "Installation is done."

@ -245,6 +245,8 @@ The two aforementioned requirements are not only satisfied by the Occlum toolcha
To debug an app running upon Occlum, one can harness Occlum's builtin support for GDB via `occlum gdb` command. More info can be found [here](demos/gdb_support/). To debug an app running upon Occlum, one can harness Occlum's builtin support for GDB via `occlum gdb` command. More info can be found [here](demos/gdb_support/).
Meanwhile, one can use `occlum mount` command to access and manipulate the secure filesystem for debug purpose. More info can be found [here](docs/occlum_mount.md).
If the cause of a problem does not seem to be the app but Occlum itself, then one can take a glimpse into the inner workings of Occlum by checking out its log. Occlum's log level can be adjusted through `OCCLUM_LOG_LEVEL` environment variable. It has six levels: `off`, `error`, `warn`, `debug`, `info`, and `trace`. The default value is `off`, i.e., showing no log messages at all. The most verbose level is `trace`. If the cause of a problem does not seem to be the app but Occlum itself, then one can take a glimpse into the inner workings of Occlum by checking out its log. Occlum's log level can be adjusted through `OCCLUM_LOG_LEVEL` environment variable. It has six levels: `off`, `error`, `warn`, `debug`, `info`, and `trace`. The default value is `off`, i.e., showing no log messages at all. The most verbose level is `trace`.
## How to Build and Run Release-Mode Enclaves? ## How to Build and Run Release-Mode Enclaves?

2
deps/sefs vendored

@ -1 +1 @@
Subproject commit 57ea3214eb0f39ffeb290d6db56e4953b9c23e71 Subproject commit 12b4fbc6aed7bea1beb60ad121fd28cc96bd7fa4

28
docs/occlum_mount.md Normal file

@ -0,0 +1,28 @@
# The Mount Command
The `occlum mount` command is designed to mount the secure FS image of the Occlum instance as a Linux FS at a specified path on Linux. This makes it easy to access and manipulate Occlum's secure FS for debug purpose.
To mount an Occlum's secure FS image successfully, three conditions must be satisfied:
1. The secure FS image exists and is not being used (e.g., via the `occlum run` or `occlum mount` command). This condition ensures that the secure FS will not be broken due to the concurrent access of different Occlum commands.
2. The two (optional) sign key and sign tool arguments that are given to the `occlum mount` command must have the same values as those given to the `occlum build` command, which is how the image is created in the first place. This ensures that the secure FS can only be accessed by the owner of the enclave.
3. The `occlum mount` command must be run on the same machine as the `occlum run` command that runs the current Occlum instance and writes to the image. This condition is due to the fact that the encryption key of the secure FS is bound to the machine.
With the three conditions satisfied, the mount command is able to start a Linux FUSE (Filesystems in Userspace) 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.
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.
## How to use
Step 1: Create an empty directory to serve as the mount point
```
mkdir <path>
```
Step 2: Mount the secure FS at the newly created mount point
```
occlum mount [--sign-key <key_path>] [--sign-tool <tool_path>] <path>
```
After mounting the secure FS successfully, you can access and manipulate the FS from the mount point as easy as regular Linux FS.

@ -2,10 +2,14 @@
/opt/occlum/build/bin/occlum-gen-default-occlum-json /opt/occlum/build/bin/occlum-gen-default-occlum-json
/opt/occlum/build/bin/occlum-protect-integrity /opt/occlum/build/bin/occlum-protect-integrity
/opt/occlum/build/bin/sefs-cli /opt/occlum/build/bin/sefs-cli
/opt/occlum/build/bin/sefs-cli_sim
/opt/occlum/build/lib/libocclum-pal_sim.so* /opt/occlum/build/lib/libocclum-pal_sim.so*
/opt/occlum/build/lib/libocclum-libos.so* /opt/occlum/build/lib/libocclum-libos.so*
/opt/occlum/build/lib/libocclum-libos_sim.so* /opt/occlum/build/lib/libocclum-libos_sim.so*
/opt/occlum/build/lib/libsefs-cli.so
/opt/occlum/build/lib/libsefs-cli_sim.so
/opt/occlum/build/lib/libsefs-cli.signed.so /opt/occlum/build/lib/libsefs-cli.signed.so
/opt/occlum/build/lib/occlum-protect-integrity.signed.so* /opt/occlum/build/lib/occlum-protect-integrity.signed.so*
/opt/occlum/build/sefs-cli.Enclave.xml
/opt/occlum/etc/template/* /opt/occlum/etc/template/*
/opt/occlum/include/* /opt/occlum/include/*

@ -55,6 +55,10 @@ Usage:
occlum gdb <program_name> <program_args> occlum gdb <program_name> <program_args>
Debug the program running inside an SGX enclave with GDB. Debug the program running inside an SGX enclave with GDB.
occlum mount [--sign-key <key_path>] [--sign-tool <tool_path>] <path>
Mount the secure FS image of the Occlum instance as a Linux FS at an existing <path>.
This makes it easy to access and manipulate Occlum's secure FS for debug purpose.
EOF EOF
} }
@ -174,8 +178,8 @@ cmd_build() {
rm -rf "$instance_dir/run" rm -rf "$instance_dir/run"
occlum_dir=$occlum_dir instance_dir=$instance_dir pal_lib=$pal_lib major_ver=$major_ver \ occlum_dir=$occlum_dir instance_dir=$instance_dir pal_lib=$pal_lib major_ver=$major_ver \
occlum_version=$occlum_version libos_lib=$libos_lib ENCLAVE_SIGN_KEY=$ENCLAVE_SIGN_KEY \ occlum_version=$occlum_version libos_lib=$libos_lib \
ENCLAVE_SIGN_TOOL=$ENCLAVE_SIGN_TOOL \ ENCLAVE_SIGN_KEY=$ENCLAVE_SIGN_KEY ENCLAVE_SIGN_TOOL=$ENCLAVE_SIGN_TOOL \
make -f $build_makefile $MAKE_OPTION make -f $build_makefile $MAKE_OPTION
cd "$instance_dir" cd "$instance_dir"
@ -278,6 +282,62 @@ cmd_gdb() {
echo "built" > "$status_file" echo "built" > "$status_file"
} }
cmd_mount() {
check_has_built
while [ -n "$1" ]; do
case "$1" in
--sign-key) [ -n "$2" ] && ENCLAVE_SIGN_KEY=$2 ; shift 2 || exit_error "empty signing key path" ;;
--sign-tool) [ -n "$2" ] && ENCLAVE_SIGN_TOOL=$2 ; shift 2 || exit_error "empty signing tool path" ;;
*) MNT_POINT=$1 ; shift ;;
esac
done
[ -e "$ENCLAVE_SIGN_KEY" ] || exit_error "invalid signing key path: $ENCLAVE_SIGN_KEY"
[ -e "$ENCLAVE_SIGN_TOOL" ] || exit_error "invalid signing tool path: $ENCLAVE_SIGN_TOOL"
[ -d "$MNT_POINT" ] || exit_error "invalid mount point: $MNT_POINT"
echo "Mount tool sign-tool: $ENCLAVE_SIGN_TOOL"
echo "Mount tool sign-key: $ENCLAVE_SIGN_KEY"
echo "Mount point: $MNT_POINT"
SGX_MODE=$(cat $instance_dir/.sgx_mode)
if [[ -n $SGX_MODE && "$SGX_MODE" != "HW" ]]; then
sefs_cli="$occlum_dir/build/bin/sefs-cli_sim"
sefs_cli_lib="$occlum_dir/build/lib/libsefs-cli_sim.so"
echo "SGX mode: $SGX_MODE"
else
sefs_cli="$occlum_dir/build/bin/sefs-cli"
sefs_cli_lib="$occlum_dir/build/lib/libsefs-cli.so"
echo "SGX mode: HW"
fi
signed_sefs_cli_lib="$instance_dir/build/lib/libsefs-cli.signed.so"
echo "Signing the mount tool..."
"$ENCLAVE_SIGN_TOOL" sign \
-key "$ENCLAVE_SIGN_KEY" \
-config "$occlum_dir/build/sefs-cli.Enclave.xml" \
-enclave "$sefs_cli_lib" \
-out "$signed_sefs_cli_lib"
image_fs="$instance_dir/build/mount/__ROOT"
if [ -e "$instance_dir/run/mount/__ROOT/metadata" ]; then
container_fs="$instance_dir/run/mount/__ROOT"
else
container_fs=""
fi
echo "Start to mount the FS..."
LD_LIBRARY_PATH="$SGX_SDK/sdk_libs" "$sefs_cli" \
--integrity-only \
"$signed_sefs_cli_lib" \
"$image_fs" \
"$container_fs" \
"$MNT_POINT" \
mount
# After mounting the FS, remove the signed mount tool
rm -f "$signed_sefs_cli_lib"
}
cmd_status() { cmd_status() {
cat "$status_file" cat "$status_file"
} }
@ -315,6 +375,9 @@ case "$cmd" in
gdb) gdb)
cmd_gdb "${@:2}" cmd_gdb "${@:2}"
;; ;;
mount)
cmd_mount "${@:2}"
;;
status) status)
cmd_status cmd_status
;; ;;

@ -7,6 +7,9 @@ JSON_CONF := $(instance_dir)/Occlum.json
LIBOS := $(instance_dir)/build/lib/$(libos_lib).$(occlum_version) LIBOS := $(instance_dir)/build/lib/$(libos_lib).$(occlum_version)
SIGNED_ENCLAVE := $(instance_dir)/build/lib/libocclum-libos.signed.so SIGNED_ENCLAVE := $(instance_dir)/build/lib/libocclum-libos.signed.so
SEFS_CLI_SIM := $(occlum_dir)/build/bin/sefs-cli_sim
SIGNED_SEFS_CLI_LIB := $(occlum_dir)/build/lib/libsefs-cli.signed.so
BIN_LINKS := occlum_exec_client occlum_exec_server occlum-run BIN_LINKS := occlum_exec_client occlum_exec_server occlum-run
BIN_LINKS := $(addprefix $(instance_dir)/build/bin/, $(BIN_LINKS)) BIN_LINKS := $(addprefix $(instance_dir)/build/bin/, $(BIN_LINKS))
@ -67,7 +70,9 @@ endef
.PHONY : all .PHONY : all
all: $(SIGNED_ENCLAVE) $(BIN_LINKS) $(LIB_LINKS) ALL_TARGETS := $(SIGNED_ENCLAVE) $(BIN_LINKS) $(LIB_LINKS)
all: $(ALL_TARGETS)
$(SIGNED_ENCLAVE): $(LIBOS) $(SIGNED_ENCLAVE): $(LIBOS)
@echo "Signing the enclave..." @echo "Signing the enclave..."
@ -124,16 +129,17 @@ $(instance_dir)/build/lib:
# If image dir not exist, just use the secure Occlum FS image # If image dir not exist, just use the secure Occlum FS image
ifneq ($(wildcard $(IMAGE)/. ),) ifneq ($(wildcard $(IMAGE)/. ),)
$(SECURE_IMAGE): $(IMAGE) $(IMAGE_DIRS) $(IMAGE_FILES) $(SECURE_IMAGE): $(IMAGE) $(IMAGE_DIRS) $(IMAGE_FILES) $(SEFS_CLI_SIM) $(SIGNED_SEFS_CLI_LIB)
@echo "Building new image..." @echo "Building new image..."
@rm -rf build/mount @rm -rf build/mount
@mkdir -p build/mount/ @mkdir -p build/mount/
@cd "$(occlum_dir)/build/bin/" && \ @LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" $(SEFS_CLI_SIM) \
LD_LIBRARY_PATH="$(SGX_SDK)/sdk_libs" ./sefs-cli \
--integrity-only \ --integrity-only \
"$(SIGNED_SEFS_CLI_LIB)" \
"$(instance_dir)/build/mount/__ROOT" \ "$(instance_dir)/build/mount/__ROOT" \
"" \
"$(instance_dir)/image" \ "$(instance_dir)/image" \
zip zip
endif endif