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,