diff --git a/src/enclave/enclave_event_channel.c b/src/enclave/enclave_event_channel.c index 875138741..0ae66e9bb 100644 --- a/src/enclave/enclave_event_channel.c +++ b/src/enclave/enclave_event_channel.c @@ -19,9 +19,7 @@ static struct ticketlock** evt_chn_lock; struct lthread** vio_tasks = NULL; /* Event channel configuration */ -static enc_dev_config_t* _enc_dev_config = NULL; static bool _event_channel_initialized = false; -static uint8_t _evt_channel_num; static _Atomic(bool) _vio_terminate = false; @@ -55,10 +53,16 @@ static inline void vio_wait_for_host_event( */ static inline int vio_signal_evt_channel(uint8_t dev_id) { - enc_evt_channel_t* evt_channel = _enc_dev_config[dev_id].enc_evt_chn; - evt_t* processed = &_enc_dev_config[dev_id].evt_processed; + enc_dev_config_t* enc_dev_config = + sgxlkl_enclave_state.shared_memory.enc_dev_config; + enc_evt_channel_t* evt_channel = enc_dev_config[dev_id].enc_evt_chn; + evt_t* processed = + &sgxlkl_enclave_state.event_channel_state[dev_id].evt_processed; evt_t* evt_chn = &evt_channel->enclave_evt_channel; + sgxlkl_ensure_outside(evt_channel, sizeof(enc_evt_channel_t)); + sgxlkl_ensure_outside(evt_chn, sizeof(evt_t)); + evt_t cur = __atomic_load_n(evt_chn, __ATOMIC_SEQ_CST); struct lthread* lt = vio_tasks[dev_id]; @@ -83,14 +87,17 @@ static void vio_enclave_process_host_event(uint8_t* param) lthread_set_funcname(lthread_self(), thread_name); lthread_detach(); - /* release memory after extracting dev_id */ - oe_free(param); - - enc_evt_channel_t* evt_channel = _enc_dev_config[dev_id].enc_evt_chn; - evt_t* evt_processed = &_enc_dev_config[dev_id].evt_processed; + enc_dev_config_t* enc_dev_config = + sgxlkl_enclave_state.shared_memory.enc_dev_config; + enc_evt_channel_t* evt_channel = enc_dev_config[dev_id].enc_evt_chn; + evt_t* evt_processed = + &sgxlkl_enclave_state.event_channel_state[dev_id].evt_processed; evt_t* evt_chn = &evt_channel->enclave_evt_channel; evt_t cur = 0, new = 0; + sgxlkl_ensure_outside(evt_channel, sizeof(enc_evt_channel_t)); + sgxlkl_ensure_outside(evt_chn, sizeof(evt_t)); + for (;;) { if (_vio_terminate) @@ -130,42 +137,46 @@ static void vio_enclave_process_host_event(uint8_t* param) /* * Function to initialize enclave event handler */ -void initialize_enclave_event_channel( - enc_dev_config_t* enc_dev_config, - size_t evt_channel_num) +void initialize_enclave_event_channels(void) { - uint8_t* dev_id = NULL; - _evt_channel_num = evt_channel_num; + enc_dev_config_t* enc_dev_config = + sgxlkl_enclave_state.shared_memory.enc_dev_config; + + const size_t _num_channels = sgxlkl_enclave_state.num_event_channel_state; + SGXLKL_ASSERT(SIZE_MAX / sizeof(enc_dev_config_t) >= _num_channels); + sgxlkl_ensure_inside( + enc_dev_config, sizeof(enc_dev_config_t) * _num_channels); evt_chn_lock = (struct ticketlock**)oe_calloc_or_die( - evt_channel_num, + _num_channels, sizeof(struct ticketlock*), "Could not allocate memory for evt_chn_lock\n"); vio_tasks = (struct lthread**)oe_calloc_or_die( - evt_channel_num, + _num_channels, sizeof(struct lthread*), "Could not allocate memory for vio_tasks\n"); - _enc_dev_config = enc_dev_config; - for (int i = 0; i < evt_channel_num; i++) + for (int i = 0; i < _num_channels; i++) { + const enc_dev_config_t* ed_conf_i = &enc_dev_config[i]; + const enc_evt_channel_t* ee_chan_i = ed_conf_i->enc_evt_chn; + sgxlkl_ensure_inside(ed_conf_i, sizeof(enc_dev_config_t)); + sgxlkl_ensure_outside(ee_chan_i, sizeof(enc_evt_channel_t)); + sgxlkl_ensure_outside(ee_chan_i->host_evt_channel, sizeof(evt_t)); + sgxlkl_ensure_outside(ee_chan_i->qidx_p, sizeof(uint32_t)); + evt_chn_lock[i] = (struct ticketlock*)oe_calloc_or_die( 1, sizeof(struct ticketlock), "Could not allocate memory for evt_chn_lock[%i]\n", i); - dev_id = (uint8_t*)oe_calloc_or_die( - 1, sizeof(uint8_t), "Could not allocate memory for dev_id\n"); - - *dev_id = enc_dev_config[i].dev_id; - if (lthread_create( &vio_tasks[i], NULL, vio_enclave_process_host_event, - (void*)dev_id) != 0) + (void*)&ed_conf_i->dev_id) != 0) { oe_free(vio_tasks); sgxlkl_fail("Failed to create lthread for event channel\n"); @@ -185,11 +196,17 @@ void vio_terminate() */ void vio_enclave_notify_enclave_event(uint8_t dev_id, uint32_t qidx) { - enc_evt_channel_t* evt_chn = _enc_dev_config[dev_id].enc_evt_chn; + enc_dev_config_t* enc_dev_config = + sgxlkl_enclave_state.shared_memory.enc_dev_config; + enc_evt_channel_t* evt_chn = enc_dev_config[dev_id].enc_evt_chn; uint32_t* qidx_p = evt_chn->qidx_p; + evt_t* host_evt_chn = evt_chn->host_evt_channel; + + sgxlkl_ensure_outside(evt_chn, sizeof(enc_evt_channel_t)); + sgxlkl_ensure_outside(qidx_p, sizeof(uint32_t)); + sgxlkl_ensure_outside(host_evt_chn, sizeof(evt_t)); - evt_t cur = - __atomic_fetch_add(evt_chn->host_evt_channel, 2, __ATOMIC_SEQ_CST); + evt_t cur = __atomic_fetch_add(host_evt_chn, 2, __ATOMIC_SEQ_CST); *qidx_p = qidx; @@ -204,13 +221,14 @@ void vio_enclave_notify_enclave_event(uint8_t dev_id, uint32_t qidx) int vio_enclave_wakeup_event_channel(void) { int ret = 0; + const size_t _num_channels = sgxlkl_enclave_state.num_event_channel_state; /* Event channel processing not available or terminating */ if (!_event_channel_initialized || _vio_terminate) return 0; /* Schedule picks up the available event channel processing */ - for (uint8_t dev_id = 0; dev_id < _evt_channel_num; dev_id++) + for (uint8_t dev_id = 0; dev_id < _num_channels; dev_id++) { if (ticket_trylock(evt_chn_lock[dev_id])) continue; diff --git a/src/enclave/enclave_init.c b/src/enclave/enclave_init.c index 4c1df4805..f4e671ec9 100644 --- a/src/enclave/enclave_init.c +++ b/src/enclave/enclave_init.c @@ -55,7 +55,8 @@ static void find_and_mount_disks() for (int j = 0; j < shm->num_virtio_blk_dev && !found; j++) { if (oe_strcmp( - cfg_disk->destination, shm->virtio_blk_dev_names[j]) == 0) + cfg_disk->destination, estate->virtio_blk_dev_names[j]) == + 0) { estate->disk_state[i + 1].host_disk_index = j; found = true; diff --git a/src/enclave/enclave_oe.c b/src/enclave/enclave_oe.c index 6d3622eff..5989f9d54 100644 --- a/src/enclave/enclave_oe.c +++ b/src/enclave/enclave_oe.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "openenclave/corelibc/oestring.h" @@ -12,6 +13,7 @@ #include "enclave/enclave_util.h" #include "enclave/lthread.h" #include "enclave/lthread_int.h" +#include "lkl/virtio.h" #include "shared/env.h" #include "shared/timer_dev.h" @@ -104,32 +106,8 @@ static void _prepare_elf_stack() sgxlkl_enclave_state_t* state = &sgxlkl_enclave_state; const sgxlkl_enclave_config_t* cfg = state->config; - size_t num_imported_env = 0; - const char** imported_env = NULL; - - if (sgxlkl_enclave_state.shared_memory.env && cfg->num_host_import_env > 0) - { - imported_env = oe_calloc_or_die( - cfg->num_host_import_env, - sizeof(char*), - "Could not allocate memory for imported host environment\n"); - - for (size_t i = 0; i < cfg->num_host_import_env; i++) - { - const char* name = cfg->host_import_env[i]; - for (char* const* p = sgxlkl_enclave_state.shared_memory.env; - p && *p != NULL; - p++) - { - size_t n = oe_strlen(name); - if (_strncmp(name, *p, n) == 0 && (*p)[n] == '=') - { - const char* str = *p; - imported_env[num_imported_env++] = str; - } - } - } - } + size_t num_imported_env = state->num_env_imported; + char* const* imported_env = state->env_imported; size_t num_bytes = 0; size_t num_ptrs = 0; @@ -191,8 +169,6 @@ static void _prepare_elf_stack() SGXLKL_ASSERT(j + 1 == num_ptrs); SGXLKL_ASSERT(out[j] == NULL); SGXLKL_ASSERT(out[j - 4] == (char*)AT_HW_MODE); - - oe_free(imported_env); } static void _free_elf_stack() @@ -306,30 +282,81 @@ static void _read_eeid_config() sgxlkl_enclave_state.config = cfg; } +void sgxlkl_ensure_inside(const void* ptr, size_t sz) +{ + oe_lfence(); + if (ptr != NULL && !oe_is_within_enclave(ptr, sz)) + sgxlkl_fail("Unexpected: buffer is not in enclave memory.\n"); +} + +void sgxlkl_ensure_outside(const void* ptr, size_t sz) +{ + oe_lfence(); + if (ptr != NULL && !oe_is_outside_enclave(ptr, sz)) + sgxlkl_fail("Unexpected: buffer is in enclave memory.\n"); +} + static void _copy_shared_memory(const sgxlkl_shared_memory_t* host) { const sgxlkl_enclave_config_t* cfg = sgxlkl_enclave_state.config; - /* Deep copy where necessary */ + /* The host shared memory struct has been copied by OE (but not its + * contents). */ + sgxlkl_ensure_inside(host, sizeof(sgxlkl_shared_memory_t)); - sgxlkl_shared_memory_t* enc = &sgxlkl_enclave_state.shared_memory; - memset(enc, 0, sizeof(sgxlkl_shared_memory_t)); + /* Temporary, volatile copy to make sure checks aren't reordered */ + volatile sgxlkl_shared_memory_t* enc = oe_calloc_or_die( + 1, + sizeof(sgxlkl_shared_memory_t), + "Could not allocate memory for shared memory\n"); if (cfg->io.network) + { enc->virtio_net_dev_mem = host->virtio_net_dev_mem; + sgxlkl_ensure_outside( + enc->virtio_net_dev_mem, sizeof(struct virtio_dev)); + } if (cfg->io.console) + { enc->virtio_console_mem = host->virtio_console_mem; + sgxlkl_ensure_outside( + enc->virtio_console_mem, sizeof(struct virtio_dev)); + } - enc->evt_channel_num = host->evt_channel_num; - /* enc_dev_config is required to be outside the enclave */ - enc->enc_dev_config = host->enc_dev_config; + size_t num_channels = host->num_evt_channel; + if (num_channels > 0) + { + _Static_assert( + sizeof(enc_dev_config_t) == 16UL, + "enc_dev_config_t size has changed"); + + _Static_assert( + sizeof(enc_dev_state_t) == 8UL, "enc_dev_state_t size has changed"); + + enc->num_evt_channel = num_channels; + enc->enc_dev_config = oe_calloc_or_die( + num_channels, + sizeof(enc_dev_config_t), + "Could not allocate memory for event channel config\n"); + + for (size_t i = 0; i < num_channels; i++) + { + const enc_dev_config_t* host_conf_i = &host->enc_dev_config[i]; + enc_dev_config_t* enc_conf_i = &enc->enc_dev_config[i]; + enc_conf_i->dev_id = host_conf_i->dev_id; + enc_conf_i->enc_evt_chn = host_conf_i->enc_evt_chn; + sgxlkl_ensure_outside( + enc_conf_i->enc_evt_chn, sizeof(enc_evt_channel_t)); + } + } enc->virtio_swiotlb = host->virtio_swiotlb; enc->virtio_swiotlb_size = host->virtio_swiotlb_size; + sgxlkl_ensure_outside(enc->virtio_swiotlb, enc->virtio_swiotlb_size); - /* timer_dev_mem is required to be outside the enclave */ enc->timer_dev_mem = host->timer_dev_mem; + sgxlkl_ensure_outside(enc->timer_dev_mem, sizeof(struct timer_dev)); if (cfg->io.block) { @@ -337,38 +364,133 @@ static void _copy_shared_memory(const sgxlkl_shared_memory_t* host) enc->virtio_blk_dev_mem = oe_calloc_or_die( enc->num_virtio_blk_dev, - sizeof(void*), + sizeof(struct virtio_dev*), "Could not allocate memory for virtio block devices\n"); - enc->virtio_blk_dev_names = oe_calloc_or_die( + for (size_t i = 0; i < enc->num_virtio_blk_dev; i++) + { + enc->virtio_blk_dev_mem[i] = host->virtio_blk_dev_mem[i]; + sgxlkl_ensure_outside( + enc->virtio_blk_dev_mem[i], sizeof(struct virtio_dev)); + } + + size_t names_length = host->virtio_blk_dev_names_length; + sgxlkl_ensure_outside(host->virtio_blk_dev_names, names_length); + char* names_tmp = oe_calloc_or_die( + names_length, + sizeof(char), + "Could not allocate temporary memory for block device names\n"); + oe_memcpy_s( + names_tmp, names_length, host->virtio_blk_dev_names, names_length); + + if (names_tmp[names_length - 1] != '\0') + sgxlkl_fail("unterminated virtio block device name\n"); + + char** name_array_tmp = oe_calloc_or_die( enc->num_virtio_blk_dev, sizeof(char*), - "Could not allocate memory for virtio block devices\n"); + "Could not allocate temporary memory for block device name " + "array\n"); + + sgxlkl_enclave_state.virtio_blk_dev_names = oe_calloc_or_die( + enc->num_virtio_blk_dev, + sizeof(char*), + "Could not allocate memory for virtio block device names\n"); + const char* name_p = names_tmp; for (size_t i = 0; i < enc->num_virtio_blk_dev; i++) { - enc->virtio_blk_dev_mem[i] = host->virtio_blk_dev_mem[i]; - const char* name = host->virtio_blk_dev_names[i]; - size_t name_len = oe_strlen(name) + 1; - enc->virtio_blk_dev_names[i] = oe_calloc_or_die( - name_len, - sizeof(char), - "Could not allocate memory for virtio block device name\n"); - memcpy(enc->virtio_blk_dev_names[i], name, name_len); + name_array_tmp[i] = oe_strdup(name_p); + name_p += oe_strlen(name_p) + 1; } + free(names_tmp); + sgxlkl_enclave_state.virtio_blk_dev_names = name_array_tmp; } - if (host->env) + /* Import environment variables from the host */ + const char* henv = host->env; + size_t henv_len = host->env_length; + if (cfg->num_host_import_env && cfg->host_import_env && henv && henv_len) { - size_t henvc = 0; - while (host->env[henvc++] != 0) - ; + sgxlkl_ensure_outside(henv, sizeof(char) * henv_len); + + char* henv_copy = oe_calloc_or_die( + henv_len, + sizeof(char), + "Could not allocate memory for host-imported environment variable " + "copy."); + oe_memcpy_s(henv_copy, henv_len, henv, henv_len); + + size_t num_vars = 0; + for (size_t i = 0; i < henv_len; i++) + if (henv_copy[i] == '\0') + num_vars++; + char** tmp = oe_calloc_or_die( - henvc + 1, + num_vars, sizeof(char*), - "Could not allocate memory for host import environment variable\n"); - for (size_t i = 0; i < henvc; i++) - tmp[i] = oe_strdup(host->env[i]); - tmp[henvc] = NULL; - enc->env = tmp; + "Could not allocate memory for host-imported environment " + "variables\n"); + + /* Import only those variable settings that are specified to be imported + * in cfg->host_import_env and ignore the others. */ + size_t begin = 0; + sgxlkl_enclave_state.num_env_imported = 0; + for (size_t i = 0; i < henv_len; i++) + { + if (henv_copy[i] == '\0') + { + const char* henv_i = henv_copy + begin; + size_t henv_i_len = i - begin; + + /* Find setting in cfg->host_import_env */ + for (size_t j = 0; j < cfg->num_host_import_env; j++) + { + const char* name = cfg->host_import_env[j]; + size_t name_len = oe_strlen(name); + if (name_len + 1 < henv_i_len && + _strncmp(name, henv_i, name_len) == 0 && + henv_i[name_len] == '=') + { + tmp[sgxlkl_enclave_state.num_env_imported++] = + oe_strdup(henv_i); + } + } + + begin = i + 1; + } + } + + if (sgxlkl_enclave_state.num_env_imported == 0) + oe_free(tmp); + else + sgxlkl_enclave_state.env_imported = tmp; + + /* Shared memory not needed anymore. */ + sgxlkl_enclave_state.shared_memory.env = NULL; + sgxlkl_enclave_state.shared_memory.env_length = 0; + oe_free((char*)henv_copy); + } + + /* Commit to the temporary copy */ + sgxlkl_enclave_state.shared_memory = *enc; + oe_free((sgxlkl_shared_memory_t*)enc); +} + +static void _init_event_channel_state(void) +{ + const sgxlkl_shared_memory_t* shm = &sgxlkl_enclave_state.shared_memory; + size_t num_channels = shm->num_evt_channel; + + sgxlkl_enclave_state.event_channel_state = oe_calloc_or_die( + num_channels, + sizeof(enc_dev_state_t), + "Could not allocate memory for event channel state\n"); + + sgxlkl_enclave_state.num_event_channel_state = num_channels; + for (size_t i = 0; i < num_channels; i++) + { + enc_dev_state_t* enc_state_i = + &sgxlkl_enclave_state.event_channel_state[i]; + enc_state_i->evt_processed = 0; } } @@ -376,22 +498,26 @@ static void _free_shared_memory() { sgxlkl_shared_memory_t* shm = &sgxlkl_enclave_state.shared_memory; - for (size_t i = 0; i < shm->num_virtio_blk_dev; i++) - oe_free(shm->virtio_blk_dev_names[i]); + for (size_t i = 0; i < shm->num_evt_channel; i++) + { + if (shm->enc_dev_config[i].enc_evt_chn) + { + oe_free(shm->enc_dev_config[i].enc_evt_chn->host_evt_channel); + oe_free(shm->enc_dev_config[i].enc_evt_chn->qidx_p); + oe_free(shm->enc_dev_config[i].enc_evt_chn); + } + } + oe_free(shm->enc_dev_config); oe_free(shm->virtio_blk_dev_mem); - oe_free(shm->virtio_blk_dev_names); - - for (size_t i = 0; shm->env[i] != 0; i++) - oe_free(shm->env[i]); - oe_free((char**)shm->env); } int sgxlkl_enclave_init(const sgxlkl_shared_memory_t* shared_memory) { - SGXLKL_ASSERT(shared_memory); + SGXLKL_ASSERT(shared_memory && !sgxlkl_enclave_state.initialized); memset(&sgxlkl_enclave_state, 0, sizeof(sgxlkl_enclave_state)); + sgxlkl_enclave_state.initialized = true; sgxlkl_enclave_state.libc_state = libc_not_started; #ifdef DEBUG @@ -402,6 +528,7 @@ int sgxlkl_enclave_init(const sgxlkl_shared_memory_t* shared_memory) _read_eeid_config(); _copy_shared_memory(shared_memory); + _init_event_channel_state(); #ifdef DEBUG // Initialise verbosity setting, so SGXLKL_VERBOSE can be used from this @@ -438,6 +565,7 @@ int sgxlkl_enclave_init(const sgxlkl_shared_memory_t* shared_memory) void sgxlkl_free_enclave_state() { sgxlkl_enclave_state_t* state = &sgxlkl_enclave_state; + size_t num_blk_devs = state->shared_memory.num_virtio_blk_dev; state->elf64_stack.argc = 0; oe_free(state->elf64_stack.argv); /* includes envp/auxv */ @@ -448,6 +576,17 @@ void sgxlkl_free_enclave_state() state->libc_state = libc_not_started; _free_shared_memory(); + + state->num_event_channel_state = 0; + oe_free(state->event_channel_state); + + for (size_t i = 0; i < num_blk_devs; i++) + oe_free(state->virtio_blk_dev_names[i]); + oe_free((char**)state->virtio_blk_dev_names); + + for (size_t i = 0; i < state->num_env_imported; i++) + oe_free(state->env_imported[i]); + oe_free((void*)state->env_imported); } void sgxlkl_debug_dump_stack_traces(void) diff --git a/src/enclave/enclave_timer.c b/src/enclave/enclave_timer.c index 583e57365..af6ed2e7d 100644 --- a/src/enclave/enclave_timer.c +++ b/src/enclave/enclave_timer.c @@ -28,7 +28,9 @@ _Atomic(uint64_t) internal_counter = 0; */ uint64_t enclave_nanos() { - uint64_t e = sgxlkl_enclave_state.shared_memory.timer_dev_mem->nanos; + struct timer_dev* t = sgxlkl_enclave_state.shared_memory.timer_dev_mem; + + uint64_t e = t->nanos; uint64_t i = internal_counter; if (e > i) { diff --git a/src/host_interface/virtio_blkdev.c b/src/host_interface/virtio_blkdev.c index e62c15db2..c0f32c7bd 100644 --- a/src/host_interface/virtio_blkdev.c +++ b/src/host_interface/virtio_blkdev.c @@ -163,8 +163,6 @@ int blk_device_init( sgxlkl_host_state.shared_memory.virtio_blk_dev_mem[disk_index] = &host_blk_device->dev; - sgxlkl_host_state.shared_memory.virtio_blk_dev_names[disk_index] = - strdup(disk->root_config ? "/" : disk->mount_config->destination); return 0; } diff --git a/src/include/enclave/enclave_state.h b/src/include/enclave/enclave_state.h index f5c60103c..b6eea5407 100644 --- a/src/include/enclave/enclave_state.h +++ b/src/include/enclave/enclave_state.h @@ -31,8 +31,16 @@ typedef struct char* data; /* Buffer that holds all strings on the stack */ } elf64_stack_t; +/* State of event channels */ +typedef struct enc_dev_state +{ + evt_t evt_processed; +} enc_dev_state_t; + typedef struct sgxlkl_enclave_state { + _Atomic(bool) initialized; + const sgxlkl_enclave_config_t* config; /* Flattened ELF64 process stack */ @@ -53,6 +61,17 @@ typedef struct sgxlkl_enclave_state /* This flag is used by the tracing macros */ bool verbose; + + /* Event channel state */ + size_t num_event_channel_state; + enc_dev_state_t* event_channel_state; + + /* Block device names */ + char* const* virtio_blk_dev_names; + + /* Environment variables imported from the host */ + size_t num_env_imported; + char* const* env_imported; } sgxlkl_enclave_state_t; extern sgxlkl_enclave_state_t sgxlkl_enclave_state; diff --git a/src/include/enclave/enclave_util.h b/src/include/enclave/enclave_util.h index 586ec6de8..639f0508b 100644 --- a/src/include/enclave/enclave_util.h +++ b/src/include/enclave/enclave_util.h @@ -91,6 +91,12 @@ void* oe_malloc_or_die(size_t size, const char* fail_msg, ...); */ void* oe_calloc_or_die(size_t nmemb, size_t size, const char* fail_msg, ...); +/** + * Ensure buffers are held entirely inside or outside the enclave memory. + */ +void sgxlkl_ensure_inside(const void* ptr, size_t sz); +void sgxlkl_ensure_outside(const void* ptr, size_t sz); + /** * * Note that generating a stack trace by unwinding stack frames could be exploited diff --git a/src/include/shared/shared_memory.h b/src/include/shared/shared_memory.h index 41cbee9cc..0c77ea85d 100644 --- a/src/include/shared/shared_memory.h +++ b/src/include/shared/shared_memory.h @@ -5,13 +5,15 @@ #include +struct virtio_dev; + typedef struct sgxlkl_shared_memory { /* Shared memory for virtio implementation */ - void* virtio_net_dev_mem; /* Virtio network device */ - void* virtio_console_mem; /* Virtio console device */ + struct virtio_dev* virtio_net_dev_mem; /* Virtio network device */ + struct virtio_dev* virtio_console_mem; /* Virtio console device */ - size_t evt_channel_num; /* Number of event channels */ + size_t num_evt_channel; /* Number of event channels */ enc_dev_config_t* enc_dev_config; /* Device configuration */ void* virtio_swiotlb; /* Memory for setting up bounce buffer */ @@ -22,11 +24,13 @@ typedef struct sgxlkl_shared_memory /* Shared memory for virtio block devices */ size_t num_virtio_blk_dev; - void** virtio_blk_dev_mem; - char** virtio_blk_dev_names; + struct virtio_dev** virtio_blk_dev_mem; + char const* virtio_blk_dev_names; + size_t virtio_blk_dev_names_length; /* Host environment variables for optional import */ - char* const* env; + char const* env; + size_t env_length; } sgxlkl_shared_memory_t; #endif /* SGXLKL_SHARED_MEMORY_H */ \ No newline at end of file diff --git a/src/include/shared/vio_event_channel.h b/src/include/shared/vio_event_channel.h index 5c93253cb..360498eae 100644 --- a/src/include/shared/vio_event_channel.h +++ b/src/include/shared/vio_event_channel.h @@ -18,7 +18,6 @@ typedef struct enc_dev_config { uint8_t dev_id; enc_evt_channel_t* enc_evt_chn; - evt_t evt_processed; } enc_dev_config_t; #endif //_VIO_EVENT_CHANNEL_H diff --git a/src/lkl/setup.c b/src/lkl/setup.c index 1a77bc25c..9fb30a255 100644 --- a/src/lkl/setup.c +++ b/src/lkl/setup.c @@ -1,3 +1,5 @@ +/* clang-format off */ + #include #include #include @@ -94,9 +96,7 @@ int sgxlkl_mtu = 0; extern struct timespec sgxlkl_app_starttime; /* Function to setup bounce buffer in LKL */ -extern void initialize_enclave_event_channel( - enc_dev_config_t* enc_dev_config, - size_t evt_channel_num); +extern void initialize_enclave_event_channels(void); extern void lkl_virtio_netdev_remove(void); extern void vio_terminate(void); @@ -1315,12 +1315,6 @@ static void init_enclave_clock() SGXLKL_VERBOSE("Setting enclave realtime clock\n"); - if (oe_is_within_enclave(shm->timer_dev_mem, sizeof(struct timer_dev))) - { - sgxlkl_fail( - "timer_dev memory isn't outside of the enclave. Aborting.\n"); - } - struct timer_dev* t = shm->timer_dev_mem; struct lkl_timespec start_time; start_time.tv_sec = t->init_walltime_sec; @@ -1390,15 +1384,13 @@ void lkl_start_init() sgxlkl_mtu = cfg->tap_mtu; SGXLKL_VERBOSE("calling initialize_enclave_event_channel()\n"); - initialize_enclave_event_channel(shm->enc_dev_config, shm->evt_channel_num); + initialize_enclave_event_channels(); // Register console device lkl_virtio_console_add(shm->virtio_console_mem); // Register network tap if given one - int net_dev_id = -1; - if (shm->virtio_net_dev_mem) - net_dev_id = lkl_virtio_netdev_add(shm->virtio_net_dev_mem); + int net_dev_id = lkl_virtio_netdev_add(shm->virtio_net_dev_mem); /* Prepare bootargs to boot lkl kernel */ char bootargs[BOOTARGS_LEN] = {0}; @@ -1462,7 +1454,7 @@ void lkl_start_init() if (sgxlkl_enclave_state.config->swiotlb) { /* validate bounce buffer memory before setting it up */ - if (!oe_is_within_enclave( + if (oe_is_outside_enclave( shm->virtio_swiotlb, shm->virtio_swiotlb_size)) { lkl_initialize_swiotlb( diff --git a/src/lkl/virtio_blkdev.c b/src/lkl/virtio_blkdev.c index c98ed0517..1d370377d 100644 --- a/src/lkl/virtio_blkdev.c +++ b/src/lkl/virtio_blkdev.c @@ -13,8 +13,14 @@ */ static void lkl_deliver_irq(uint8_t dev_id) { - struct virtio_dev* dev = - sgxlkl_enclave_state.shared_memory.virtio_blk_dev_mem[dev_id]; + struct virtio_dev** mems = + sgxlkl_enclave_state.shared_memory.virtio_blk_dev_mem; + + sgxlkl_ensure_inside(mems, sizeof(struct virtio_dev*)); + + struct virtio_dev* dev = mems[dev_id]; + + sgxlkl_ensure_outside(dev, sizeof(struct virtio_dev)); dev->int_status |= VIRTIO_MMIO_INT_VRING; @@ -29,9 +35,17 @@ int lkl_add_disks( const sgxlkl_enclave_mount_config_t* mounts, size_t num_mounts) { + struct virtio_dev** mems = + sgxlkl_enclave_state.shared_memory.virtio_blk_dev_mem; + + sgxlkl_ensure_inside(mems, sizeof(struct virtio_dev*)); + struct virtio_dev* root_dev = - sgxlkl_enclave_state.shared_memory.virtio_blk_dev_mem - [sgxlkl_enclave_state.disk_state[0].host_disk_index]; + mems[sgxlkl_enclave_state.disk_state[0].host_disk_index]; + + if (!oe_is_outside_enclave(root_dev, sizeof(struct virtio_dev))) + oe_abort(); + int mmio_size = VIRTIO_MMIO_CONFIG + root_dev->config_len; if (lkl_virtio_dev_setup(root_dev, mmio_size, lkl_deliver_irq) != 0) return -1; @@ -39,8 +53,9 @@ int lkl_add_disks( for (size_t i = 0; i < num_mounts; ++i) { struct virtio_dev* dev = - sgxlkl_enclave_state.shared_memory.virtio_blk_dev_mem - [sgxlkl_enclave_state.disk_state[i + 1].host_disk_index]; + mems[sgxlkl_enclave_state.disk_state[i + 1].host_disk_index]; + if (!oe_is_outside_enclave(dev, sizeof(struct virtio_dev))) + oe_abort(); int mmio_size = VIRTIO_MMIO_CONFIG + dev->config_len; if (lkl_virtio_dev_setup(dev, mmio_size, lkl_deliver_irq) != 0) return -1; diff --git a/src/lkl/virtio_console.c b/src/lkl/virtio_console.c index 92c2971f1..8d8269ed9 100644 --- a/src/lkl/virtio_console.c +++ b/src/lkl/virtio_console.c @@ -17,6 +17,7 @@ static void lkl_deliver_irq(uint64_t dev_id) struct virtio_dev* dev = sgxlkl_enclave_state.shared_memory.virtio_console_mem; + sgxlkl_ensure_outside(dev, sizeof(struct virtio_dev)); dev->int_status |= VIRTIO_MMIO_INT_VRING; lkl_trigger_irq(dev->irq); @@ -29,6 +30,8 @@ int lkl_virtio_console_add(struct virtio_dev* console) { int ret = -1; + sgxlkl_ensure_outside(console, sizeof(struct virtio_dev)); + int mmio_size = VIRTIO_MMIO_CONFIG + console->config_len; ret = lkl_virtio_dev_setup(console, mmio_size, &lkl_deliver_irq); diff --git a/src/lkl/virtio_netdev.c b/src/lkl/virtio_netdev.c index 1222300fa..92a7d91ea 100644 --- a/src/lkl/virtio_netdev.c +++ b/src/lkl/virtio_netdev.c @@ -65,6 +65,12 @@ static void lkl_deliver_irq(uint64_t dev_id) int lkl_virtio_netdev_add(struct virtio_dev* netdev) { int ret = -1; + + if (!netdev) + return -1; + + sgxlkl_ensure_outside(netdev, sizeof(struct virtio_dev)); + int mmio_size = VIRTIO_MMIO_CONFIG + netdev->config_len; registered_devs[registered_dev_idx] = netdev; diff --git a/src/main-oe/sgxlkl_evt_chn_cfg.c b/src/main-oe/sgxlkl_evt_chn_cfg.c index 5d946d624..7bf6d5190 100644 --- a/src/main-oe/sgxlkl_evt_chn_cfg.c +++ b/src/main-oe/sgxlkl_evt_chn_cfg.c @@ -119,7 +119,6 @@ static void host_dev_cfg_init( enc_dev_config_t* edev_cfg = &enc_dev_cfg[index]; edev_cfg->dev_id = (uint8_t)index; edev_cfg->enc_evt_chn = &enc_evt_channel[index]; - edev_cfg->evt_processed = 0; } *h_dev_config = host_dev_cfg; *e_dev_config = enc_dev_cfg; diff --git a/src/main-oe/sgxlkl_run_oe.c b/src/main-oe/sgxlkl_run_oe.c index e30cb84ad..c07c190e5 100644 --- a/src/main-oe/sgxlkl_run_oe.c +++ b/src/main-oe/sgxlkl_run_oe.c @@ -820,6 +820,18 @@ void set_clock_res(bool have_enclave_config) } } +static void set_host_env(char* const* envp) +{ + sgxlkl_host_state.shared_memory.env_length = 0; + for (char* const* env = envp; *env != 0; env++) + sgxlkl_host_state.shared_memory.env_length += strlen(*env) + 1; + + char* tmp = malloc(sgxlkl_host_state.shared_memory.env_length); + sgxlkl_host_state.shared_memory.env = tmp; + for (char* const* env = envp; *env != 0; env++) + tmp += sprintf(tmp, "%s", *env) + 1; +} + static void rdfsbase_sigill_handler(int sig, siginfo_t* si, void* data) { rdfsbase_caused_sigill = 1; @@ -1041,6 +1053,7 @@ static void register_hds(char* root_hd) if (!shm->virtio_blk_dev_mem || !shm->virtio_blk_dev_names) sgxlkl_host_fail("out of memory\n"); + size_t names_length = 0; for (size_t i = 0; i < num_disks; i++) { sgxlkl_host_disk_state_t* disk = &sgxlkl_host_state.disks[i]; @@ -1064,9 +1077,22 @@ static void register_hds(char* root_hd) disk->mount_config->destination, disk->mount_config->readonly, i); - strcpy(shm->virtio_blk_dev_names[i], dest); } + names_length += strlen(dest) + 1; + } + + char* tmp = malloc(names_length); + if (!tmp) + sgxlkl_host_fail("out of memory\n"); + char* p = tmp; + for (size_t i = 0; i < num_disks; i++) + { + sgxlkl_host_disk_state_t* disk = &sgxlkl_host_state.disks[i]; + char* dest = disk->root_config ? "/" : disk->mount_config->destination; + p += sprintf(p, "%s", dest) + 1; } + shm->virtio_blk_dev_names = tmp; + shm->virtio_blk_dev_names_length = names_length; } static void register_net() @@ -1127,7 +1153,7 @@ static void sgxlkl_cleanup(void) close(sgxlkl_host_state.disks[--sgxlkl_host_state.num_disks].fd); } free(sgxlkl_host_state.shared_memory.virtio_blk_dev_mem); - free(sgxlkl_host_state.shared_memory.virtio_blk_dev_names); + free((char*)sgxlkl_host_state.shared_memory.virtio_blk_dev_names); } static void serialize_ucontext( @@ -1884,7 +1910,7 @@ int main(int argc, char* argv[], char* envp[]) bool have_enclave_config_file = enclave_config_path != NULL; set_clock_res(have_enclave_config_file); - sgxlkl_host_state.shared_memory.env = envp; + set_host_env(envp); set_tls(have_enclave_config_file); register_hds(root_hd); register_net(); @@ -1960,7 +1986,7 @@ int main(int argc, char* argv[], char* envp[]) * console device. Each block disk is treated as a seperate block * device and have an event channel associated with it. */ - sgxlkl_host_state.shared_memory.evt_channel_num = + sgxlkl_host_state.shared_memory.num_evt_channel = sgxlkl_host_state.num_disks + HOST_NETWORK_DEV_COUNT + HOST_CONSOLE_DEV_COUNT; @@ -1973,11 +1999,11 @@ int main(int argc, char* argv[], char* envp[]) &sgxlkl_host_state.shared_memory, &host_dev_cfg, &enc_dev_config, - sgxlkl_host_state.shared_memory.evt_channel_num); + sgxlkl_host_state.shared_memory.num_evt_channel); /* Initialize the host dev configuration in host event handler */ vio_host_initialize_device_cfg( - host_dev_cfg, sgxlkl_host_state.shared_memory.evt_channel_num); + host_dev_cfg, sgxlkl_host_state.shared_memory.num_evt_channel); int dev_index = 0; diff --git a/tests/basic/eeid-config/Makefile b/tests/basic/eeid-config/Makefile index 7efc8772f..afab966fd 100644 --- a/tests/basic/eeid-config/Makefile +++ b/tests/basic/eeid-config/Makefile @@ -6,7 +6,7 @@ IMAGE_SIZE=5M EXECUTION_TIMEOUT=60 -SGXLKL_ENV=SGXLKL_VERBOSE=1 SGXLKL_KERNEL_VERBOSE=1 +SGXLKL_ENV=SGXLKL_VERBOSE=1 SGXLKL_KERNEL_VERBOSE=1 HOSTNAME=EEIDHOST SGXLKL_HW_PARAMS=--hw-debug SGXLKL_SW_PARAMS=--sw-debug diff --git a/tests/basic/eeid-config/hello-eeid.c b/tests/basic/eeid-config/hello-eeid.c index 693dfe519..6c66984bd 100644 --- a/tests/basic/eeid-config/hello-eeid.c +++ b/tests/basic/eeid-config/hello-eeid.c @@ -31,5 +31,16 @@ int main(int argc, char** argv) exit(1); } + // Application environment variable + const char* abc = getenv("ABC"); + if (strcmp(abc, "DEF") != 0) + exit(1); + + // Environment variable imported from host + const char* hostname = getenv("HOSTNAME"); + printf("HOSTNAME=%s\n", hostname); + if (!hostname || strcmp(hostname, "EEIDHOST") != 0) + exit(1); + return 0; }