Skip to content
This repository has been archived by the owner on Jan 20, 2022. It is now read-only.

[Examples] Add SQLite #2493

Merged
merged 1 commit into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .ci/lib/stage-clean-check.jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ stage('clean-check') {
make -C Examples/apache distclean
make -C Examples/blender distclean
make -C Examples/r distclean
make -C Examples/sqlite distclean
make -C Pal/src PAL_HOST=Skeleton clean

make -C Examples/ra-tls-mbedtls distclean
Expand Down
7 changes: 7 additions & 0 deletions .ci/lib/stage-test-direct.jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,11 @@ stage('test-direct') {
make check
'''
}
timeout(time: 5, unit: 'MINUTES') {
sh '''
cd Examples/sqlite
make ${MAKEOPTS} all
make ${MAKEOPTS} regression
'''
}
}
7 changes: 7 additions & 0 deletions .ci/lib/stage-test-sgx.jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ stage('test-sgx') {
make ${MAKEOPTS} check
'''
}
timeout(time: 5, unit: 'MINUTES') {
sh '''
cd Examples/sqlite
make ${MAKEOPTS} all
make ${MAKEOPTS} regression
'''
}
timeout(time: 5, unit: 'MINUTES') {
sh '''
cd Examples/ra-tls-mbedtls
Expand Down
1 change: 1 addition & 0 deletions .ci/ubuntu18.04.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y \
python3-scipy \
r-base-core \
shellcheck \
sqlite3 \
texinfo \
wget \
zlib1g \
Expand Down
1 change: 1 addition & 0 deletions .ci/ubuntu20.04.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ RUN apt-get update && env DEBIAN_FRONTEND=noninteractive apt-get install -y \
r-base-core \
shellcheck \
sphinx-doc \
sqlite3 \
texinfo \
wget \
zlib1g \
Expand Down
3 changes: 3 additions & 0 deletions Examples/sqlite/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/OUTPUT
/scripts/testdir/*
!/scripts/testdir/.dummy
71 changes: 71 additions & 0 deletions Examples/sqlite/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Use one of these commands to build the manifest for sqlite:
#
# - make
# - make DEBUG=1
# - make SGX=1
# - make SGX=1 DEBUG=1
#
# Use `make clean` to remove Graphene-generated files.

# Relative path to Graphene root and key for enclave signing
GRAPHENEDIR ?= ../..
SGX_SIGNER_KEY ?= $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem

ifeq ($(DEBUG),1)
GRAPHENE_LOG_LEVEL = debug
else
GRAPHENE_LOG_LEVEL = error
endif

.PHONY: all
all: sqlite3.manifest
ifeq ($(SGX),1)
all: sqlite3.manifest.sgx sqlite3.sig sqlite3.token
endif

include ../../Scripts/Makefile.configs

sqlite3.manifest: manifest.template
graphene-manifest \
-Dlog_level=$(GRAPHENE_LOG_LEVEL) \
-Dexecdir=$(shell dirname $(shell which sqlite3)) \
-Darch_libdir=$(ARCH_LIBDIR) \
$< >$@

sqlite3.manifest.sgx: sqlite3.manifest
graphene-sgx-sign \
--key $(SGX_SIGNER_KEY) \
--manifest sqlite3.manifest \
--output $@

sqlite3.sig: sqlite3.manifest.sgx

sqlite3.token: sqlite3.sig
graphene-sgx-get-token --output sqlite3.token --sig sqlite3.sig

ifeq ($(SGX),)
GRAPHENE = graphene-direct
else
GRAPHENE = graphene-sgx
endif

.PHONY: regression
regression: all
@rm -f scripts/testdir/*

$(GRAPHENE) sqlite3 scripts/testdir/test.db < scripts/create.sql
@echo "[ Success 1/3 ]"

$(GRAPHENE) sqlite3 scripts/testdir/test.db < scripts/update.sql
@echo "[ Success 2/3 ]"

$(GRAPHENE) sqlite3 scripts/testdir/test.db < scripts/select.sql > OUTPUT
diff OUTPUT scripts/select.txt
@echo "[ Success 3/3 ]"

.PHONY: clean
clean:
$(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT scripts/testdir/*

.PHONY: distclean
distclean: clean
54 changes: 54 additions & 0 deletions Examples/sqlite/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# SQLite example

This directory contains an example for running SQLite in Graphene, including the
Makefile and a template for generating the manifest. The application is tested
on Ubuntu 20.04, with both normal Linux and SGX platforms.

# Generating the manifest

## Installing prerequisite:

Please run the following command to install SQLite (Ubuntu-specific):

sudo apt-get install sqlite3

## Building for Linux

Run `make` (non-debug) or `make DEBUG=1` (debug) in the directory.

## Building for SGX

Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the directory.

# Running SQLite with Graphene

Here's an example of running SQLite under Graphene:

Without SGX:
```
graphene-direct sqlite scripts/testdir/test.db < scripts/create.sql
graphene-direct sqlite scripts/testdir/test.db < scripts/update.sql
graphene-direct sqlite scripts/testdir/test.db < scripts/select.sql
```

With SGX:
```
graphene-sgx sqlite scripts/testdir/test.db < scripts/create.sql
graphene-sgx sqlite scripts/testdir/test.db < scripts/update.sql
graphene-sgx sqlite scripts/testdir/test.db < scripts/select.sql
```

# Note about concurrency

SQLite uses POSIX record locks (`fcntl`) to guard concurrent accesses to the
database file. These locks are emulated within Graphene, and not translated to
host-level locks, even if you are mounting a file from the host.

That means it is safe to access the same database file from multiple processes,
but only within a **single Graphene instance**. In other words, a multi-process
Graphene application is OK, but multiple Graphene instances should not access
the same database file concurrently.

Note that in a production setup, the database should be either mounted as a
protected file, or from tmpfs, which would make it impossible to access from
multiple Graphene instances anyway.
47 changes: 47 additions & 0 deletions Examples/sqlite/manifest.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This is a general manifest template for running SQLite.
#
# This manifest was prepared and tested on Ubuntu 20.04.
loader.preload = "file:{{ graphene.libos }}"
libos.entrypoint = "{{ execdir }}/sqlite3"

# Read application arguments directly from the command line. Don't use this on production!
loader.insecure__use_cmdline_argv = true

loader.log_level = "{{ log_level }}"

# Environment variables
loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}"
loader.env.PATH = "{{ execdir }}"
# Set HOME to suppress "warning: cannot find home directory; cannot read ~/.sqliterc"
loader.env.HOME = "/"

# Mounted FSes. The following "chroot" FSes mount a part of the host FS into the
# guest. Other parts of the host FS will not be available in the guest.

# Default glibc files, mounted from the Runtime directory in GRAPHENEDIR.
fs.mount.lib.type = "chroot"
fs.mount.lib.path = "/lib"
fs.mount.lib.uri = "file:{{ graphene.runtimedir() }}"

# Host-level libraries (e.g., /lib/x86_64-linux-gnu) required by SQLite3
fs.mount.lib64.type = "chroot"
fs.mount.lib64.path = "{{ arch_libdir }}"
fs.mount.lib64.uri = "file:{{ arch_libdir }}"

# Mount sqlite3 binary
fs.mount.sqlite3.type = "chroot"
fs.mount.sqlite3.path = "{{ execdir }}/sqlite3"
fs.mount.sqlite3.uri = "file:{{ execdir }}/sqlite3"

# SGX general options

sgx.enclave_size = "256M"
sgx.thread_num = 4

# SGX trusted files

sgx.trusted_files.sqlite3 = "file:{{ execdir }}/sqlite3"
sgx.trusted_files.runtime = "file:{{ graphene.runtimedir() }}/"
sgx.trusted_files.arch_libdir = "file:{{ arch_libdir }}/"

sgx.allowed_files.scripts = "file:scripts/"
8 changes: 8 additions & 0 deletions Examples/sqlite/scripts/create.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
DROP TABLE IF EXISTS tab;

CREATE TABLE tab (
id INTEGER,
str TEXT
);

INSERT INTO tab (id, str) VALUES (1, ''), (2, ''), (3, ''), (4, '');
1 change: 1 addition & 0 deletions Examples/sqlite/scripts/select.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
SELECT id, str FROM tab ORDER BY id DESC;
4 changes: 4 additions & 0 deletions Examples/sqlite/scripts/select.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
4|row 4
3|row 3
2|row 2
1|row 1
Empty file.
1 change: 1 addition & 0 deletions Examples/sqlite/scripts/update.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
UPDATE tab SET str = 'row ' || id;