lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 19 Dec 2018 07:22:00 +0200
From:   Jarkko Sakkinen <jarkko.sakkinen@...ux.intel.com>
To:     Andy Lutomirski <luto@...nel.org>
Cc:     X86 ML <x86@...nel.org>,
        Platform Driver <platform-driver-x86@...r.kernel.org>,
        linux-sgx@...r.kernel.org, Dave Hansen <dave.hansen@...el.com>,
        "Christopherson, Sean J" <sean.j.christopherson@...el.com>,
        nhorman@...hat.com, npmccallum@...hat.com,
        "Ayoun, Serge" <serge.ayoun@...el.com>, shay.katz-zamir@...el.com,
        Haitao Huang <haitao.huang@...ux.intel.com>,
        Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        "Svahn, Kai" <kai.svahn@...el.com>, mark.shanahan@...el.com,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        "H. Peter Anvin" <hpa@...or.com>,
        Darren Hart <dvhart@...radead.org>,
        Andy Shevchenko <andy@...radead.org>,
        "open list:X86 ARCHITECTURE (32-BIT AND 64-BIT)" 
        <linux-kernel@...r.kernel.org>
Subject: Re: [PATCH v17 18/23] platform/x86: Intel SGX driver

On Mon, Dec 17, 2018 at 09:55:08PM -0800, Andy Lutomirski wrote:
> On Thu, Nov 15, 2018 at 5:08 PM Jarkko Sakkinen
> <jarkko.sakkinen@...ux.intel.com> wrote:
> >
> > Intel Software Guard eXtensions (SGX) is a set of CPU instructions that
> > can be used by applications to set aside private regions of code and
> > data. The code outside the enclave is disallowed to access the memory
> > inside the enclave by the CPU access control.
> 
> This is a very partial review.

Thank you, appreciate it.

> > +int sgx_encl_find(struct mm_struct *mm, unsigned long addr,
> > +                 struct vm_area_struct **vma)
> > +{
> > +       struct vm_area_struct *result;
> > +       struct sgx_encl *encl;
> > +
> > +       result = find_vma(mm, addr);
> > +       if (!result || result->vm_ops != &sgx_vm_ops || addr < result->vm_start)
> > +               return -EINVAL;
> > +
> > +       encl = result->vm_private_data;
> > +       *vma = result;
> > +
> > +       return encl ? 0 : -ENOENT;
> > +}
> 
> I realize that this function may go away entirely but, if you keep it:
> what are the locking rules?  What, if anything, prevents another
> thread from destroying the enclave after sgx_encl_find() returns?

The kref inside the enclave is used to manage this but this function
directly does not prevent it (see for example sgx_encl_get). But yes,
this function does not give any guarantees (should probably have
a documentation stating this).

