[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()`.
This commit is contained in:
Isaku Yamahata
2020-03-02 19:53:41 +00:00
committed by Dmitrii Kuvaiskii
parent c8632aac37
commit 4a6a9889c2
3 changed files with 39 additions and 47 deletions
+6 -11
View File
@@ -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;
+31 -34
View File
@@ -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;
}
+2 -2
View File
@@ -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,