Skip to content
This repository has been archived by the owner on Mar 31, 2020. It is now read-only.

Commit

Permalink
Rewrite R example
Browse files Browse the repository at this point in the history
  • Loading branch information
chiache authored and mkow committed Sep 3, 2019
1 parent b60c298 commit 050ae21
Show file tree
Hide file tree
Showing 7 changed files with 653 additions and 135 deletions.
133 changes: 116 additions & 17 deletions r/Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,124 @@
R_SRC = R-3.1.2
R_INSTALL = $(R_SRC)/build
# Build the manifest for R:
#
# - make Building for Linux
# - make DEBUG=1 Building for Linux (with Graphene debug output)
# - make SGX=1 Building for SGX
# - make SGX=1 DEBUG=1 Building for SGX (with Graphene debug output)
#
# Use `make clean` to remove Graphene-generated files.

manifests = R.manifest Rscript.manifest sh.manifest $(if $(wildcard R-local),R-local.manifest,)
# Constants

target =
exec_target = $(manifests)
# Installation location of R. By default, Graphene will run the system R executable.
R_HOME ?= /usr/lib/R
R_EXEC = $(R_HOME)/bin/exec/R

extra_rules = -e 's:\$$(RDIR):$(R_INSTALL)/lib/R/:g'
# Relative path to Graphene root
GRAPHENEDIR ?= ../../../../..

include ../../Makefile.Test
ifeq ($(DEBUG),1)
GRAPHENEDEBUG = inline
else
GRAPHENEDEBUG = none
endif

$(R_INSTALL)/lib/R/bin/exec/R: $(R_SRC)/Makefile
cd $(R_SRC) && $(MAKE)
cd $(R_SRC) && $(MAKE) install
LD_LIBRARY_PATH := $(LD_LIBRARY_PATH):$(R_HOME)/lib
export LD_LIBRARY_PATH

$(R_SRC)/Makefile: $(R_SRC)/configure
cd $(R_SRC) && \
./configure --prefix=$(shell readlink -f $(R_INSTALL))
.PHONY: all
all: R.manifest sh.manifest pal_loader
ifeq ($(SGX),1)
all: R.manifest.sgx R.sig R.token sh.manifest.sgx sh.sig sh.token
endif

$(R_SRC)/configure: $(R_SRC).tar.gz
tar -xmzf $<
# R dependencies (generate from ldd):
#
# For SGX, the manifest needs to list all the libraries loaded during the
# execution, so that the signer can include the file checksums.
#
# The dependencies are generated from the ldd results of:
# - $(R_HOME)/bin/exec/R
# - $(R_HOME)/library/stats/libs/stats.so
# - $(R_HOME)/modules/lapack.so

distclean: clean
rm -rf $(R_SRC)
# We need to replace Glibc dependencies with Graphene-specific Glibc. The Glibc
# binaries are already listed in the manifest template, so we can skip them
# from the ldd results
GLIBC_DEPS = linux-vdso /lib64/ld-linux-x86-64 libc libm librt libdl libpthread

# Use the ldd result of R, stats.so, and lapack.so
R_TARGETS = $(R_EXEC) $(R_HOME)/library/stats/libs/stats.so $(R_HOME)/modules/lapack.so

# Listing all the R dependencies, besides Glibc libraries
.INTERMEDIATE: R-ldd
R-ldd:
@for F in $(R_TARGETS); do ldd $$F >> $@ || exit 1; done

.INTERMEDIATE: R-deps
R-deps: R-ldd
@cat $< | awk '{if ($$2 =="=>") {split($$1,s,/\./); print s[1]}}' \
| sort | uniq | grep -v -x $(patsubst %,-e %,$(GLIBC_DEPS)) > $@

# Generating manifest rules for R dependencies
.INTERMEDIATE: R-trusted-libs
R-trusted-libs: R-deps
@R_LIBS="$(R_TARGETS)" && \
for F in `cat R-deps`; do \
P=`ldd $$R_LIBS | grep $$F | awk '{print $$3; exit}'`; \
N=`echo $$F | tr --delete '-'`; \
echo -n "sgx.trusted_files.$$N = file:$$P\\\\n"; \
done > $@

# R manifests:
# For each dependency, generate a rule as follows:
# sgx.trusted_files.xxxx = file:xxxx

R.manifest: R.manifest.template R-trusted-libs
sed -e 's|$$(GRAPHENEDIR)|'"$(GRAPHENEDIR)"'|g' \
-e 's|$$(GRAPHENEDEBUG)|'"$(GRAPHENEDEBUG)"'|g' \
-e 's|$$(R_HOME)|'"$(R_HOME)"'|g' \
-e 's|$$(R_EXEC)|'"$(R_EXEC)"'|g' \
-e 's|$$(R_TRUSTED_LIBS)|'"`cat R-trusted-libs`"'|g' \
$< > $@

sh.manifest: sh.manifest.template
sed -e 's|$$(GRAPHENEDIR)|'"$(GRAPHENEDIR)"'|g' \
-e 's|$$(GRAPHENEDEBUG)|'"$(GRAPHENEDEBUG)"'|g' \
$< > $@

