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>
//============================================================================
@ -64,9 +65,32 @@ int main(int argc, char* argv[]) {
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;
}

@ -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;
}