Works with a minimal version of Occlum's libc

This commit is contained in:
Tate, Hongliang Tian 2018-11-18 23:08:43 +08:00
parent a4f37f8917
commit f0e7bae0d7
19 changed files with 24 additions and 346 deletions

@ -51,7 +51,7 @@ pub fn do_write(fd: FileDesc, buf: &[u8]) -> Result<usize, Error> {
let current_ref = process::get_current(); let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let file_ref = current_process.file_table.get(fd) let file_ref = current_process.file_table.get(fd)
.ok_or_else(|| Error::new(Errno::EBADF, "Invalid file descriptor"))?; .ok_or_else(|| Error::new(Errno::EBADF, "Invalid file descriptor [do_write]"))?;
file_ref.write(buf) file_ref.write(buf)
} }
@ -59,7 +59,7 @@ pub fn do_read(fd: FileDesc, buf: &mut [u8]) -> Result<usize, Error> {
let current_ref = process::get_current(); let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap(); let current_process = current_ref.lock().unwrap();
let file_ref = current_process.file_table.get(fd) let file_ref = current_process.file_table.get(fd)
.ok_or_else(|| Error::new(Errno::EBADF, "Invalid file descriptor"))?; .ok_or_else(|| Error::new(Errno::EBADF, "Invalid file descriptor [do_read]"))?;
file_ref.read(buf) file_ref.read(buf)
} }
@ -69,6 +69,6 @@ pub fn do_close(fd: FileDesc) -> Result<(), Error> {
let file_table = &mut current_process.file_table; let file_table = &mut current_process.file_table;
match file_table.del(fd) { match file_table.del(fd) {
Some(_) => Ok(()), Some(_) => Ok(()),
None => Err(Error::new(Errno::EBADF, "Invalid file descriptor")), None => Err(Error::new(Errno::EBADF, "Invalid file descriptor [do_close]")),
} }
} }

@ -18,6 +18,7 @@ extern int occlum_spawn(int* child_pid, const char* path,
extern int occlum_wait4(int child_pid, int* status, int options/*, struct rusage* rusage*/); extern int occlum_wait4(int child_pid, int* status, int options/*, struct rusage* rusage*/);
extern unsigned int occlum_getpid(void); extern unsigned int occlum_getpid(void);
extern void occlum_exit(int status); extern void occlum_exit(int status);
extern int occlum_unknown(int num);
#ifdef __cplusplus #ifdef __cplusplus
} }

@ -85,6 +85,12 @@ pub extern "C" fn occlum_exit(status: i32)
process::do_exit(status); process::do_exit(status);
} }
#[no_mangle]
pub extern "C" fn occlum_unknown(num: u32)
{
println!("[WARNING] Unknown syscall (num = {})", num);
}
#[no_mangle] #[no_mangle]
pub extern "C" fn occlum_spawn(child_pid: *mut c_int, path: *const c_char, pub extern "C" fn occlum_spawn(child_pid: *mut c_int, path: *const c_char,
argv: *const *const c_char, envp: *const *const c_char) -> c_int argv: *const *const c_char, envp: *const *const c_char) -> c_int

@ -61,7 +61,7 @@ long dispatch_syscall(int num, long arg0, long arg1, long arg2, long arg3, long
break; break;
} }
default: default:
ret = -1; ret = occlum_unknown(num);
break; break;
} }

@ -1,7 +1,7 @@
CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) CUR_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
PROJECT_DIR := $(realpath $(CUR_DIR)/../) PROJECT_DIR := $(realpath $(CUR_DIR)/../)
TEST_SUITES := hello_world_raw spawn_and_wait4_raw getpid file_io TEST_SUITES := empty
BUILD_TEST_SUITES := $(TEST_SUITES:%=%) BUILD_TEST_SUITES := $(TEST_SUITES:%=%)
RUN_TEST_SUITES := $(TEST_SUITES:%=run-%) RUN_TEST_SUITES := $(TEST_SUITES:%=run-%)
CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%) CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)
@ -14,10 +14,7 @@ CLEAN_TEST_SUITES := $(TEST_SUITES:%=clean-%)
all: build all: build
build: build_rusgx_stub $(BUILD_TEST_SUITES) build: $(BUILD_TEST_SUITES)
build_rusgx_stub:
@$(MAKE) -C rusgx_stub
$(BUILD_TEST_SUITES): %: $(BUILD_TEST_SUITES): %:
@$(MAKE) -C $@ @$(MAKE) -C $@
@ -42,7 +39,6 @@ $(RUN_TEST_SUITES): run-%: % pal libocclum.signed.so
############################################################################# #############################################################################
clean: $(CLEAN_TEST_SUITES) clean: $(CLEAN_TEST_SUITES)
@$(MAKE) -C rusgx_stub clean
@$(RM) -f pal libocclum.signed.so @$(RM) -f pal libocclum.signed.so
$(CLEAN_TEST_SUITES): clean-%: $(CLEAN_TEST_SUITES): clean-%:

