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@xxxxxxxxx> --- arch/x86/kernel/cpu/sgx/ioctl.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c index d34a13d98148..3800281c5945 100644 --- a/arch/x86/kernel/cpu/sgx/ioctl.c +++ b/arch/x86/kernel/cpu/sgx/ioctl.c @@ -540,7 +540,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; } @@ -683,11 +683,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); -- 2.22.0