On Thu, Jul 25, 2024 at 01:21:56PM +1200, Huang, Kai wrote: > > > Two enclave threads may try to add and remove the same enclave page > > simultaneously (e.g., if the SGX runtime supports both lazy allocation > > and MADV_DONTNEED semantics). Consider some enclave page added to the > > enclave. User space decides to temporarily remove this page (e.g., > > emulating the MADV_DONTNEED semantics) on CPU1. At the same time, user > > space performs a memory access on the same page on CPU2, which results > > in a #PF and ultimately in sgx_vma_fault(). Scenario proceeds as > > follows: > > > > [ ... skipped ... ] > > > > Here, CPU1 removed the page. However CPU2 installed the PTE entry on the > > same page. This enclave page becomes perpetually inaccessible (until > > another SGX_IOC_ENCLAVE_REMOVE_PAGES ioctl). This is because the page is > > marked accessible in the PTE entry but is not EAUGed, and any subsequent > > access to this page raises a fault: with the kernel believing there to > > be a valid VMA, the unlikely error code X86_PF_SGX encountered by code > > path do_user_addr_fault() -> access_error() causes the SGX driver's > > sgx_vma_fault() to be skipped and user space receives a SIGSEGV instead. > > The userspace SIGSEGV handler cannot perform EACCEPT because the page > > was not EAUGed. Thus, the user space is stuck with the inaccessible > > page. > > Reading the code, it seems the ioctl(sgx_ioc_enclave_modify_types) also zaps > EPC mapping when converting a normal page to TSC. Thus IIUC it should also > suffer this issue? Technically yes, sgx_enclave_modify_types() has a similar code path and can be patched in a similar way. Practically though, I can't imagine an SGX program or framework to allow a scenario when CPU1 modifies the type of the enclave page from REG to TCS and at the same time CPU2 performs a memory access on the same page. This would be clearly a bug in the SGX program/framework. For example, Gramine always follows the path of: create a new REG enclave page, modify it to TCS, only then start using it; i.e., there is never a point in time at which the REG page is allocated and ready to be converted to a TCS page, and some other thread/CPU accesses it in-between these steps. TLDR: I can add similar handling to sgx_enclave_modify_types() if reviewers insist, but I don't see how this data race can ever be triggered by benign real-world SGX applications. -- Dmitrii Kuvaiskii