4
test/empty/Makefile Normal file

@ -0,0 +1,4 @@
include ../test_common.mk
EXTRA_C_FLAGS :=
EXTRA_LINK_FLAGS :=

3
test/empty/empty.c Normal file

@ -0,0 +1,3 @@
int main(void) {
return 0;
}

@ -1,4 +0,0 @@
include ../test_common.mk
EXTRA_C_FLAGS := -fno-builtin
EXTRA_LINK_FLAGS := -nostdlib

@ -1,66 +0,0 @@
#include "rusgx_stub.h"
static char success_str_buf[] = "Success!\n";
static unsigned long success_str_size = sizeof(success_str_buf);
static void print_ok(void) {
__rusgx_write(1, success_str_buf, success_str_size);
}
static int test_write(const char* file_path) {
int write_fd = __rusgx_open(file_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (write_fd < 0) {
return -1;
}
char write_buf[] = "Hello World!\n";
size_t write_len = sizeof(write_buf);
if (__rusgx_write(write_fd, write_buf, write_len) != write_len) {
return -2;
}
if (__rusgx_close(write_fd) < 0) {
return -3;
}
return 0;
}
static int test_read(const char* file_path) {
int read_fd = __rusgx_open(file_path, O_RDONLY, 0);
if (read_fd < 0) {
return -1;
}
char read_buf[256] = { 0 };
size_t read_len;
if ((read_len = __rusgx_read(read_fd, read_buf, 256)) < 0 ) {
return -2;
}
__rusgx_write(1, read_buf, read_len);
if (__rusgx_close(read_fd) < 0) {
return -3;
}
return 0;
}
void _start(void) {
int ret = 0;
const char* file_path = "tmp.txt.protected";
if ((ret = test_write(file_path)) < 0) {
goto on_exit;
}
if ((ret = test_read(file_path)) < 0) {
goto on_exit;
}
print_ok();
on_exit:
__rusgx_exit(ret);
}

@ -1,4 +0,0 @@
include ../test_common.mk
EXTRA_C_FLAGS := -fno-builtin
EXTRA_LINK_FLAGS := -nostdlib

@ -1,8 +0,0 @@
#include "rusgx_stub.h"
void _start(void) {
int pid = __rusgx_getpid();
(void)pid;
__rusgx_exit(0);
}

@ -1,4 +0,0 @@
include ../test_common.mk
EXTRA_C_FLAGS := -fno-builtin
EXTRA_LINK_FLAGS := -nostdlib

@ -1,9 +0,0 @@
#include "rusgx_stub.h"
char str_buf[] = "Hello World!\n";
unsigned long str_size = sizeof(str_buf);
void _start(void) {
__rusgx_write(1, str_buf, str_size);
__rusgx_exit(0);
}

@ -1,99 +0,0 @@
#ifndef __RUSGX_STUB__
#define __RUSGX_STUB__
#include <stddef.h>
#include <sys/types.h>
/*
* Stub for Rusgx syscalls
*
* Executables built with Rusgx's toolchain are dynamically linked with this
* stub library. This stub library serves two purposes:
*
* 1) Enable Rusgx's syscalls. Since this library is dynamically linked with
* executables, the compile-time linker generates proper dynamic linking
* information. Using this information, the program loader of Rusgx can do
* runtime relocation so that user programs can make syscalls to the library
* OS.
*
* 2) Run without Rusgx. When not running upon Rusgx, the executables can use the
* host syscalls provided by the default implementation of this library.
*/
#define SYS_read 0
#define SYS_write 1
#define SYS_open 2
#define SYS_close 3
#define SYS_getpid 39
#define SYS_exit 60
#define SYS_wait4 61
#define SYS_spawn 360
#define O_RDONLY 0x00000000U
#define O_WRONLY 0x00000001U
#define O_RDWR 0x00000002U
#define O_CREAT 0x00000040U
#define O_EXCL 0x00000080U
#define O_NOCTTY 0x00000100U
#define O_TRUNC 0x00000200U
#define O_APPEND 0x00000400U
#define O_NONBLOCK 0x00000800U
#define O_NDELAY 0x00000800U
#define O_DSYNC 0x00001000U
#define O_DIRECTORY 0x00010000U
#define O_NOFOLLOW 0x00020000U
#define O_CLOEXEC 0x00080000U
#define O_SYNC 0x00101000U
long __occlum_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4);
#define RUSGX_SYSCALL0(num) \
__occlum_syscall((num), (long)0, (long)0, (long)0, (long)0, (long)0)
#define RUSGX_SYSCALL1(num, arg0) \
__occlum_syscall((num), (long)(arg0), (long)0, (long)0, (long)0, (long)0)
#define RUSGX_SYSCALL2(num, arg0, arg1) \
__occlum_syscall((num), (long)(arg0), (long)(arg1), (long)0, (long)0, (long)0)
#define RUSGX_SYSCALL3(num, arg0, arg1, arg2) \
__occlum_syscall((num), (long)(arg0), (long)(arg1), (long)(arg2), (long)0, (long)0)
#define RUSGX_SYSCALL4(num, arg0, arg1, arg2, arg3) \
__occlum_syscall((num), (long)(arg0), (long)(arg1), (long)(arg2), (long)(arg3), (long)0)
#define RUSGX_SYSCALL5(num, arg0, arg1, arg2, arg3, arg4) \
__occlum_syscall((num), (long)(arg0), (long)(arg1), (long)(arg2), (long)(arg3), (long)(arg4))
static inline ssize_t __rusgx_read(int fd, void* buf, unsigned long size) {
return (ssize_t) RUSGX_SYSCALL3(SYS_read, fd, buf, size);
}
static inline ssize_t __rusgx_write(int fd, const void* buf, unsigned long size) {
return (ssize_t) RUSGX_SYSCALL3(SYS_write, fd, buf, size);
}
static inline int __rusgx_open(const void* buf, int flags, int mode) {
return (int) RUSGX_SYSCALL3(SYS_open, buf, flags, mode);
}
static inline int __rusgx_close(int fd) {
return (int) RUSGX_SYSCALL1(SYS_close, fd);
}
static inline unsigned int __rusgx_getpid(void) {
return (unsigned int) RUSGX_SYSCALL0(SYS_getpid);
}
static inline void __rusgx_exit(int status) {
RUSGX_SYSCALL1(SYS_exit, status);
}
static inline int __rusgx_spawn(int* child_pid, const char* path,
const char** argv, const char** envp) {
return (int) RUSGX_SYSCALL4(SYS_spawn, child_pid, path, argv, envp);
}
static inline int __rusgx_wait4(int child_pid, int* status, int options/*, struct rusage* rusage*/) {
return (int) RUSGX_SYSCALL3(SYS_wait4, child_pid, status, options);
}
#endif /* __RUSGX_STUB__ */

