On 2019-04-19 14:34, Thomas Gleixner wrote: > And how so? You create writeable AND executable memory. That's a nono and > you can argue in circles, that's not going to change with any of your > proposed changes. On 2019-04-19 14:38, Thomas Gleixner wrote: > You are working around LSM nothing else and that's just not going to fly. Based on your comments, I'm still unsure if we're on the same page with regards to what I'm proposing. Here's a regular non-SGX flow that LSM would likely prevent: mmap(PROT_READ|PROT_WRITE) memcpy() mmap(PROT_READ|PROT_EXEC) <-- denied by LSM Or just something based on regular PT permissions: mmap(PROT_READ|PROT_EXEC) memcpy() <-- SIGSEGV Now, the equivalent for SGX: mmap(PROT_READ|PROT_WRITE) ioctl(EADD) mmap(PROT_READ|PROT_EXEC) <-- denied by LSM This works fine with v20 as-is. However, consider the equivalent of the PT-based flow: mmap(PROT_READ|PROT_EXEC) ioctl(EADD) <-- no error! It's not me that's working around the LSM, it's the SGX driver! It's writing to memory that's not marked writable! The fundamental issue here is that the SGX instruction set has several instructions that bypass the page table permission bits, and this is (naturally) confusing to any kind of reference monitor like the LSM framework. You can come up with similar scenarios that involve PROT_READ|PROT_WRITE|PROT_EXEC or ptrace(PTRACE_POKETEXT). So, clearly, the proper way to fix this failure of complete mediation is by enforcing appropriate page-table permissions even on the SGX instructions that don't do it themselves. Just make any implicit memory access look like a regular memory access and now everyone is on the same page (pun intended). -- Jethro Beekman | Fortanix