SGX vs LSM (Re: [PATCH v20 00/28] Intel SGX1 support)
Stephen Smalley
sds at tycho.nsa.gov
Fri May 17 16:37:40 UTC 2019
On 5/17/19 12:20 PM, Stephen Smalley wrote:
> On 5/17/19 11:09 AM, Sean Christopherson wrote:
>> On Fri, May 17, 2019 at 09:53:06AM -0400, Stephen Smalley wrote:
>>> On 5/16/19 6:23 PM, Xing, Cedric wrote:
>>>> I thought EXECMOD applied to files (and memory mappings backed by
>>>> them) but
>>>> I was probably wrong. It sounds like EXECMOD applies to the whole
>>>> process so
>>>> would allow all pages within a process's address space to be
>>>> modified then
>>>> executed, regardless the backing files. Am I correct this time?
>>>
>>> No, you were correct the first time I think; EXECMOD is used to control
>>> whether a process can make executable a private file mapping that has
>>> previously been modified (e.g. text relocation); it is a special case to
>>> support text relocations without having to allow full EXECMEM (i.e.
>>> execute
>>> arbitrary memory).
>>>
>>> SELinux checks relevant to W^X include:
>>>
>>> - EXECMEM: mmap/mprotect PROT_EXEC an anonymous mapping (regardless of
>>> PROT_WRITE, since we know the content has to have been written at some
>>> point) or a private file mapping that is also PROT_WRITE.
>>> - EXECMOD: mprotect PROT_EXEC a private file mapping that has been
>>> previously modified, typically for text relocations,
>>> - FILE__WRITE: mmap/mprotect PROT_WRITE a shared file mapping,
>>> - FILE__EXECUTE: mmap/mprotect PROT_EXEC a file mapping.
>>>
>>> (ignoring EXECSTACK and EXECHEAP here since they aren't really
>>> relevant to
>>> this discussion)
>>>
>>> So if you want to ensure W^X, then you wouldn't allow EXECMEM for the
>>> process, EXECMOD by the process to any file, and the combination of both
>>> FILE__WRITE and FILE__EXECUTE by the process to any file.
>>>
>>> If the /dev/sgx/enclave mappings are MAP_SHARED and you aren't using an
>>> anonymous inode, then I would expect that only the FILE__WRITE and
>>> FILE__EXECUTE checks are relevant.
>>
>> Yep, I was just typing this up in a different thread:
>>
>> I think we may want to change the SGX API to alloc an anon inode for each
>> enclave instead of hanging every enclave off of the /dev/sgx/enclave
>> inode.
>> Because /dev/sgx/enclave is NOT private, SELinux's file_map_prot_check()
>> will only require FILE__WRITE and FILE__EXECUTE to mprotect() enclave
>> VMAs
>> to RWX. Backing each enclave with an anon inode will make SELinux treat
>> EPC memory like anonymous mappings, which is what we want (I think), e.g.
>> making *any* EPC page executable will require PROCESS__EXECMEM (SGX is
>> 64-bit only at this point, so SELinux will always have default_noexec).
>
> I don't think we want to require EXECMEM (or equivalently both
> FILE__WRITE and FILE__EXECUTE to /dev/sgx/enclave) for making any EPC
> page executable, only if the page is also writable or previously
> modified. The intent is to prevent arbitrary code execution without
> EXECMEM (or FILE__WRITE|FILE__EXECUTE), while still allowing enclaves to
> be created without EXECMEM as long as the EPC page mapping is only ever
> mapped RX and its initial contents came from an unmodified file mapping
> that was PROT_EXEC (and hence already checked via FILE__EXECUTE).
Also, just to be clear, there is nothing inherently better about
checking EXECMEM instead of checking both FILE__WRITE and FILE__EXECUTE
to the /dev/sgx/enclave inode, so I wouldn't switch to using anon inodes
for that reason. Using anon inodes also unfortunately disables SELinux
inode-based checking since we no longer have any useful inode
information, so you'd lose out on SELinux ioctl whitelisting on those
enclave inodes if that matters.
More information about the Linux-security-module-archive
mailing list