> > +static int sgx_validate_secs(const struct sgx_secs *secs,
> > +                            unsigned long ssaframesize)
> > +{
> 
> ...
> 
> > +       if (secs->attributes & SGX_ATTR_MODE64BIT) {
> > +               if (secs->size > sgx_encl_size_max_64)
> > +                       return -EINVAL;
> > +       } else {
> > +               /* On 64-bit architecture allow 32-bit encls only in
> > +                * the compatibility mode.
> > +                */
> > +               if (!test_thread_flag(TIF_ADDR32))
> > +                       return -EINVAL;
> > +               if (secs->size > sgx_encl_size_max_32)
> > +                       return -EINVAL;
> > +       }
> 
> Why do we need the 32-bit-on-64-bit check?  In general, anything that
> checks per-task or per-mm flags like TIF_ADDR32 is IMO likely to be
> problematic.  You're allowing 64-bit enclaves in 32-bit tasks, so I'm
> guessing you could just delete the check.

I guess you are right. I can remove this.


> 
> > +
> > +       if (!(secs->xfrm & XFEATURE_MASK_FP) ||
> > +           !(secs->xfrm & XFEATURE_MASK_SSE) ||
> > +           (((secs->xfrm >> XFEATURE_BNDREGS) & 1) !=
> > +            ((secs->xfrm >> XFEATURE_BNDCSR) & 1)) ||
> > +           (secs->xfrm & ~sgx_xfrm_mask))
> > +               return -EINVAL;
> 
> Do we need to check that the enclave doesn't use xfeatures that the
> kernel doesn't know about?  Or are they all safe by design in enclave
> mode?

Really good catch BTW. We don't check what kernel doesn't know about.

I'm not sure what harm this would have as the enclave cannot have much
effect to the outside world. Is there easy way to get similar mask
of kernel supported features as sgx_xfrm_mask? The safe play would
be to use such here as I don't have definitive answer to your second
question.

> 
> > +static int sgx_encl_pm_notifier(struct notifier_block *nb,
> > +                               unsigned long action, void *data)
> > +{
> > +       struct sgx_encl *encl = container_of(nb, struct sgx_encl, pm_notifier);
> > +
> > +       if (action != PM_SUSPEND_PREPARE && action != PM_HIBERNATION_PREPARE)
> > +               return NOTIFY_DONE;
> 
> Hmm.  There's an argument to made that omitting this would better
> exercise the code that handles fully asynchronous loss of an enclave.
> Also, I think you're unnecessarily killing enclaves when suspend is
> attempted but fails.

Are you proposing to not do anything at all to the enclaves? There was
is a problem that it could lead to infinite #PF loop if we don't do
it.


> 
> > +
> > +static int sgx_get_key_hash(const void *modulus, void *hash)
> > +{
> > +       struct crypto_shash *tfm;
> > +       int ret;
> > +
> > +       tfm = crypto_alloc_shash("sha256", 0, CRYPTO_ALG_ASYNC);
> > +       if (IS_ERR(tfm))
> > +               return PTR_ERR(tfm);
> > +
> > +       ret = __sgx_get_key_hash(tfm, modulus, hash);
> > +
> > +       crypto_free_shash(tfm);
> > +       return ret;
> > +}
> > +
> 
> I'm so sorry you had to deal with this API.  Once Zinc lands, you
> could clean this up :)
> 
> 
> > +static int sgx_encl_get(unsigned long addr, struct sgx_encl **encl)
> > +{
> > +       struct mm_struct *mm = current->mm;
> > +       struct vm_area_struct *vma;
> > +       int ret;
> > +
> > +       if (addr & (PAGE_SIZE - 1))
> > +               return -EINVAL;
> > +
> > +       down_read(&mm->mmap_sem);
> > +
> > +       ret = sgx_encl_find(mm, addr, &vma);
> > +       if (!ret) {
> > +               *encl = vma->vm_private_data;
> > +
> > +               if ((*encl)->flags & SGX_ENCL_SUSPEND)
> > +                       ret = SGX_POWER_LOST_ENCLAVE;
> > +               else
> > +                       kref_get(&(*encl)->refcount);
> > +       }
> 
> Hmm.  This version has explicit refcounting.
> 
> > +static int sgx_mmap(struct file *file, struct vm_area_struct *vma)
> > +{
> > +       vma->vm_ops = &sgx_vm_ops;
> > +       vma->vm_flags |= VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP | VM_IO |
> > +                        VM_DONTCOPY;
> > +
> > +       return 0;
> > +}
> > +
> > +static unsigned long sgx_get_unmapped_area(struct file *file,
> > +                                          unsigned long addr,
> > +                                          unsigned long len,
> > +                                          unsigned long pgoff,
> > +                                          unsigned long flags)
> > +{
> > +       if (len < 2 * PAGE_SIZE || (len & (len - 1)))
> > +               return -EINVAL;
> > +
> > +       if (len > sgx_encl_size_max_64)
> > +               return -EINVAL;
> > +
> > +       if (len > sgx_encl_size_max_32 && test_thread_flag(TIF_ADDR32))
> > +               return -EINVAL;
> 
> Generally speaking, this type of check wants to be
> in_compat_syscall().  But I'm not sure I understand why you need it at
> all.

I'll remove it.

> 
> > +static void sgx_ipi_cb(void *info)
> > +{
> > +}
> > +
> > +void sgx_flush_cpus(struct sgx_encl *encl)
> > +{
> > +       on_each_cpu_mask(mm_cpumask(encl->mm), sgx_ipi_cb, NULL, 1);
> > +}
> 
> Please add a comment explaining what this promises to do.

Will do.

/Jarkko

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