linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Dave Hansen <dave.hansen@intel.com>
Cc: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>,
	Andy Lutomirski <luto@amacapital.net>,
	Andy Lutomirski <luto@kernel.org>, X86 ML <x86@kernel.org>,
	linux-sgx@vger.kernel.org, LKML <linux-kernel@vger.kernel.org>,
	Linux-MM <linux-mm@kvack.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	Matthew Wilcox <willy@infradead.org>,
	Jethro Beekman <jethro@fortanix.com>,
	Darren Kenny <darren.kenny@oracle.com>,
	Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
	asapek@google.com, Borislav Petkov <bp@alien8.de>,
	"Xing, Cedric" <cedric.xing@intel.com>,
	chenalexchen@google.com, Conrad Parker <conradparker@google.com>,
	cyhanish@google.com, "Huang, Haitao" <haitao.huang@intel.com>,
	Josh Triplett <josh@joshtriplett.org>,
	"Huang, Kai" <kai.huang@intel.com>,
	"Svahn, Kai" <kai.svahn@intel.com>, Keith Moyer <kmoy@google.com>,
	Christian Ludloff <ludloff@google.com>,
	Neil Horman <nhorman@redhat.com>,
	Nathaniel McCallum <npmccallum@redhat.com>,
	Patrick Uiterwijk <puiterwijk@redhat.com>,
	David Rientjes <rientjes@google.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	yaozhangx@google.com
Subject: Re: [PATCH v38 10/24] mm: Add vm_ops->mprotect()
Date: Thu, 24 Sep 2020 09:27:51 -0700	[thread overview]
Message-ID: <20200924162750.GC22819@linux.intel.com> (raw)
In-Reply-To: <982367fb-17b7-a647-a33b-8c8e5e1511a2@intel.com>

On Thu, Sep 24, 2020 at 07:50:15AM -0700, Dave Hansen wrote:
> On 9/23/20 7:33 AM, Jarkko Sakkinen wrote:
> > The consequence is that enclaves are best created with an ioctl API and the
> > access control can be based only to the origin of the source file for the
> > enclave data, i.e. on VMA file pointer and page permissions. For example,
> > this could be done with LSM hooks that are triggered in the appropriate
> > ioctl's and they could make the access control decision based on this
> > information.
> > 
> > Unfortunately, there is ENCLS[EMODPE] that a running enclave can use to
> > upgrade its permissions. If we do not limit mmap() and mprotect(), enclave
> > could upgrade its permissions by using EMODPE followed by an appropriate
> > mprotect() call. This would be completely hidden from the kernel.
> > 
> > Add 'mprotect' hook to vm_ops, so that a callback can be implemeted for SGX
> > that will ensure that {mmap, mprotect}() permissions do not surpass any of
> > the original page permissions. This feature allows to maintain and refine
> > sane access control for enclaves.
> 
> Maybe I'm just being dense, but I still don't have a clear idea what
> function this hook serves.
> 
> I understand that SGX has an orthogonal set of page permissions to the
> normal x86 page tables.  It needs these so that the OS can't play nasty
> tricks on the enclave, like removing read-only protections that provide
> hardening.
> 
> But, I still don't get the connection to mprotect() and the x86 paging
> permissions.  If the enclave's permissions are orthogonal, then why
> bother with this hook?  Why does the OS view of the enclave's memory matter?

For the purpose of this discussion, ignore the enclave permissions.  The only
reason they're mentioned is to explain the background (well, try to) of how we
ended up at an ->mprotect() hook.  There was a great deal of discussion in the
past about whether or not we could use enclave permissions to enforce OS
permissions.  The TL:DR version is that because of ENCLU[EMODPE], the answer
is "no".

What we're preventing via ->mprotect() is using SGX to bypass existing
restrictions on code execution, e.g. noexec and LSM policies.

Because code must first be loaded into an enclave before it can be executed,
all enclaves are kind of a variant on (in SELinux terminology) either EXECMOD
or EXECMEM.  I.e. it's simply not possible to execute an enclave by mapping
the source file as executable.  This effectively allows userspace to bypass a
noexec FS by loading code into an enclave without EXEC perms on the source
file, only on /dev/sgx/enclave, and denying EXEC on /dev/sgx/enclave would
prevent running _any_ enclave.

