Skip to content

Commit dfd16f8

Browse files
linux-sgx: Implement SGX IPFS as POSIX backend for file interaction (#1489)
This PR integrates an Intel SGX feature called Intel Protection File System Library (IPFS) into the runtime to create, operate and delete files inside the enclave, while guaranteeing the confidentiality and integrity of the data persisted. IPFS can be referred to here: https://www.intel.com/content/www/us/en/developer/articles/technical/overview-of-intel-protected-file-system-library-using-software-guard-extensions.html Introduce a cmake variable `WAMR_BUILD_SGX_IPFS`, when enabled, the files interaction API of WASI will leverage IPFS, instead of the regular POSIX OCALLs. The implementation has been written with light changes to sgx platform layer, so all the security aspects WAMR relies on are conserved. In addition to this integration, the following changes have been made: - The CI workflow has been adapted to test the compilation of the runtime and sample with the flag `WAMR_BUILD_SGX_IPFS` set to true - Introduction of a new sample that demonstrates the interaction of the files (called `file`), - Documentation of this new feature
1 parent fa736d1 commit dfd16f8

File tree

20 files changed

+1211
-4
lines changed

20 files changed

+1211
-4
lines changed

.github/workflows/compilation_on_android_ubuntu.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,15 @@ jobs:
413413
./build.sh
414414
./run.sh
415415
416+
- name: Build Sample [file]
417+
if: ${{ matrix.light == 'green' }}
418+
run: |
419+
cd samples/file
420+
mkdir build && cd build
421+
cmake ..
422+
cmake --build . --config Release --parallel 4
423+
./src/iwasm -f wasm-app/file.wasm -d .
424+
416425
- name: Build Sample [multi-thread]
417426
if: ${{ matrix.light == 'green' }}
418427
run: |

.github/workflows/compilation_on_macos.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,15 @@ jobs:
356356
./build.sh
357357
./run.sh
358358
359+
- name: Build Sample [file]
360+
if: ${{ matrix.light == 'green' }}
361+
run: |
362+
cd samples/file
363+
mkdir build && cd build
364+
cmake ..
365+
cmake --build . --config Release --parallel 4
366+
./src/iwasm -f wasm-app/file.wasm -d .
367+
359368
- name: Build Sample [multi-thread]
360369
if: ${{ matrix.light == 'green' }}
361370
run: |

.github/workflows/compilation_on_sgx.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ jobs:
140140
# "-DWAMR_BUILD_SIMD=1",
141141
"-DWAMR_BUILD_TAIL_CALL=1",
142142
"-DWAMR_DISABLE_HW_BOUND_CHECK=1",
143+
"-DWAMR_BUILD_SGX_IPFS=1",
143144
]
144145
os: [ubuntu-20.04]
145146
platform: [linux-sgx]
@@ -363,6 +364,15 @@ jobs:
363364
./build.sh
364365
./run.sh
365366
367+
- name: Build Sample [file]
368+
if: ${{ matrix.light == 'green' }}
369+
run: |
370+
cd samples/file
371+
mkdir build && cd build
372+
cmake ..
373+
cmake --build . --config Release --parallel 4
374+
./src/iwasm -f wasm-app/file.wasm -d .
375+
366376
- name: Build Sample [multi-thread]
367377
if: ${{ matrix.light == 'green' }}
368378
run: |

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a
151151

