Add support for PAL API v2

This commit is contained in:
Hui, Chunyang 2020-05-27 05:44:10 +00:00
parent e6996f3c45
commit 73b4f8b08c
7 changed files with 211 additions and 74 deletions

@ -1,6 +1,7 @@
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <occlum_pal_api.h>
//============================================================================
@ -23,7 +24,7 @@
"The embedded mode makes it possible to build Occlum-based SGX apps " \
"that comprise of trusted and untrused halves.\n"
static void print_help_msg(const char* prog_name) {
static void print_help_msg(const char *prog_name) {
fprintf(stderr, HELP_MSG, prog_name, prog_name);
}
@ -31,15 +32,15 @@ static void print_help_msg(const char* prog_name) {
// Main
//============================================================================
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
// Parse arguments
const char* prog_name = (const char*)argv[0];
const char *prog_name = (const char *)argv[0];
if (argc < 2) {
fprintf(stderr, "error: require one argument\n\n");
print_help_msg(prog_name);
return EXIT_FAILURE;
}
const char* total_bytes_str = argv[1];
const char *total_bytes_str = argv[1];
// Init Occlum PAL
occlum_pal_attr_t pal_attr = OCCLUM_PAL_ATTR_INITVAL;
@ -52,21 +53,44 @@ int main(int argc, char* argv[]) {
char shared_buf[1024 * 1024] = {0};
// Prepare cmd path and arguments
const char* cmd_path = "/bin/trusted_memcpy_bench";
const char *cmd_path = "/bin/trusted_memcpy_bench";
char buf_ptr_str[32] = {0};
char buf_size_str[32] = {0};
snprintf(buf_ptr_str, sizeof buf_ptr_str, "%lu", (unsigned long) shared_buf);
snprintf(buf_size_str, sizeof buf_size_str, "%lu", sizeof shared_buf);
const char* cmd_args[] = {
const char *cmd_args[] = {
buf_ptr_str, // buf_ptr
buf_size_str, // buf_size
total_bytes_str, // total_bytes
NULL
};
struct occlum_stdio_fds io_fds = {
.stdin_fd = STDIN_FILENO,
.stdout_fd = STDOUT_FILENO,
.stderr_fd = STDERR_FILENO,
};
// Use Occlum PAL to create new process
int libos_tid = 0;
struct occlum_pal_create_process_args create_process_args = {
.path = cmd_path,
.argv = cmd_args,
.env = NULL,
.stdio = (const struct occlum_stdio_fds *) &io_fds,
.pid = &libos_tid,
};
if (occlum_pal_create_process(&create_process_args) < 0) {
return EXIT_FAILURE;
}
// Use Occlum PAL to execute the cmd
int exit_status = 0;
if (occlum_pal_exec(cmd_path, cmd_args, NULL, &exit_status) < 0) {
struct occlum_pal_exec_args exec_args = {
.pid = libos_tid,
.exit_value = &exit_status,
};
if (occlum_pal_exec(&exec_args) < 0) {
return EXIT_FAILURE;
}

@ -15,7 +15,7 @@
" <buf_size> The size of the untrusted buffer\n" \
" <total_bytes> The total number of bytes to copy from the buffer into the enclave\n"
static void print_help_msg(const char* prog_name) {
static void print_help_msg(const char *prog_name) {
fprintf(stderr, HELP_MSG, prog_name);
}
@ -25,8 +25,8 @@ static void print_help_msg(const char* prog_name) {
#define MIN(x, y) ((x) <= (y) ? (x) : (y))
static int copy_into_enclave(const char* src_buf, size_t buf_size, size_t total_bytes) {
char* dst_buf = malloc(buf_size);
static int copy_into_enclave(const char *src_buf, size_t buf_size, size_t total_bytes) {
char *dst_buf = malloc(buf_size);
if (dst_buf == NULL) {
fprintf(stderr, "ERROR: out of memory");
return -1;
@ -46,14 +46,14 @@ static int copy_into_enclave(const char* src_buf, size_t buf_size, size_t total_
// Main
//============================================================================
int main(int argc, char* argv[]) {
int main(int argc, char *argv[]) {
// Parse arguments
const char* prog_name = argv[0];
const char *prog_name = argv[0];
if (argc < 4) {
print_help_msg(prog_name);
return EXIT_FAILURE;
}
const char* buf_ptr = (const char*) strtoul(argv[1], NULL, 10);
const char *buf_ptr = (const char *) strtoul(argv[1], NULL, 10);
size_t buf_size = (size_t) strtoul(argv[2], NULL, 10);
size_t total_bytes = (size_t) strtoul(argv[3], NULL, 10);
if (buf_ptr == NULL || buf_size == 0 || total_bytes == 0) {
@ -63,7 +63,7 @@ int main(int argc, char* argv[]) {
// Benchmark memcpy from outside the enclave to inside the enclave
printf("Start copying data from the given buffer (ptr = %p, len = %lu) for a total of %lu bytes...\n",
buf_ptr, buf_size, total_bytes);
buf_ptr, buf_size, total_bytes);
// Time begin
struct timeval time_begin, time_end;
@ -79,7 +79,7 @@ int main(int argc, char* argv[]) {
// Calculate the throughput
unsigned long elapsed_us = (time_end.tv_sec - time_begin.tv_sec) * 1000000
+ (time_end.tv_usec - time_begin.tv_usec);
+ (time_end.tv_usec - time_begin.tv_usec);
if (elapsed_us == 0) {
fprintf(stderr, "ERROR: elapsed time (in us) cannot be zero");
print_help_msg(prog_name);

@ -318,29 +318,45 @@ pub struct occlum_stdio_fds {
pub stderr_fd: i32,
}
/*
* The struct which consists of arguments needed by occlum_pal_create_process
*/
#[repr(C)]
pub struct occlum_pal_create_process_args {
pub path: *const libc::c_char,
pub argv: *const *const libc::c_char,
pub env: *const *const libc::c_char,
pub stdio: *const occlum_stdio_fds,
pub pid: *mut i32,
}
/*
* The struct which consists of arguments needed by occlum_pal_exec
*/
#[repr(C)]
pub struct occlum_pal_exec_args {
pub pid: i32,
pub exit_value: *mut i32,
}
extern "C" {
/*
* @brief Execute a command inside the Occlum enclave
* @brief Create a new process inside the Occlum enclave
*
* @param cmd_path The path of the command to be executed
* @param cmd_args The arguments to the command. The array must be NULL
* terminated.
* @param io_fds The file descriptors of the redirected standard I/O
* (i.e., stdin, stdout, stderr), If set to NULL, will
* use the original standard I/O file descriptors.
* @param exit_status Output. The exit status of the command. Note that the
* exit status is returned if and only if the function
* succeeds.
* @param args Mandatory input. Arguments for occlum_pal_create_process.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
fn occlum_pal_exec(
cmd_path: *const libc::c_char,
cmd_args: *const *const libc::c_char,
cmd_env: *const *const libc::c_char,
io_fds: *const occlum_stdio_fds,
exit_status: *mut i32,
) -> i32;
fn occlum_pal_create_process(args: *mut occlum_pal_create_process_args) -> i32;
/*
* @brief Execute the process inside the Occlum enclave
*
* @param args Mandatory input. Arguments for occlum_pal_exec.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
fn occlum_pal_exec(args: *mut occlum_pal_exec_args) -> i32;
/*
* @brief Send a signal to one or multiple LibOS processes
@ -381,16 +397,26 @@ fn rust_occlum_pal_exec(
let (cmd_envs_array, _cmd_envs) = vec_strings_to_cchars(envs)?;
let stdio_raw = Box::new(stdio);
let mut libos_tid = 0;
let create_process_args = Box::new(occlum_pal_create_process_args {
path: cmd_path.as_ptr() as *const libc::c_char,
argv: Box::into_raw(cmd_args_array.into_boxed_slice()) as *const *const libc::c_char,
env: Box::into_raw(cmd_envs_array.into_boxed_slice()) as *const *const libc::c_char,
stdio: *stdio_raw,
pid: &mut libos_tid as *mut i32,
});
let ret = unsafe {
occlum_pal_exec(
cmd_path.as_ptr() as *const libc::c_char,
Box::into_raw(cmd_args_array.into_boxed_slice()) as *const *const libc::c_char,
Box::into_raw(cmd_envs_array.into_boxed_slice()) as *const *const libc::c_char,
*stdio_raw,
exit_status as *mut i32,
)
};
let ret = unsafe{occlum_pal_create_process(Box::into_raw(create_process_args))};
if ret != 0 {
return Err(ret);
}
let exec_args = Box::new(occlum_pal_exec_args {
pid: libos_tid,
exit_value: exit_status as *mut i32,
});
let ret = unsafe {occlum_pal_exec(Box::into_raw(exec_args))};
match ret {
0 => Ok(()),

@ -54,6 +54,67 @@ typedef struct occlum_stdio_fds {
int stderr_fd;
} occlum_stdio_fds_t;
/*
* The struct which consists of arguments needed by occlum_pal_create_process
*/
struct occlum_pal_create_process_args {
// Path to new process.
//
// The path of the command which will be created as a new process.
//
// Mandatory field. Must not be NULL.
const char *path;
// Argments array pass to new process.
//
// The arguments to the command. The array must be NULL terminated.
//
// Mandatory field. Must not be NULL.
const char **argv;
// Untrusted environment variable array pass to new process.
//
// The untrusted env vars to the command. The array must be NULL terminated.
//
// Optional field.
const char **env;
// File descriptors of the redirected standard I/O (i.e., stdin, stdout, stderr)
//
// If set to NULL, will use the original standard I/O file descriptors.
//
// Optional field.
const struct occlum_stdio_fds *stdio;
// Output. Pid of new process in libos.
//
// If occlum_pal_create_process returns success, pid of the new process will
// be updated.
//
// Mandatory field. Must not be NULL.
int *pid;
};
/*
* The struct which consists of arguments needed by occlum_pal_exec
*/
struct occlum_pal_exec_args {
// Pid of new process created with occlum_pal_create_process.
//
// Mandatory field.
int pid;
// Output. The exit status of the command. The semantic of
// this value follows the one described in wait(2) man
// page. For example, if the program terminated normally,
// then WEXITSTATUS(exit_status) gives the value returned
// from a main function.
//
// Mandatory field. Must not be NULL.
int *exit_value;
};
/*
* @brief Initialize an Occlum enclave
*
@ -64,29 +125,22 @@ typedef struct occlum_stdio_fds {
int occlum_pal_init(const struct occlum_pal_attr *attr);
/*
* @brief Execute a command inside the Occlum enclave
* @brief Create a new process inside the Occlum enclave
*
* @param cmd_path The path of the command to be executed
* @param cmd_args The arguments to the command. The array must be NULL
* terminated.
* @param cmd_env The untrusted env vars to the command. The array must
* be NULL terminated.
* @param io_fds The file descriptors of the redirected standard I/O
* (i.e., stdin, stdout, stderr), If set to NULL, will
* use the original standard I/O file descriptors.
* @param exit_status Output. The exit status of the command. The semantic of
* this value follows the one described in wait(2) man
* page. For example, if the program terminated normally,
* then WEXITSTATUS(exit_status) gives the value returned
* from a main function.
* @param args Mandatory input. Arguments for occlum_pal_create_process.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
int occlum_pal_exec(const char *cmd_path,
const char **cmd_args,
const char **cmd_env,
const struct occlum_stdio_fds *io_fds,
int *exit_status);
int occlum_pal_create_process(struct occlum_pal_create_process_args *args);
/*
* @brief Execute the process inside the Occlum enclave
*
* @param args Mandatory input. Arguments for occlum_pal_exec.
*
* @retval If 0, then success; otherwise, check errno for the exact error type.
*/
int occlum_pal_exec(struct occlum_pal_exec_args *args);
/*
* @brief Send a signal to one or multiple LibOS processes

@ -2,6 +2,7 @@
global:
occlum_pal_get_version;
occlum_pal_init;
occlum_pal_create_process;
occlum_pal_exec;
occlum_pal_kill;
occlum_pal_destroy;

@ -50,14 +50,11 @@ int occlum_pal_init(const struct occlum_pal_attr *attr) {
return 0;
}
int occlum_pal_exec(const char *cmd_path,
const char **cmd_args,
const char **cmd_env,
const struct occlum_stdio_fds *io_fds,
int *exit_status) {
errno = 0;
int occlum_pal_create_process(struct occlum_pal_create_process_args *args) {
int ecall_ret = 0; // libos_tid
if (cmd_path == NULL || cmd_args == NULL || exit_status == NULL) {
errno = 0;
if (args->path == NULL || args->argv == NULL || args->pid == NULL) {
errno = EINVAL;
return -1;
}
@ -69,9 +66,8 @@ int occlum_pal_exec(const char *cmd_path,
return -1;
}
int ecall_ret = 0; // libos_tid
sgx_status_t ecall_status = occlum_ecall_new_process(eid, &ecall_ret, cmd_path, cmd_args,
cmd_env, io_fds);
sgx_status_t ecall_status = occlum_ecall_new_process(eid, &ecall_ret, args->path,
args->argv, args->env, args->stdio);
if (ecall_status != SGX_SUCCESS) {
const char *sgx_err = pal_get_sgx_error_msg(ecall_status);
PAL_ERROR("Failed to do ECall: %s", sgx_err);
@ -83,9 +79,28 @@ int occlum_pal_exec(const char *cmd_path,
return -1;
}
int libos_tid = ecall_ret;
*args->pid = ecall_ret;
return 0;
}
int occlum_pal_exec(struct occlum_pal_exec_args *args) {
int host_tid = gettid();
ecall_status = occlum_ecall_exec_thread(eid, &ecall_ret, libos_tid, host_tid);
int ecall_ret = 0;
if (args->exit_value == NULL) {
errno = EINVAL;
return -1;
}
sgx_enclave_id_t eid = pal_get_enclave_id();
if (eid == SGX_INVALID_ENCLAVE_ID) {
PAL_ERROR("Enclave is not initialized yet.");
errno = ENOENT;
return -1;
}
sgx_status_t ecall_status = occlum_ecall_exec_thread(eid, &ecall_ret, args->pid,
host_tid);
if (ecall_status != SGX_SUCCESS) {
const char *sgx_err = pal_get_sgx_error_msg(ecall_status);
PAL_ERROR("Failed to do ECall: %s", sgx_err);
@ -97,7 +112,7 @@ int occlum_pal_exec(const char *cmd_path,
return -1;
}
*exit_status = ecall_ret;
*args->exit_value = ecall_ret;
return 0;
}

@ -47,7 +47,24 @@ int main(int argc, char *argv[]) {
.stderr_fd = STDERR_FILENO,
};
int exit_status = 0;
if (occlum_pal_exec(cmd_path, cmd_args, environ, &io_fds, &exit_status) < 0) {
int libos_tid = 0;
struct occlum_pal_create_process_args create_process_args = {
.path = cmd_path,
.argv = cmd_args,
.env = environ,
.stdio = (const struct occlum_stdio_fds *) &io_fds,
.pid = &libos_tid,
};
if (occlum_pal_create_process(&create_process_args) < 0) {
// Command not found or other internal errors
return 127;
}
struct occlum_pal_exec_args exec_args = {
.pid = libos_tid,
.exit_value = &exit_status,
};
if (occlum_pal_exec(&exec_args) < 0) {
// Command not found or other internal errors
return 127;
}