@@ -532,7 +532,7 @@ static int sgx_encl_init(struct sgx_encl *encl, struct sgx_sigstruct *sigstruct,
mutex_lock(&encl->lock);
- if (atomic_read(&encl->flags) & (SGX_ENCL_INITIALIZED | SGX_ENCL_DEAD)) {
+ if (atomic_read(&encl->flags) & SGX_ENCL_INITIALIZED) {
ret = -EFAULT;
goto err_out;
}
@@ -675,11 +675,15 @@ static long sgx_ioc_enclave_set_attribute(struct sgx_encl *encl,
long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
struct sgx_encl *encl = filep->private_data;
- int ret;
+ int ret, encl_flags;
- if (atomic_fetch_or(SGX_ENCL_IOCTL, &encl->flags) & SGX_ENCL_IOCTL)
+ encl_flags = atomic_fetch_or(SGX_ENCL_IOCTL, &encl->flags);
+ if (encl_flags & SGX_ENCL_IOCTL)
return -EBUSY;
+ if (encl_flags & SGX_ENCL_DEAD)
+ return -EFAULT;
+
switch (cmd) {
case SGX_IOC_ENCLAVE_CREATE:
ret = sgx_ioc_enclave_create(encl, (void __user *)arg);
Do not allow userspace to operate on a dead enclave. Note, moving the SGX_ENCL_DEAD for EINIT outside of encl->lock is safe now that sgx_ioctl() prevents concurrent calls. SGX_ENCL_DEAD is only set when the fd is released, i.e. EINIT can no longer be reached, or within an ioctl call. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- arch/x86/kernel/cpu/sgx/ioctl.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)