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 <linux/limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h>
#include <occlum_pal_api.h> #include <occlum_pal_api.h>
//============================================================================ //============================================================================
@ -23,7 +24,7 @@
"The embedded mode makes it possible to build Occlum-based SGX apps " \ "The embedded mode makes it possible to build Occlum-based SGX apps " \
"that comprise of trusted and untrused halves.\n" "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); fprintf(stderr, HELP_MSG, prog_name, prog_name);
} }
@ -31,15 +32,15 @@ static void print_help_msg(const char* prog_name) {
// Main // Main
//============================================================================ //============================================================================
int main(int argc, char* argv[]) { int main(int argc, char *argv[]) {
// Parse arguments // Parse arguments
const char* prog_name = (const char*)argv[0]; const char *prog_name = (const char *)argv[0];
if (argc < 2) { if (argc < 2) {
fprintf(stderr, "error: require one argument\n\n"); fprintf(stderr, "error: require one argument\n\n");
print_help_msg(prog_name); print_help_msg(prog_name);
return EXIT_FAILURE; return EXIT_FAILURE;
} }
const char* total_bytes_str = argv[1]; const char *total_bytes_str = argv[1];
// Init Occlum PAL // Init Occlum PAL
occlum_pal_attr_t pal_attr = OCCLUM_PAL_ATTR_INITVAL; 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}; char shared_buf[1024 * 1024] = {0};
// Prepare cmd path and arguments // 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_ptr_str[32] = {0};
char buf_size_str[32] = {0}; char buf_size_str[32] = {0};
snprintf(buf_ptr_str, sizeof buf_ptr_str, "%lu", (unsigned long) shared_buf); 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); 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_ptr_str, // buf_ptr
buf_size_str, // buf_size buf_size_str, // buf_size
total_bytes_str, // total_bytes total_bytes_str, // total_bytes
NULL 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 // Use Occlum PAL to execute the cmd
int exit_status = 0; 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; return EXIT_FAILURE;
} }

@ -15,7 +15,7 @@
" <buf_size> The size of the untrusted buffer\n" \ " <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" " <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); 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)) #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) { static int copy_into_enclave(const char *src_buf, size_t buf_size, size_t total_bytes) {
char* dst_buf = malloc(buf_size); char *dst_buf = malloc(buf_size);
if (dst_buf == NULL) { if (dst_buf == NULL) {
fprintf(stderr, "ERROR: out of memory"); fprintf(stderr, "ERROR: out of memory");
return -1; return -1;
@ -46,14 +46,14 @@ static int copy_into_enclave(const char* src_buf, size_t buf_size, size_t total_
// Main // Main
//============================================================================ //============================================================================
int main(int argc, char* argv[]) { int main(int argc, char *argv[]) {
// Parse arguments // Parse arguments
const char* prog_name = argv[0]; const char *prog_name = argv[0];
if (argc < 4) { if (argc < 4) {
print_help_msg(prog_name); print_help_msg(prog_name);
return EXIT_FAILURE; 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 buf_size = (size_t) strtoul(argv[2], NULL, 10);
size_t total_bytes = (size_t) strtoul(argv[3], NULL, 10); size_t total_bytes = (size_t) strtoul(argv[3], NULL, 10);
if (buf_ptr == NULL || buf_size == 0 || total_bytes == 0) { 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 // 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", 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 // Time begin
struct timeval time_begin, time_end; struct timeval time_begin, time_end;
@ -79,7 +79,7 @@ int main(int argc, char* argv[]) {
// Calculate the throughput // Calculate the throughput
unsigned long elapsed_us = (time_end.tv_sec - time_begin.tv_sec) * 1000000 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) { if (elapsed_us == 0) {
fprintf(stderr, "ERROR: elapsed time (in us) cannot be zero"); fprintf(stderr, "ERROR: elapsed time (in us) cannot be zero");
print_help_msg(prog_name); print_help_msg(prog_name);

@ -318,29 +318,45 @@ pub struct occlum_stdio_fds {
pub stderr_fd: i32, 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" { 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 args Mandatory input. Arguments for occlum_pal_create_process.
* @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.
* *
* @retval If 0, then success; otherwise, check errno for the exact error type. * @retval If 0, then success; otherwise, check errno for the exact error type.
*/ */
fn occlum_pal_exec( fn occlum_pal_create_process(args: *mut occlum_pal_create_process_args) -> i32;
cmd_path: *const libc::c_char,
cmd_args: *const *const libc::c_char, /*
cmd_env: *const *const libc::c_char, * @brief Execute the process inside the Occlum enclave
io_fds: *const occlum_stdio_fds, *
exit_status: *mut i32, * @param args Mandatory input. Arguments for occlum_pal_exec.
) -> i32; *
* @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 * @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 (cmd_envs_array, _cmd_envs) = vec_strings_to_cchars(envs)?;
let stdio_raw = Box::new(stdio); 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 { let ret = unsafe{occlum_pal_create_process(Box::into_raw(create_process_args))};
occlum_pal_exec( if ret != 0 {
cmd_path.as_ptr() as *const libc::c_char, return Err(ret);
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, let exec_args = Box::new(occlum_pal_exec_args {
exit_status as *mut i32, pid: libos_tid,
) exit_value: exit_status as *mut i32,
}; });
let ret = unsafe {occlum_pal_exec(Box::into_raw(exec_args))};
match ret { match ret {
0 => Ok(()), 0 => Ok(()),

@ -54,6 +54,67 @@ typedef struct occlum_stdio_fds {
int stderr_fd; int stderr_fd;
} occlum_stdio_fds_t; } 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 * @brief Initialize an Occlum enclave
* *
@ -64,29 +125,22 @@ typedef struct occlum_stdio_fds {
int occlum_pal_init(const struct occlum_pal_attr *attr); 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 args Mandatory input. Arguments for occlum_pal_create_process.
* @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.
* *
* @retval If 0, then success; otherwise, check errno for the exact error type. * @retval If 0, then success; otherwise, check errno for the exact error type.
*/ */
int occlum_pal_exec(const char *cmd_path, int occlum_pal_create_process(struct occlum_pal_create_process_args *args);
const char **cmd_args,
const char **cmd_env, /*
const struct occlum_stdio_fds *io_fds, * @brief Execute the process inside the Occlum enclave
int *exit_status); *
* @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 * @brief Send a signal to one or multiple LibOS processes

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

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

@ -47,7 +47,24 @@ int main(int argc, char *argv[]) {
.stderr_fd = STDERR_FILENO, .stderr_fd = STDERR_FILENO,
}; };
int exit_status = 0; 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 // Command not found or other internal errors
return 127; return 127;
} }