# R manifests for SGX:
# Generating the SGX-specific manifest (R.manifest.sgx), the enclave signature,
# and the token for enclave initialization.

R.manifest.sgx: R.manifest sh.manifest.sgx
$(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-sign \
-libpal $(GRAPHENEDIR)/Runtime/libpal-Linux-SGX.so \
-key $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem \
-manifest $< -output $@

R.sig: R.manifest.sgx

R.token: R.sig
$(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token \
-output R.token -sig R.sig

# sh.manifest.sgx is needed for R to run the shell for file clean-up
sh.manifest.sgx: sh.manifest
$(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-sign \
-libpal $(GRAPHENEDIR)/Runtime/libpal-Linux-SGX.so \
-key $(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/enclave-key.pem \
-manifest $< -output $@

sh.sig: sh.manifest.sgx

sh.token: sh.sig
$(GRAPHENEDIR)/Pal/src/host/Linux-SGX/signer/pal-sgx-get-token \
-output sh.token -sig sh.sig

# Extra executables
pal_loader:
ln -s $(GRAPHENEDIR)/Runtime/pal_loader $@

.PHONY: clean
clean:
$(RM) *.manifest *.manifest.sgx *.token *.sig pal_loader
Binary file removed r/R-3.1.2.tar.gz
Binary file not shown.
114 changes: 68 additions & 46 deletions r/R.manifest.template
Original file line number Diff line number Diff line change
@@ -1,73 +1,95 @@
#!$(PAL)
# R manifest example
#
# This manifest was prepared and tested on Ubuntu 16.04.
#
# R must be run with the pal_loader:
#
# ./pal_loader R.manifest <script>

loader.preload = file:$(SHIMPATH)
loader.exec = file:/usr/lib/R/bin/exec/R
loader.execname = /usr/lib/R/bin/exec/R
loader.env.LD_LIBRARY_PATH = /lib:/lib/x86_64-linux-gnu:/usr/lib:/usr/lib/x86_64-linux-gnu
loader.env.PATH = /usr/lib/R/bin:/usr/bin:/bin
# The executable to load in Graphene. By default, $(R_HOME) points to the R
# system installation. To run R from a local installation, specify R_HOME
# when running `make` in this directory.
loader.exec = file:$(R_EXEC)

# Graphene environment, including the path of the library OS and the debug
# option (inline/none).
loader.preload = file:$(GRAPHENEDIR)/Runtime/libsysdb.so
loader.debug_type = $(GRAPHENEDEBUG)

# Environment variables for R
loader.env.LD_LIBRARY_PATH = $(R_HOME)/lib:/lib:/lib/x86_64-linux-gnu:/usr/lib:/usr/lib/x86_64-linux-gnu
loader.env.PATH = $(R_HOME)/bin:/usr/bin:/bin
loader.env.USERNAME =
loader.env.HOME =
loader.env.PWD =
loader.env.R_ARCH =
loader.env.R_HOME = /usr/lib/R
loader.env.R_SHARE_DIR = /usr/share/R/share
loader.env.R_INCLUDE_DIR = /usr/share/R/include
loader.env.R_DOC_DIR = /usr/share/R/doc
loader.debug_type = none
loader.env.R_HOME = $(R_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.

fs.mount.lib1.type = chroot
fs.mount.lib1.path = /lib
fs.mount.lib1.uri = file:$(LIBCDIR)
# 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:$(GRAPHENEDIR)/Runtime

# Host-level libraries (/lib/x86_64-linux-gnu) required by the R executable
fs.mount.lib2.type = chroot
fs.mount.lib2.path = /lib/x86_64-linux-gnu
fs.mount.lib2.uri = file:/lib/x86_64-linux-gnu

# Host-level directory (/usr) required by the R executable
fs.mount.usr.type = chroot
fs.mount.usr.path = /usr
fs.mount.usr.uri = file:/usr

fs.mount.bin.type = chroot
fs.mount.bin.path = /bin
fs.mount.bin.uri = file:/bin
# Mount $R_HOME
fs.mount.r_home.type = chroot
fs.mount.r_home.path = $(R_HOME)
fs.mount.r_home.uri = file:$(R_HOME)

# Mount /tmp
fs.mount.tmp.type = chroot
fs.mount.tmp.path = /tmp
fs.mount.tmp.uri = file:/tmp

sys.stack.size = 256K
sys.brk.size = 4M
glibc.heap_size = 16M

# SGX general options

# Set the virtual memory size of the SGX enclave. For SGX v1, the enclave
# size must be specified during signing. If R needs more virtual memory than
# the enclave size, Graphene will not be able to allocate it.
sgx.enclave_size = 1G

sgx.trusted_files.ld = file:$(LIBCDIR)/ld-linux-x86-64.so.2
sgx.trusted_files.libc = file:$(LIBCDIR)/libc.so.6
sgx.trusted_files.libdl = file:$(LIBCDIR)/libdl.so.2
sgx.trusted_files.libm = file:$(LIBCDIR)/libm.so.6
sgx.trusted_files.libpthread = file:$(LIBCDIR)/libpthread.so.0
sgx.trusted_files.libutil = file:$(LIBCDIR)/libutil.so.1
sgx.trusted_files.librt = file:$(LIBCDIR)/librt.so.1
sgx.trusted_files.libnsl = file:/lib/x86_64-linux-gnu/libnsl.so.1
sgx.trusted_files.libreadline = file:/lib/x86_64-linux-gnu/libreadline.so.6
sgx.trusted_files.libpcre = file:/lib/x86_64-linux-gnu/libpcre.so.3
sgx.trusted_files.liblzma = file:/lib/x86_64-linux-gnu/liblzma.so.5
sgx.trusted_files.libz2 = file:/lib/x86_64-linux-gnu/libbz2.so.1.0
sgx.trusted_files.libz = file:/lib/x86_64-linux-gnu/libz.so.1
sgx.trusted_files.libtinfo = file:/lib/x86_64-linux-gnu/libtinfo.so.5
sgx.trusted_files.libgomp = file:/usr/lib/x86_64-linux-gnu/libgomp.so.1
sgx.trusted_files.libR = file:/usr/lib/libR.so
sgx.trusted_files.libblas = file:/usr/lib/libblas.so.3
sgx.trusted_files.liblapack = file:/usr/lib/liblapack.so.3
sgx.trusted_files.libnssfiles = file:/lib/x86_64-linux-gnu/libnss_files.so.2
sgx.trusted_files.libnsscompact = file:/lib/x86_64-linux-gnu/libnss_compat.so.2
sgx.trusted_files.libnssnis = file:/lib/x86_64-linux-gnu/libnss_nis.so.2
sgx.trusted_files.libgfortran = file:/usr/lib/x86_64-linux-gnu/libgfortran.so.3
sgx.trusted_files.libgcc = file:/lib/x86_64-linux-gnu/libgcc_s.so.1
sgx.trusted_files.libquadmath = file:/usr/lib/x86_64-linux-gnu/libquadmath.so.0
sgx.trusted_files.sh = file:/bin/sh
# Set the maximum number of enclave threads. For SGX v1, the number of enclave
# TCSes must be specified during signing, so the application cannot use more
# threads than the number of TCSes. Note that Graphene also creates an internal
# thread for handling inter-process communication (IPC), and potentially another
# thread for asynchronous events. Therefore, the actual number of threads that
# the application can create is (sgx.thread_num - 2).
sgx.thread_num = 4

sgx.allowed_files.rhome = file:/usr/lib/R
# SGX trusted libraries

# Glibc libraries
sgx.trusted_files.ld = file:$(GRAPHENEDIR)/Runtime/ld-linux-x86-64.so.2
sgx.trusted_files.libc = file:$(GRAPHENEDIR)/Runtime/libc.so.6
sgx.trusted_files.libm = file:$(GRAPHENEDIR)/Runtime/libm.so.6
sgx.trusted_files.libdl = file:$(GRAPHENEDIR)/Runtime/libdl.so.2
sgx.trusted_files.librt = file:$(GRAPHENEDIR)/Runtime/librt.so.1
sgx.trusted_files.libpthread = file:$(GRAPHENEDIR)/Runtime/libpthread.so.0

# Other libraries as dependencies of R (generated from ldd from the Makefile)
sgx.trusted_files.stats_lib = file:$(R_HOME)/library/stats/libs/stats.so
sgx.trusted_files.lapack = file:$(R_HOME)/modules/lapack.so
$(R_TRUSTED_LIBS)

# SGX untrusted (allowed) files/directories
sgx.allowed_files.scripts = file:scripts
sgx.allowed_files.tmp = file:/tmp
sgx.allowed_files.r_etc = file:$(R_HOME)/etc
sgx.allowed_files.r_lib = file:$(R_HOME)/library

# Allow creating child enclaves for sh
sgx.trusted_files.sh = file:/bin/sh
sgx.trusted_children.sh = file:sh.sig
43 changes: 43 additions & 0 deletions r/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# R example

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

# Generating the manifest

## 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.

## Building with a local R installation

By default, the `make` command creates the manifest for the system R binary
(`/usr/lib/R/bin/exec/R`). If you have a local R installation, you may create
the manifest with the `R_HOME` variable set accordingly. For example:

```
make R_HOME=<install path>/lib/R SGX=1
```

# Run R with Graphene

When running R with Graphene, please use the `--vanilla` or `--no-save` option.

Here's an example of running an R script under Graphene:

Without SGX:
```
./pal_loader R.manifest --slave --vanilla -f scripts/sample.r
./pal_loader R.manifest --slave --vanilla -f scripts/R-benchmark-25.R
```

With SGX:
```
SGX=1 ./pal_loader R.manifest --slave --vanilla -f scripts/sample.r
SGX=1 ./pal_loader R.manifest --slave --vanilla -f scripts/R-benchmark-25.R
```
Loading

0 comments on commit 050ae21

Please sign in to comment.