@ -1,23 +0,0 @@
C_SRCS := $(wildcard *.c)
S_FILES := $(C_SRCS:%.c=%.S)
C_OBJS := $(C_SRCS:%.c=%.o)
LIB_NAME := librusgx_stub.so
C_FLAGS := -Wall -fno-builtin -fno-stack-protector -fverbose-asm -fpic -I../include
C_FLAGS += -O0
LINK_FLAGS := -nostdlib
.PHONY: all clean
all: $(LIB_NAME)
$(LIB_NAME): $(C_OBJS)
$(CC) $^ $(LINK_FLAGS) -shared -o $(LIB_NAME)
$(C_OBJS): %.o: %.S
$(CC) $(C_FLAGS) -c $< -o $@
$(S_FILES): %.S: %.c
$(CC) $(C_FLAGS) -S $< -o $@
clean:
$(RM) -f *.o *.S $(LIB_NAME)

@ -1,77 +0,0 @@
#include "rusgx_stub.h"
static long __read(int fd, void* buf, unsigned long size) {
long ret;
__asm__ __volatile__ (
"syscall"
: "=a" (ret)
: "0" (SYS_read), "D" (fd), "S" (buf), "d" (size)
: "cc", "rcx", "r11", "memory"
);
return ret;
}
static long __write(int fd, const void* buf, unsigned long size) {
long ret;
__asm__ __volatile__ (
"syscall"
: "=a" (ret)
: "0" (SYS_write), "D" (fd), "S" (buf), "d" (size)
: "cc", "rcx", "r11", "memory"
);
return ret;
}
static long __open(const char* path, int flags, int mode) {
long ret;
__asm__ __volatile__ (
"syscall"
: "=a" (ret)
: "0" (SYS_open), "D" (path), "S" (flags), "d" (mode)
: "cc", "rcx", "r11", "memory"
);
return ret;
}
static long __close(int fd) {
long ret;
__asm__ __volatile__ (
"syscall"
: "=a" (ret)
: "a" (SYS_close), "D" (fd)
: "cc", "rcx", "r11", "memory" );
return ret;
}
static void __exit(int status) {
__asm__ __volatile__ (
"syscall"
:
: "a" (SYS_exit), "D" (status)
: "cc", "rcx", "r11", "memory" );
return;
}
long __occlum_syscall(int num, long arg0, long arg1, long arg2, long arg3, long arg4) {
long ret = 0;
switch (num) {
case SYS_exit:
__exit((int)arg0);
break;
case SYS_read:
ret = __read((int)arg0, (void*)arg1, (unsigned long)arg2);
break;
case SYS_write:
ret = __write((int)arg0, (const void*)arg1, (unsigned long)arg2);
break;
case SYS_open:
ret = __open((const char*)arg0, (int)arg1, (int)arg2);
break;
case SYS_close:
ret = __close((int)arg0);
break;
default:
break;
}
return ret;
}

