From 4a6a9889c2bec6207e89ec4fee1ebcca447d9bdb Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Tue, 11 Feb 2020 15:39:56 -0800 Subject: [PATCH] [Pal/Linux-SGX] Eliminate redundant file mmap/munmap in untrusted area Linux-SGX PAL calls `load_trusted_file()` during file open. This function mmaps trusted files to calculate checksums. Previously, file open also mmapped the same trusted file for its own purposes. This commit removes this redundancy and leaves only one mmap, the one in `load_trusted_file()`. --- Pal/src/host/Linux-SGX/db_files.c | 17 ++---- Pal/src/host/Linux-SGX/enclave_framework.c | 65 +++++++++++----------- Pal/src/host/Linux-SGX/pal_linux.h | 4 +- 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/Pal/src/host/Linux-SGX/db_files.c b/Pal/src/host/Linux-SGX/db_files.c index b3ed44bc..a23ef1a0 100644 --- a/Pal/src/host/Linux-SGX/db_files.c +++ b/Pal/src/host/Linux-SGX/db_files.c @@ -70,7 +70,8 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, int sgx_stub_t* stubs; uint64_t total; - ret = load_trusted_file(hdl, &stubs, &total, create); + void* umem; + ret = load_trusted_file(hdl, &stubs, &total, create, &umem); if (ret < 0) { SGX_DBG(DBG_E, "Accessing file:%s is denied. (%s) " @@ -79,19 +80,13 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, int free(hdl); return ret; } + if (stubs && total) { + assert(umem); + } hdl->file.stubs = (PAL_PTR)stubs; hdl->file.total = total; - - if (hdl->file.stubs && hdl->file.total) { - /* case of trusted file: mmap the whole file in untrusted memory for future reads/writes */ - ret = ocall_mmap_untrusted(hdl->file.fd, 0, hdl->file.total, PROT_READ, &hdl->file.umem); - if (IS_ERR(ret)) { - /* note that we don't free stubs because they are re-used in same trusted file */ - free(hdl); - return unix_to_pal_error(ERRNO(ret)); - } - } + hdl->file.umem = umem; *handle = hdl; return 0; diff --git a/Pal/src/host/Linux-SGX/enclave_framework.c b/Pal/src/host/Linux-SGX/enclave_framework.c index 2adcf036..28421ae6 100644 --- a/Pal/src/host/Linux-SGX/enclave_framework.c +++ b/Pal/src/host/Linux-SGX/enclave_framework.c @@ -259,8 +259,12 @@ static bool path_is_equal_or_subpath(const struct trusted_file* tf, * Returns 0 if succeeded, or an error code otherwise. */ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr, - uint64_t * sizeptr, int create) + uint64_t * sizeptr, int create, void** umem) { + *stubptr = NULL; + *sizeptr = 0; + *umem = NULL; + struct trusted_file * tf = NULL, * tmp; char uri[URI_MAX]; char normpath[URI_MAX]; @@ -278,8 +282,6 @@ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr, The created file is added to allowed_file list for later access */ if (create && allow_file_creation) { register_trusted_file(uri, NULL); - *stubptr = NULL; - *sizeptr = 0; return 0; } @@ -344,6 +346,19 @@ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr, if (tf->index < 0) return tf->index; + sgx_stub_t* stubs = NULL; + /* mmap the whole trusted file in untrusted memory for future reads/writes; it is + * caller's responsibility to unmap those areas after use */ + *sizeptr = tf->size; + if (*sizeptr) { + ret = ocall_mmap_untrusted(fd, 0, tf->size, PROT_READ, umem); + if (IS_ERR(ret)) { + *umem = NULL; + ret = unix_to_pal_error(ERRNO(ret)); + goto failed; + } + } + #if CACHE_FILE_STUBS == 1 if (tf->stubs) { *stubptr = tf->stubs; @@ -355,14 +370,15 @@ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr, int nstubs = tf->size / TRUSTED_STUB_SIZE + (tf->size % TRUSTED_STUB_SIZE ? 1 : 0); - sgx_stub_t * stubs = malloc(sizeof(sgx_stub_t) * nstubs); - if (!stubs) - return -PAL_ERROR_NOMEM; + stubs = malloc(sizeof(sgx_stub_t) * nstubs); + if (!stubs) { + ret = -PAL_ERROR_NOMEM; + goto failed; + } sgx_stub_t * s = stubs; /* stubs is an array of 128bit values */ uint64_t offset = 0; LIB_SHA256_CONTEXT sha; - void * umem; ret = lib_SHA256Init(&sha); if (ret < 0) @@ -377,12 +393,6 @@ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr, if (ret < 0) goto failed; - ret = ocall_mmap_untrusted(fd, offset, mapping_size, PROT_READ, &umem); - if (IS_ERR(ret)) { - ret = unix_to_pal_error(ERRNO(ret)); - goto unmap; - } - /* * To prevent TOCTOU attack when generating the file checksum, we * need to copy the file content into the enclave before hashing. @@ -400,23 +410,21 @@ int load_trusted_file (PAL_HANDLE file, sgx_stub_t ** stubptr, /* Any file content needs to be copied into the enclave before * checking and re-hashing */ - memcpy(small_chunk, umem + chunk_offset, chunk_size); + memcpy(small_chunk, *umem + offset + chunk_offset, chunk_size); /* Update the file checksum */ ret = lib_SHA256Update(&sha, small_chunk, chunk_size); if (ret < 0) - goto unmap; + goto failed; /* Update the checksum for the file chunk */ ret = lib_AESCMACUpdate(&aes_cmac, small_chunk, chunk_size); if (ret < 0) - goto unmap; + goto failed; } /* Store the checksum for one file chunk for checking */ ret = lib_AESCMACFinish(&aes_cmac, (uint8_t *) s, sizeof *s); -unmap: - ocall_munmap_untrusted(umem, mapping_size); if (ret < 0) goto failed; } @@ -439,34 +447,23 @@ unmap: if (tf->stubs || tf->index == -PAL_ERROR_DENIED) free(tf->stubs); *stubptr = tf->stubs = stubs; - *sizeptr = tf->size; ret = tf->index; spinlock_unlock(&trusted_file_lock); return ret; failed: + if (*umem) { + assert(*sizeptr > 0); + ocall_munmap_untrusted(*umem, *sizeptr); + } free(stubs); spinlock_lock(&trusted_file_lock); - if (tf->stubs) { - *stubptr = tf->stubs; - *sizeptr = tf->size; - ret = tf->index; - } else { + if (!tf->stubs) { tf->index = -PAL_ERROR_DENIED; } spinlock_unlock(&trusted_file_lock); -#if PRINT_ENCLAVE_STAT - if (!ret) { - sgx_stub_t * loaded_stub; - uint64_t loaded_size; - PAL_HANDLE handle = NULL; - if (!_DkStreamOpen(&handle, normpath, PAL_ACCESS_RDONLY, 0, 0, 0)) - load_trusted_file (handle, &loaded_stub, &loaded_size); - } -#endif - return ret; } diff --git a/Pal/src/host/Linux-SGX/pal_linux.h b/Pal/src/host/Linux-SGX/pal_linux.h index 3da5479c..b1e70919 100644 --- a/Pal/src/host/Linux-SGX/pal_linux.h +++ b/Pal/src/host/Linux-SGX/pal_linux.h @@ -138,8 +138,8 @@ int init_trusted_files (void); * return: 0 succeed */ -int load_trusted_file - (PAL_HANDLE file, sgx_stub_t ** stubptr, uint64_t * sizeptr, int create); +int load_trusted_file(PAL_HANDLE file, sgx_stub_t** stubptr, uint64_t* sizeptr, int create, + void** umem); enum { FILE_CHECK_POLICY_STRICT = 0,