152152
- [**basic**](./samples/basic): Demonstrating how to use runtime exposed API's to call WASM functions, how to register native functions and call them, and how to call WASM function from native function.
153153
- **[simple](./samples/simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default.
154+
- **[file](./samples/file/README.md)**: Demonstrating the supported file interaction API of WASI. This sample can also demonstrate the SGX IPFS (Intel Protected File System), enabling an enclave to seal and unseal data at rest.
154155
- **[littlevgl](./samples/littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LVGL](https://github.com/lvgl/lvgl) 2D user graphic library and the UI application are built into WASM application. It uses **WASI libc** and executes apps in **AOT mode** by default.
155156
- **[gui](./samples/gui/README.md)**: Move the [LVGL](https://github.com/lvgl/lvgl) library into the runtime and define a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default.
156157
- **[multi-thread](./samples/multi-thread/)**: Demonstrating how to run wasm application which creates multiple threads to execute wasm functions concurrently, and uses mutex/cond by calling pthread related API's.

build-scripts/config_common.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,7 @@ if (WAMR_BUILD_STACK_GUARD_SIZE GREATER 0)
287287
add_definitions (-DWASM_STACK_GUARD_SIZE=${WAMR_BUILD_STACK_GUARD_SIZE})
288288
message (" Custom stack guard size: " ${WAMR_BUILD_STACK_GUARD_SIZE})
289289
endif ()
290+
if (WAMR_BUILD_SGX_IPFS EQUAL 1)
291+
add_definitions (-DWASM_ENABLE_SGX_IPFS=1)
292+
message (" SGX IPFS enabled")
293+
endif ()

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,4 +407,8 @@
407407
#define WASM_ENABLE_REF_TYPES 0
408408
#endif
409409

410+
#ifndef WASM_ENABLE_SGX_IPFS
411+
#define WASM_ENABLE_SGX_IPFS 0
412+
#endif
413+
410414
#endif /* end of _CONFIG_H_ */

core/shared/platform/linux-sgx/sgx_file.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#include "sgx_error.h"
88
#include "sgx_file.h"
99

10+
#if WASM_ENABLE_SGX_IPFS != 0
11+
#include "sgx_ipfs.h"
12+
#endif
13+
1014
#ifndef SGX_DISABLE_WASI
1115

1216
#define TRACE_FUNC() os_printf("undefined %s\n", __FUNCTION__)
@@ -184,6 +188,22 @@ openat(int dirfd, const char *pathname, int flags, ...)
184188

185189
if (fd == -1)
186190
errno = get_errno();
191+
192+
#if WASM_ENABLE_SGX_IPFS != 0
193+
// When WAMR uses Intel SGX IPFS to enabled, it opens a second
194+
// file descriptor to interact with the secure file.
195+
// The first file descriptor opened earlier is used to interact
196+
// with the metadata of the file (e.g., time, flags, etc.).
197+
int ret;
198+
void *file_ptr = ipfs_fopen(fd, pathname, flags);
199+
if (file_ptr == NULL) {
200+
if (ocall_close(&ret, fd) != SGX_SUCCESS) {
201+
TRACE_OCALL_FAIL();
202+
}
203+
return -1;
204+
}
205+
#endif
206+
187207
return fd;
188208
}
189209

@@ -192,6 +212,13 @@ close(int fd)
192212
{
193213
int ret;
194214

215+
#if WASM_ENABLE_SGX_IPFS != 0
216+
// Close the IPFS file pointer in addition of the file descriptor
217+
ret = ipfs_close(fd);
218+
if (ret == -1)
219+
errno = get_errno();
220+
#endif
221+
195222
if (ocall_close(&ret, fd) != SGX_SUCCESS) {
196223
TRACE_OCALL_FAIL();
197224
return -1;
@@ -345,6 +372,12 @@ readv_internal(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
345372
if (total_size >= UINT32_MAX)
346373
return -1;
347374

375+
#if WASM_ENABLE_SGX_IPFS != 0
376+
if (fd > 2) {
377+
return ipfs_read(fd, iov, iovcnt, has_offset, offset);
378+
}
379+
#endif
380+
348381
iov1 = BH_MALLOC((uint32)total_size);
349382

350383
if (iov1 == NULL)
@@ -410,6 +443,12 @@ writev_internal(int fd, const struct iovec *iov, int iovcnt, bool has_offset,
410443
if (total_size >= UINT32_MAX)
411444
return -1;
412445

446+
#if WASM_ENABLE_SGX_IPFS != 0
447+
if (fd > 2) {
448+
return ipfs_write(fd, iov, iovcnt, has_offset, offset);
449+
}
450+
#endif
451+
413452
iov1 = BH_MALLOC((uint32)total_size);
414453

415454
if (iov1 == NULL)
@@ -468,12 +507,18 @@ off_t
468507
lseek(int fd, off_t offset, int whence)
469508
{
470509
off_t ret;
510+
511+
#if WASM_ENABLE_SGX_IPFS != 0
512+
ret = ipfs_lseek(fd, offset, whence);
513+
#else
471514
if (ocall_lseek(&ret, fd, (long)offset, whence) != SGX_SUCCESS) {
472515
TRACE_OCALL_FAIL();
473516
return -1;
474517
}
475518
if (ret == -1)
476519
errno = get_errno();
520+
#endif
521+
477522
return ret;
478523
}
479524

@@ -482,12 +527,17 @@ ftruncate(int fd, off_t length)
482527
{
483528
int ret;
484529

530+
#if WASM_ENABLE_SGX_IPFS != 0
531+
ret = ipfs_ftruncate(fd, length);
532+
#else
485533
if (ocall_ftruncate(&ret, fd, length) != SGX_SUCCESS) {
486534
TRACE_OCALL_FAIL();
487535
return -1;
488536
}
489537
if (ret == -1)
490538
errno = get_errno();
539+
#endif
540+
491541
return ret;
492542
}
493543

@@ -554,12 +604,17 @@ fsync(int fd)
554604
{
555605
int ret;
556606

607+
#if WASM_ENABLE_SGX_IPFS != 0
608+
ret = ipfs_fflush(fd);
609+
#else
557610
if (ocall_fsync(&ret, fd) != SGX_SUCCESS) {
558611
TRACE_OCALL_FAIL();
559612
return -1;
560613
}
561614
if (ret == -1)
562615
errno = get_errno();
616+
#endif
617+
563618
return ret;
564619
}
565620

@@ -568,12 +623,17 @@ fdatasync(int fd)
568623
{
569624
int ret;
570625

626+
#if WASM_ENABLE_SGX_IPFS != 0
627+
ret = ipfs_fflush(fd);
628+
#else
571629
if (ocall_fdatasync(&ret, fd) != SGX_SUCCESS) {
572630
TRACE_OCALL_FAIL();
573631
return -1;
574632
}
575633
if (ret == -1)
576634
errno = get_errno();
635+
#endif
636+
577637
return ret;
578638
}
579639

@@ -801,10 +861,14 @@ posix_fallocate(int fd, off_t offset, off_t len)
801861
{
802862
int ret;
803863

864+
#if WASM_ENABLE_SGX_IPFS != 0
865+
ret = ipfs_posix_fallocate(fd, offset, len);
866+
#else
804867
if (ocall_posix_fallocate(&ret, fd, offset, len) != SGX_SUCCESS) {
805868
TRACE_OCALL_FAIL();
806869
return -1;
807870
}
871+
#endif
808872

809873
return ret;
810874
}

0 commit comments

Comments
 (0)