From 868126bda14bd8a66c425ef92fa42252807031b3 Mon Sep 17 00:00:00 2001 From: Anand Krishnamoorthi Date: Mon, 13 Jul 2020 13:17:23 -0700 Subject: [PATCH] Fine tune OCALL opt-out granularity. Previously, even if an enclave does not use a particular ocall, the ocall will still exist in the host binary since the ocall implementation was placed in the same file as some other symbol that the application (host) needs. To solve this, OCALLS for some core system edls are placed into separate c files whereever possible. This ensures that if an enclave does not need an ocall, the implementation of the ocall will not be picked up. Note: Weak Symbols (OE_WEAK_ALIAS) is not a viable solution since the linker will still link in the weak symbol if it is placed in a file that contains another symbol needed by the application. fixes #3254 fixes #3255 Note: Not all system ocall implementations have been moved to separate C files. Signed-off-by: Anand Krishnamoorthi --- host/CMakeLists.txt | 9 +- host/linux/time.c | 2 +- host/ocalls.c | 49 ----------- host/ocalls/log.c | 18 ++++ host/ocalls/memory.c | 9 ++ host/ocalls/ocalls.c | 18 ++++ host/{ => ocalls}/ocalls.h | 0 host/ocalls/write.c | 17 ++++ host/optee/linux/enclave.c | 2 +- host/sgx/calls.c | 4 +- host/sgx/ocalls/debug.c | 135 ++++++++++++++++++++++++++++++ host/sgx/{ => ocalls}/ocalls.c | 146 +-------------------------------- host/sgx/{ => ocalls}/ocalls.h | 2 +- host/sgx/ocalls/thread.c | 16 ++++ host/sgx/switchless.c | 1 - 15 files changed, 228 insertions(+), 200 deletions(-) delete mode 100644 host/ocalls.c create mode 100644 host/ocalls/log.c create mode 100644 host/ocalls/memory.c create mode 100644 host/ocalls/ocalls.c rename host/{ => ocalls}/ocalls.h (100%) create mode 100644 host/ocalls/write.c create mode 100644 host/sgx/ocalls/debug.c rename host/sgx/{ => ocalls}/ocalls.c (66%) rename host/sgx/{ => ocalls}/ocalls.h (92%) create mode 100644 host/sgx/ocalls/thread.c diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt index cc9ed01b0f..52507b3675 100644 --- a/host/CMakeLists.txt +++ b/host/CMakeLists.txt @@ -228,7 +228,9 @@ if (OE_SGX) sgx/exception.c sgx/load.c sgx/loadelf.c - sgx/ocalls.c + sgx/ocalls/debug.c + sgx/ocalls/ocalls.c + sgx/ocalls/thread.c sgx/quote.c sgx/registers.c sgx/report.c @@ -320,7 +322,10 @@ list( ../common/argv.c asym_keys.c calls.c - ocalls.c + ocalls/log.c + ocalls/ocalls.c + ocalls/memory.c + ocalls/write.c error.c files.c fopen.c diff --git a/host/linux/time.c b/host/linux/time.c index 900aa9f61d..0dcba340d4 100644 --- a/host/linux/time.c +++ b/host/linux/time.c @@ -4,7 +4,7 @@ #include #include #include -#include "../ocalls.h" +#include "../ocalls/ocalls.h" static const uint64_t _SEC_TO_MSEC = 1000UL; static const uint64_t _MSEC_TO_NSEC = 1000000UL; diff --git a/host/ocalls.c b/host/ocalls.c deleted file mode 100644 index b522b33c39..0000000000 --- a/host/ocalls.c +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) Open Enclave SDK contributors. -// Licensed under the MIT License. - -#include -#include - -#include -#include -#include - -#include "core_u.h" -#include "ocalls.h" - -void HandleMalloc(uint64_t arg_in, uint64_t* arg_out) -{ - if (arg_out) - *arg_out = (uint64_t)malloc(arg_in); -} - -void* oe_realloc_ocall(void* ptr, size_t size) -{ - return realloc(ptr, size); -} - -void HandleFree(uint64_t arg) -{ - free((void*)arg); -} - -/* A dummy ocall used to check if the logging.edl is imported. */ -void oe_log_is_supported_ocall() -{ -} - -void oe_log_ocall(uint32_t log_level, const char* message) -{ - oe_log_message(true, (oe_log_level_t)log_level, message); -} - -void oe_write_ocall(int device, const char* str, size_t maxlen) -{ - if (str && (device == 0 || device == 1)) - { - FILE* stream = (device == 0) ? stdout : stderr; - size_t len = strnlen(str, maxlen); - fprintf(stream, "%.*s", (int)len, str); - fflush(stream); - } -} diff --git a/host/ocalls/log.c b/host/ocalls/log.c new file mode 100644 index 0000000000..7c8ae0cdd0 --- /dev/null +++ b/host/ocalls/log.c @@ -0,0 +1,18 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#include +#include +#include + +#include "core_u.h" + +/* A dummy ocall used to check if the logging.edl is imported. */ +void oe_log_is_supported_ocall() +{ +} + +void oe_log_ocall(uint32_t log_level, const char* message) +{ + oe_log_message(true, (oe_log_level_t)log_level, message); +} diff --git a/host/ocalls/memory.c b/host/ocalls/memory.c new file mode 100644 index 0000000000..249c910e37 --- /dev/null +++ b/host/ocalls/memory.c @@ -0,0 +1,9 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#include "core_u.h" + +void* oe_realloc_ocall(void* ptr, size_t size) +{ + return realloc(ptr, size); +} diff --git a/host/ocalls/ocalls.c b/host/ocalls/ocalls.c new file mode 100644 index 0000000000..357aa497bc --- /dev/null +++ b/host/ocalls/ocalls.c @@ -0,0 +1,18 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#include + +#include "core_u.h" +#include "ocalls.h" + +void HandleMalloc(uint64_t arg_in, uint64_t* arg_out) +{ + if (arg_out) + *arg_out = (uint64_t)malloc(arg_in); +} + +void HandleFree(uint64_t arg) +{ + free((void*)arg); +} diff --git a/host/ocalls.h b/host/ocalls/ocalls.h similarity index 100% rename from host/ocalls.h rename to host/ocalls/ocalls.h diff --git a/host/ocalls/write.c b/host/ocalls/write.c new file mode 100644 index 0000000000..da1e5176fc --- /dev/null +++ b/host/ocalls/write.c @@ -0,0 +1,17 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#include + +#include "core_u.h" + +void oe_write_ocall(int device, const char* str, size_t maxlen) +{ + if (str && (device == 0 || device == 1)) + { + FILE* stream = (device == 0) ? stdout : stderr; + size_t len = strnlen(str, maxlen); + fprintf(stream, "%.*s", (int)len, str); + fflush(stream); + } +} diff --git a/host/optee/linux/enclave.c b/host/optee/linux/enclave.c index f5538429be..e85383c5e6 100644 --- a/host/optee/linux/enclave.c +++ b/host/optee/linux/enclave.c @@ -9,7 +9,7 @@ #include #include "../../calls.h" -#include "../../ocalls.h" +#include "../../ocalls/ocalls.h" #include "enclave.h" // clang-format off diff --git a/host/sgx/calls.c b/host/sgx/calls.c index ebbfd51ef1..449af159ee 100644 --- a/host/sgx/calls.c +++ b/host/sgx/calls.c @@ -31,10 +31,10 @@ #include #include "../calls.h" #include "../hostthread.h" -#include "../ocalls.h" +#include "../ocalls/ocalls.h" #include "asmdefs.h" #include "enclave.h" -#include "ocalls.h" +#include "ocalls/ocalls.h" /* **============================================================================== diff --git a/host/sgx/ocalls/debug.c b/host/sgx/ocalls/debug.c new file mode 100644 index 0000000000..33e9517e60 --- /dev/null +++ b/host/sgx/ocalls/debug.c @@ -0,0 +1,135 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. + +#include +#include +#include +#include +#include + +#include "../enclave.h" +#include "platform_u.h" + +static char** _backtrace_symbols( + oe_enclave_t* enclave, + void* const* buffer, + int size) +{ + char** ret = NULL; + + elf64_t elf = ELF64_INIT; + bool elf_loaded = false; + size_t malloc_size = 0; + const char unknown[] = ""; + char* ptr = NULL; + + if (!enclave || enclave->magic != ENCLAVE_MAGIC || !buffer || !size) + goto done; + + /* Open the enclave ELF64 image */ + { + if (elf64_load(enclave->path, &elf) != 0) + goto done; + + elf_loaded = true; + } + + /* Determine total memory requirements */ + { + /* Calculate space for the array of string pointers */ + if (oe_safe_mul_sizet((size_t)size, sizeof(char*), &malloc_size) != + OE_OK) + goto done; + + /* Calculate space for each string */ + for (int i = 0; i < size; i++) + { + const uint64_t vaddr = (uint64_t)buffer[i] - enclave->addr; + const char* name = elf64_get_function_name(&elf, vaddr); + + if (!name) + name = unknown; + + if (oe_safe_add_sizet(malloc_size, strlen(name), &malloc_size) != + OE_OK) + goto done; + + if (oe_safe_add_sizet(malloc_size, sizeof(char), &malloc_size) != + OE_OK) + goto done; + } + } + + /* Allocate the array of string pointers, followed by the strings */ + if (!(ptr = (char*)malloc(malloc_size))) + goto done; + + /* Set pointer to array of strings */ + ret = (char**)ptr; + + /* Skip over array of strings */ + ptr += (size_t)size * sizeof(char*); + + /* Copy strings into return buffer */ + for (int i = 0; i < size; i++) + { + const uint64_t vaddr = (uint64_t)buffer[i] - enclave->addr; + const char* name = elf64_get_function_name(&elf, vaddr); + + if (!name) + name = unknown; + + size_t name_size = strlen(name) + sizeof(char); + oe_memcpy_s(ptr, name_size, name, name_size); + ret[i] = ptr; + ptr += name_size; + } + +done: + + if (elf_loaded) + elf64_unload(&elf); + + return ret; +} + +oe_result_t oe_sgx_backtrace_symbols_ocall( + oe_enclave_t* oe_enclave, + const uint64_t* buffer, + size_t size, + void* symbols_buffer, + size_t symbols_buffer_size, + size_t* symbols_buffer_size_out) +{ + oe_result_t result = OE_UNEXPECTED; + char** strings = NULL; + + /* Reject invalid parameters. */ + if (!oe_enclave || !buffer || size > OE_INT_MAX || !symbols_buffer_size_out) + OE_RAISE(OE_INVALID_PARAMETER); + + /* Convert the addresses into symbol strings. */ + if (!(strings = + _backtrace_symbols(oe_enclave, (void* const*)buffer, (int)size))) + { + OE_RAISE(OE_FAILURE); + } + + *symbols_buffer_size_out = symbols_buffer_size; + + OE_CHECK(oe_argv_to_buffer( + (const char**)strings, + size, + symbols_buffer, + symbols_buffer_size, + symbols_buffer_size_out)); + + result = OE_OK; + +done: + + if (strings) + free(strings); + + return result; +} diff --git a/host/sgx/ocalls.c b/host/sgx/ocalls/ocalls.c similarity index 66% rename from host/sgx/ocalls.c rename to host/sgx/ocalls/ocalls.c index 70d81e5e16..711f908ebc 100644 --- a/host/sgx/ocalls.c +++ b/host/sgx/ocalls/ocalls.c @@ -16,22 +16,18 @@ #endif #include -#include #include #include #include #include -#include -#include #include #include #include -#include "../ocalls.h" -#include "enclave.h" +#include "../enclave.h" +#include "../quote.h" +#include "../sgxquoteprovider.h" #include "ocalls.h" #include "platform_u.h" -#include "quote.h" -#include "sgxquoteprovider.h" void HandleThreadWait(oe_enclave_t* enclave, uint64_t arg_in) { @@ -86,18 +82,6 @@ void HandleThreadWake(oe_enclave_t* enclave, uint64_t arg_in) #endif } -void oe_sgx_thread_wake_wait_ocall( - oe_enclave_t* enclave, - uint64_t waiter_tcs, - uint64_t self_tcs) -{ - if (!waiter_tcs || !self_tcs) - return; - - HandleThreadWake(enclave, waiter_tcs); - HandleThreadWait(enclave, self_tcs); -} - oe_result_t oe_get_quote_ocall( const oe_uuid_t* format_id, const void* opt_params, @@ -279,130 +263,6 @@ oe_result_t oe_get_qetarget_info_ocall( format_id, opt_params, opt_params_size, target_info); } -static char** _backtrace_symbols( - oe_enclave_t* enclave, - void* const* buffer, - int size) -{ - char** ret = NULL; - - elf64_t elf = ELF64_INIT; - bool elf_loaded = false; - size_t malloc_size = 0; - const char unknown[] = ""; - char* ptr = NULL; - - if (!enclave || enclave->magic != ENCLAVE_MAGIC || !buffer || !size) - goto done; - - /* Open the enclave ELF64 image */ - { - if (elf64_load(enclave->path, &elf) != 0) - goto done; - - elf_loaded = true; - } - - /* Determine total memory requirements */ - { - /* Calculate space for the array of string pointers */ - if (oe_safe_mul_sizet((size_t)size, sizeof(char*), &malloc_size) != - OE_OK) - goto done; - - /* Calculate space for each string */ - for (int i = 0; i < size; i++) - { - const uint64_t vaddr = (uint64_t)buffer[i] - enclave->addr; - const char* name = elf64_get_function_name(&elf, vaddr); - - if (!name) - name = unknown; - - if (oe_safe_add_sizet(malloc_size, strlen(name), &malloc_size) != - OE_OK) - goto done; - - if (oe_safe_add_sizet(malloc_size, sizeof(char), &malloc_size) != - OE_OK) - goto done; - } - } - - /* Allocate the array of string pointers, followed by the strings */ - if (!(ptr = (char*)malloc(malloc_size))) - goto done; - - /* Set pointer to array of strings */ - ret = (char**)ptr; - - /* Skip over array of strings */ - ptr += (size_t)size * sizeof(char*); - - /* Copy strings into return buffer */ - for (int i = 0; i < size; i++) - { - const uint64_t vaddr = (uint64_t)buffer[i] - enclave->addr; - const char* name = elf64_get_function_name(&elf, vaddr); - - if (!name) - name = unknown; - - size_t name_size = strlen(name) + sizeof(char); - oe_memcpy_s(ptr, name_size, name, name_size); - ret[i] = ptr; - ptr += name_size; - } - -done: - - if (elf_loaded) - elf64_unload(&elf); - - return ret; -} - -oe_result_t oe_sgx_backtrace_symbols_ocall( - oe_enclave_t* oe_enclave, - const uint64_t* buffer, - size_t size, - void* symbols_buffer, - size_t symbols_buffer_size, - size_t* symbols_buffer_size_out) -{ - oe_result_t result = OE_UNEXPECTED; - char** strings = NULL; - - /* Reject invalid parameters. */ - if (!oe_enclave || !buffer || size > OE_INT_MAX || !symbols_buffer_size_out) - OE_RAISE(OE_INVALID_PARAMETER); - - /* Convert the addresses into symbol strings. */ - if (!(strings = - _backtrace_symbols(oe_enclave, (void* const*)buffer, (int)size))) - { - OE_RAISE(OE_FAILURE); - } - - *symbols_buffer_size_out = symbols_buffer_size; - - OE_CHECK(oe_argv_to_buffer( - (const char**)strings, - size, - symbols_buffer, - symbols_buffer_size, - symbols_buffer_size_out)); - - result = OE_OK; - -done: - - if (strings) - free(strings); - - return result; -} - oe_result_t oe_get_supported_attester_format_ids_ocall( void* format_ids, size_t format_ids_size, diff --git a/host/sgx/ocalls.h b/host/sgx/ocalls/ocalls.h similarity index 92% rename from host/sgx/ocalls.h rename to host/sgx/ocalls/ocalls.h index 3281941259..d9a919af9a 100644 --- a/host/sgx/ocalls.h +++ b/host/sgx/ocalls/ocalls.h @@ -4,7 +4,7 @@ #ifndef _OE_HOST_SGX_OCALLS_H #define _OE_HOST_SGX_OCALLS_H -#include "enclave.h" +#include "../enclave.h" void HandleThreadWait(oe_enclave_t* enclave, uint64_t arg); void HandleThreadWake(oe_enclave_t* enclave, uint64_t arg); diff --git a/host/sgx/ocalls/thread.c b/host/sgx/ocalls/thread.c new file mode 100644 index 0000000000..2c2800ae98 --- /dev/null +++ b/host/sgx/ocalls/thread.c @@ -0,0 +1,16 @@ +// Copyright (c) Open Enclave SDK contributors. +// Licensed under the MIT License. +#include "ocalls.h" +#include "platform_u.h" + +void oe_sgx_thread_wake_wait_ocall( + oe_enclave_t* enclave, + uint64_t waiter_tcs, + uint64_t self_tcs) +{ + if (!waiter_tcs || !self_tcs) + return; + + HandleThreadWake(enclave, waiter_tcs); + HandleThreadWait(enclave, self_tcs); +} diff --git a/host/sgx/switchless.c b/host/sgx/switchless.c index 66aee01ffb..88df577b24 100644 --- a/host/sgx/switchless.c +++ b/host/sgx/switchless.c @@ -10,7 +10,6 @@ #include #include "../calls.h" #include "../hostthread.h" -#include "../ocalls.h" #include "enclave.h" #include "platform_u.h"