[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200522193914.GF10319@linux.intel.com>
Date: Fri, 22 May 2020 22:39:14 +0300
From: Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
To: Sean Christopherson <sean.j.christopherson@...el.com>
Cc: linux-kernel@...r.kernel.org, x86@...nel.org,
linux-sgx@...r.kernel.org, akpm@...ux-foundation.org,
dave.hansen@...el.com, nhorman@...hat.com, npmccallum@...hat.com,
haitao.huang@...el.com, andriy.shevchenko@...ux.intel.com,
tglx@...utronix.de, kai.svahn@...el.com, bp@...en8.de,
josh@...htriplett.org, luto@...nel.org, kai.huang@...el.com,
rientjes@...gle.com, cedric.xing@...el.com, puiterwijk@...hat.com,
linux-security-module@...r.kernel.org,
Suresh Siddha <suresh.b.siddha@...el.com>,
Jethro Beekman <jethro@...tanix.com>,
Haitao Huang <haitao.huang@...ux.intel.com>,
Chunyang Hui <sanqian.hcy@...fin.com>,
Jordan Hand <jorhand@...ux.microsoft.com>,
Seth Moore <sethmo@...gle.com>
Subject: Re: [PATCH v30 10/20] x86/sgx: Linux Enclave Driver
On Thu, May 21, 2020 at 12:12:36PM -0700, Sean Christopherson wrote:
> On Fri, May 15, 2020 at 03:44:00AM +0300, Jarkko Sakkinen wrote:
> > +long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
> > +{
> > + struct sgx_encl *encl = filep->private_data;
> > + int ret, encl_flags;
> > +
> > + 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;
>
> Returning immediately is wrong as it leaves SGX_ENCL_IOCTL set. This results
> in the application seeing -EBUSY on future ioctls() instead of -EFAULT. Can be
> fixed as below. Do you want me to send a formal patch on linux-sgx?
>
> diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
> index 77757a74644d..df35a79e915c 100644
> --- a/arch/x86/kernel/cpu/sgx/ioctl.c
> +++ b/arch/x86/kernel/cpu/sgx/ioctl.c
> @@ -751,8 +751,10 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
> if (encl_flags & SGX_ENCL_IOCTL)
> return -EBUSY;
>
> - if (encl_flags & SGX_ENCL_DEAD)
> - return -EFAULT;
> + if (encl_flags & SGX_ENCL_DEAD) {
> + ret = -EFAULT;
> + goto out;
> + }
>
> switch (cmd) {
> case SGX_IOC_ENCLAVE_CREATE:
> @@ -772,6 +774,7 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
> break;
> }
>
> +out:
> atomic_andnot(SGX_ENCL_IOCTL, &encl->flags);
>
> return ret;
>
>
> > +
> > + switch (cmd) {
> > + case SGX_IOC_ENCLAVE_CREATE:
> > + ret = sgx_ioc_enclave_create(encl, (void __user *)arg);
> > + break;
> > + case SGX_IOC_ENCLAVE_ADD_PAGES:
> > + ret = sgx_ioc_enclave_add_pages(encl, (void __user *)arg);
> > + break;
> > + case SGX_IOC_ENCLAVE_INIT:
> > + ret = sgx_ioc_enclave_init(encl, (void __user *)arg);
> > + break;
> > + default:
> > + ret = -ENOIOCTLCMD;
> > + break;
> > + }
> > +
> > + atomic_andnot(SGX_ENCL_IOCTL, &encl->flags);
> > +
> > + return ret;
> > +}
Thanks. Fixed in my tree:
v31:
* Unset SGX_ENCL_IOCTL in the error path of checking encl->flags in order
to prevent leaving it set, and thus block any further ioctl calls.
* Added missing cleanup_srcu_struct() call to sgx_encl_release().
* Take encl->lock in sgx_encl_add_page() in order to prevent races with
the page reclaimer.
/Jarkko
Powered by blists - more mailing lists