@@ -351,18 +351,14 @@ static int __sgx_encl_extend(struct sgx_encl *encl,
for_each_set_bit(i, &mrmask, 16) {
ret = __eextend(sgx_epc_addr(encl->secs.epc_page),
sgx_epc_addr(epc_page) + (i * 0x100));
- if (ret)
- goto err_out;
+ if (ret) {
+ if (encls_failed(ret))
+ ENCLS_WARN(ret, "EEXTEND");
+ return -EFAULT;
+ }
}
return 0;
-
-err_out:
- if (encls_failed(ret))
- ENCLS_WARN(ret, "EEXTEND");
-
- sgx_encl_destroy(encl);
- return -EFAULT;
}
static int sgx_encl_add_page(struct sgx_encl *encl,
@@ -421,19 +417,24 @@ static int sgx_encl_add_page(struct sgx_encl *encl,
if (ret)
goto err_out;
- ret = __sgx_encl_extend(encl, epc_page, addp->mrmask);
- if (ret)
- goto err_out;
-
+ /*
+ * Complete the "add" before doing the "extend" so that the "add"
+ * isn't in a half-baked state in the extremely unlikely scenario the
+ * the enclave will be destroyed in response to EEXTEND failure.
+ */
encl_page->encl = encl;
encl_page->epc_page = epc_page;
encl->secs_child_cnt++;
- sgx_mark_page_reclaimable(encl_page->epc_page);
+ ret = __sgx_encl_extend(encl, epc_page, addp->mrmask);
+ if (ret)
+ sgx_encl_destroy(encl);
+ else
+ sgx_mark_page_reclaimable(encl_page->epc_page);
mutex_unlock(&encl->lock);
up_read(¤t->mm->mmap_sem);
- return 0;
+ return ret;
err_out:
radix_tree_delete(&encl_page->encl->page_tree,
Rework EEXTEND error handling to fix issues related to destroying the enclave in response to EEXTEND failure. At the time of EEXTEND, the page is already visibile in the sense that it has been added to the radix tree, and therefore will be processed by sgx_encl_destroy(). This means the "add" part needs to be fully completed prior to invoking sgx_encl_destroy() in order to avoid consuming half-baked state. Move sgx_encl_destroy() to the call site of __sgx_encl_extend() so that it is somewhat more obvious why the add needs to complete before doing EEXTEND. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- arch/x86/kernel/cpu/sgx/ioctl.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-)