The ->mprotect() hook is used by SGX to require userspace to declare what
permissions are allowed on any given enclave page, e.g. SGX's mmap()/mprotect()
requires all underlying enclave pages to be declared as executable if the
mmap()/mprotect() is specifying VM_EXEC.  By requiring userspace to declare
their intent up front, SGX can then enforce noexec by requiring pages that are
declared as executable to have VM_MAYEXEC set in the source VMA when loading
code into the enclave.

As Jarkko pointed out, an alternative to adding ->mprotect() would be to
simply require VM_MAYEXEC on _all_ source VMAs when loading code into the
enclave.  That would work, albeit with the potentially undesirable side effect
of preventing loading any part of an enclave from e.g. a noexec, readonly FS.

But, unconditionally requiring VM_MAYEXEC doesn't address the Linux Security
Module hooks for mmap() and mprotect(), which could also be bypassed by abusing
SGX.  E.g. a process could gain arbitrary code execution by loading code from
anonymous memory into an enclave, as the LSM checks hooks at mmap()/mprotect()
will see always vm_file=/dev/sgx/enclave.  An LSM could deny a process access
to /dev/sgx/enclave, but again that is very coarse granularity.

By requiring userspace to declare permissions up front (when loading code/data
into an enclave), SGX can make explicit upcalls to LSMs hooks at load time so
that an LSM can enforce a meaningful policy, e.g. require all enclave code to
originate from an executable file system.  This series doesn't actually
implement the LSM integration, but it does ensure that _if_ we want to add LSM
support in the future, we can do so without breaking userspace.


  reply	other threads:[~2020-09-24 16:27 UTC|newest]