@ -1,4 +0,0 @@
include ../test_common.mk
EXTRA_C_FLAGS := -fno-builtin
EXTRA_LINK_FLAGS := -nostdlib

@ -1,28 +0,0 @@
#include "rusgx_stub.h"
static char success_str_buf[] = "A child process starts and exits!\n";
static unsigned long success_str_size = sizeof(success_str_buf);
static void print_ok(void) {
__rusgx_write(1, success_str_buf, success_str_size);
}
#define NUM_CHILDREN 10
void _start(void) {
for (int ci = 0; ci < NUM_CHILDREN; ci++) {
int ret = 0;
int pid = 0;
ret = __rusgx_spawn(&pid, "hello_world_raw/bin.encrypted", NULL, NULL);
if (ret < 0) { __rusgx_exit(0); }
int status;
ret = __rusgx_wait4(pid, &status, 0);
if (ret < 0) { __rusgx_exit(0); }
//print_ok();
}
__rusgx_exit(0);
}

@ -3,6 +3,7 @@ INCLUDE_MAKEFILE := $(lastword $(MAKEFILE_LIST))
CUR_DIR := $(shell dirname $(realpath $(MAIN_MAKEFILE))) CUR_DIR := $(shell dirname $(realpath $(MAIN_MAKEFILE)))
PROJECT_DIR := $(realpath $(CUR_DIR)/../../) PROJECT_DIR := $(realpath $(CUR_DIR)/../../)
CC := /usr/local/occlum/bin/musl-gcc
C_SRCS := $(wildcard *.c) C_SRCS := $(wildcard *.c)
S_FILES := $(C_SRCS:%.c=%.S) S_FILES := $(C_SRCS:%.c=%.S)
C_OBJS := $(C_SRCS:%.c=%.o) C_OBJS := $(C_SRCS:%.c=%.o)
@ -11,14 +12,10 @@ BIN_ENC_NAME := bin.encrypted
OBJDUMP_FILE := bin.objdump OBJDUMP_FILE := bin.objdump
READELF_FILE := bin.readelf READELF_FILE := bin.readelf
C_FLAGS = -Wall -fno-stack-protector -fverbose-asm -fpic \ C_FLAGS = -Wall -fverbose-asm -O0 $(EXTRA_C_FLAGS)
-I../include -L../rusgx_stub -lrusgx_stub \ LINK_FLAGS = $(EXTRA_LINK_FLAGS)
-O0 \
$(EXTRA_C_FLAGS)
LINK_FLAGS = -pie -L../rusgx_stub -lrusgx_stub \
$(EXTRA_LINK_FLAGS)
.PHONY: all run run-without-rusgx debug clean .PHONY: all run debug clean
############################################################################# #############################################################################
# Build # Build
@ -55,9 +52,6 @@ $(S_FILES): %.S: %.c
run: $(BIN_ENC_NAME) run: $(BIN_ENC_NAME)
cd ../ && RUST_BACKTRACE=1 ./pal $(CUR_DIR)/$(BIN_ENC_NAME) cd ../ && RUST_BACKTRACE=1 ./pal $(CUR_DIR)/$(BIN_ENC_NAME)
run-without-rusgx:
cd ../ && LD_LIBRARY_PATH=./rusgx_stub/ ./$(BIN_NAME)
############################################################################# #############################################################################
# Misc # Misc
############################################################################# #############################################################################