RE: [RFC PATCH v2 2/5] x86/sgx: Require userspace to define enclave pages' protection bits
From: Xing, Cedric <hidden>
Date: 2019-06-12 18:20:47
Also in:
lkml, selinux
From: Christopherson, Sean J Sent: Wednesday, June 12, 2019 7:34 AM On Tue, Jun 11, 2019 at 05:09:28PM -0700, Andy Lutomirski wrote:quoted
On Jun 10, 2019, at 3:28 PM, Xing, Cedric [off-list ref]wrote:quoted
quoted
quoted
From: Andy Lutomirski [mailto:luto@kernel.org] Sent: Monday, June 10, 2019 12:15 PM This seems like an odd workflow. Shouldn't the #PF return back to untrusted userspace so that the untrusted user code can make its own decision as to whether it wants to EAUG a page there as opposed to, say, killing the enclave or waiting to keep resource usage under control?This may seem odd to some at the first glance. But if you can think of how static heap (pre-allocated by EADD before EINIT) works, the load parses the "metadata" coming with the enclave to decide the address/size of the heap, EADDs it, and calls it done. In the case of "dynamic" heap (allocated dynamically by EAUG after EINIT), the same thing applies - the loader determines the range of the heap, tells the SGX module about it, and calls it done. Everything else isthe between the enclave and the SGX module.quoted
quoted
In practice, untrusted code usually doesn't know much about enclaves, just like it doesn't know much about the shared objects loaded into its address space either. Without the necessary knowledge, untrusted code usually just does what it is told (via o-calls, or return value from e-calls), without judging that's rightor wrong.quoted
quoted
When it comes to #PF like what I described, of course a signal could be sent to the untrusted code but what would it do then? Usually it'd just come back asking for a page at the fault address. So we figured it'd be more efficient to just have the kernel EAUG at #PF. Please don't get me wrong though, as I'm not dictating what the s/w flow shall be. It's just going to be a choice offered to user mode. And that choice was planned to be offered via mprotect() - i.e. a writable vma causes kernel to EAUG while a non-writable vma will result in a signal (then the user mode could decide whether to EAUG). The key point is flexibility - as we want to allow all reasonable s/w flows instead of dictating one over others. We hadsimilar discussions on vDSO API before.quoted
quoted
And I think you accepted my approach because of its flexibility. Am I right?As long as user code can turn this off, I have no real objection. But it might make sense to have it be more explicit — have an ioctl set up a range as “EAUG-on-demand”.This was part of the motivation behind changing SGX_IOC_ENCLAVE_ADD_PAGE to SGX_IOC_ENCLAVE_ADD_REGION and adding a @flags parameter. E.g. adding support for "EAUG-on-demand" regions would just be a new flag.
We'll end up in some sort of interface eventually. But that's too early to discuss. Currently what we need is the plumbing - i.e. the range has to be mmap()'ed and it cannot be PROT_NONE, otherwise vm_ops->fault() will not be reached.
quoted
But this is all currently irrelevant. We can argue about it when the patches show up. :)