Thread overview: 81+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20200915112842.897265-1-jarkko.sakkinen@linux.intel.com>
2020-09-15 11:28 ` [PATCH v38 10/24] mm: Add vm_ops->mprotect() Jarkko Sakkinen
2020-09-18 12:44   ` Borislav Petkov
2020-09-18 15:09   ` Andy Lutomirski
2020-09-18 23:24     ` [PATCH v38 10/24] mm: Add vm_ops->mprotect()' Jarkko Sakkinen
2020-09-18 23:53     ` [PATCH v38 10/24] mm: Add vm_ops->mprotect() Sean Christopherson
2020-09-19  0:15       ` Andy Lutomirski
2020-09-22 12:58         ` Jarkko Sakkinen
2020-09-22 15:11           ` Dave Hansen
2020-09-23 13:30             ` Jarkko Sakkinen
2020-09-23 13:43             ` Jarkko Sakkinen
2020-09-23 14:33             ` Jarkko Sakkinen
2020-09-24 14:50               ` Dave Hansen
2020-09-24 16:27                 ` Sean Christopherson [this message]
2020-09-24 19:35                 ` Jarkko Sakkinen
2020-09-21 12:49       ` Jarkko Sakkinen
2020-09-21 12:51         ` Jarkko Sakkinen
2020-09-21 13:14         ` Jarkko Sakkinen
2020-09-21 16:57         ` Sean Christopherson
2020-09-21 21:07           ` Jarkko Sakkinen
2020-09-21 21:18             ` Sean Christopherson
2020-09-22  5:29               ` Jarkko Sakkinen
2020-09-22  5:35                 ` Jarkko Sakkinen
2020-09-22 16:43                   ` Sean Christopherson
2020-09-23 13:50                     ` Jarkko Sakkinen
2020-09-24 19:11                       ` Haitao Huang
2020-09-24 19:28                         ` Sean Christopherson
2020-09-24 19:39                           ` Dave Hansen
2020-09-24 20:01                             ` Sean Christopherson
2020-09-24 20:10                               ` Dave Hansen
2020-09-24 20:25                                 ` Sean Christopherson
2020-09-24 20:54                                   ` Dave Hansen
2020-09-24 22:10                                     ` Jarkko Sakkinen
2020-09-24 23:05                                     ` Sean Christopherson
2020-09-24 23:09                                       ` Dave Hansen
2020-09-25  0:00                                         ` Sean Christopherson
2020-09-25 17:18                                           ` Dave Hansen
2020-09-25 19:43                                             ` Sean Christopherson
2020-09-25 19:53                                               ` Dave Hansen
2020-09-26  4:15                                                 ` Andy Lutomirski
2020-09-28  0:53                                                 ` Jarkko Sakkinen
2020-09-28 14:04                                                   ` Dave Hansen
2020-09-28 16:19                                                     ` Jarkko Sakkinen
2020-09-28 16:48                                                       ` Dave Hansen
2020-09-28 19:32                                                         ` Jarkko Sakkinen
2020-09-28 19:45                                                           ` Dave Hansen
2020-09-28 20:19                                                             ` Jarkko Sakkinen
2020-09-29  1:37                                                               ` Andy Lutomirski
2020-09-29  4:05                                                                 ` Jarkko Sakkinen
2020-09-29 14:24                                                                   ` Dave Hansen
2020-09-30  0:20                                                                     ` Jarkko Sakkinen
2020-09-30 14:35                                                                       ` Dave Hansen
2020-09-28 20:18                                                         ` Jarkko Sakkinen
2020-10-18  8:49                                                     ` Dr. Greg
2020-10-19 21:31                                                       ` Sean Christopherson
2020-10-20 10:01                                                         ` Dr. Greg
2020-10-20 16:40                                                           ` Sean Christopherson
2020-10-24 14:37                                                             ` Dr. Greg
2020-10-24 15:33                                                               ` Andy Lutomirski
2020-10-26 10:51                                                                 ` Dr. Greg
2020-10-26 22:59                                                                   ` Andy Lutomirski
2020-10-27  0:40                                                                     ` Sean Christopherson
2020-09-24 22:07                                 ` Jarkko Sakkinen
2020-09-24 21:58                           ` Jarkko Sakkinen
2020-09-24 21:55                         ` Jarkko Sakkinen
2020-09-15 11:28 ` [PATCH v38 11/24] x86/sgx: Add SGX enclave driver Jarkko Sakkinen
2020-09-21  9:30   ` Borislav Petkov
2020-09-21 12:09     ` Jarkko Sakkinen
2020-10-01 17:36   ` Sean Christopherson
2020-10-01 18:49     ` Jarkko Sakkinen
2020-09-15 11:28 ` [PATCH v38 16/24] x86/sgx: Add a page reclaimer Jarkko Sakkinen
2020-09-22 10:45   ` Borislav Petkov
2020-09-22 14:03     ` Jarkko Sakkinen
2020-09-22 14:24       ` Borislav Petkov
2020-09-23 14:52         ` Jarkko Sakkinen
2020-09-29  1:14       ` Sean Christopherson
2020-09-29  3:50         ` Jarkko Sakkinen
2020-09-29  8:35           ` Sean Christopherson
2020-09-22 16:24     ` Sean Christopherson
2020-09-22 18:02       ` Borislav Petkov
2020-09-23 15:25       ` Jarkko Sakkinen
     [not found] <20200915110522.893152-1-jarkko.sakkinen@linux.intel.com>
2020-09-15 11:05 ` [PATCH v38 10/24] mm: Add vm_ops->mprotect() Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200924162750.GC22819@linux.intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=akpm@linux-foundation.org \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=asapek@google.com \
    --cc=bp@alien8.de \
    --cc=cedric.xing@intel.com \
    --cc=chenalexchen@google.com \
    --cc=conradparker@google.com \
    --cc=cyhanish@google.com \
    --cc=darren.kenny@oracle.com \
    --cc=dave.hansen@intel.com \
    --cc=haitao.huang@intel.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jethro@fortanix.com \
    --cc=josh@joshtriplett.org \
    --cc=kai.huang@intel.com \
    --cc=kai.svahn@intel.com \
    --cc=kmoy@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-sgx@vger.kernel.org \
    --cc=ludloff@google.com \
    --cc=luto@amacapital.net \
    --cc=luto@kernel.org \
    --cc=nhorman@redhat.com \
    --cc=npmccallum@redhat.com \
    --cc=puiterwijk@redhat.com \
    --cc=rientjes@google.com \
    --cc=tglx@linutronix.de \
    --cc=willy@infradead.org \
    --cc=x86@kernel.org \
    --cc=yaozhangx@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).