CVE-2021-46927 - Resolved Linux Kernel Vulnerability in nitro_enclaves using get_user_pages_unlocked()
A vulnerability CVE-2021-46927 has been resolved in the Linux kernel, specifically in the nitro_enclaves subsystem. The issue is related to the use of the get_user_pages() function and its interaction with mmap asserts. This post will dive into the details of the vulnerability, the code, and how it was fixed with the help of get_user_pages_unlocked().
Vulnerability Details
In the Linux kernel commit 5b78ed24e8ec ("mm/pagemap: add mmap_assert_locked() annotations to find_vma*()"), the call to get_user_pages() started triggering the mmap assert. The mmap assert can be seen in the code snippet below:
static inline void mmap_assert_locked(struct mm_struct *mm)
{
lockdep_assert_held(&mm->mmap_lock);
VM_BUG_ON_MM(!rwsem_is_locked(&mm->mmap_lock), mm);
}
This led to the following kernel bug reported at include/linux/mmap_lock.h:156
[ 62.521410] kernel BUG at include/linux/mmap_lock.h:156!
...
[ 62.538938] RIP: 001:find_vma+x32/x80
...
[ 62.605889] Call Trace:
[ 62.608502] <TASK>
[ 62.610956] ? lock_timer_base+x61/x80
[ 62.614106] find_extend_vma+x19/x80
[ 62.617195] __get_user_pages+x9b/x6a
[ 62.620356] __gup_longterm_locked+x42d/x450
[ 62.623721] ? finish_wait+x41/x80
[ 62.626748] ? __kmalloc+x178/x2f
[ 62.629768] ne_set_user_memory_region_ioctl.isra.+x225/x6a [nitro_enclaves]
[ 62.635776] ne_enclave_ioctl+x1cf/x6d7 [nitro_enclaves]
[ 62.639541] __x64_sys_ioctl+x82/xb
[ 62.642620] do_syscall_64+x3b/x90
[ 62.645642] entry_SYSCALL_64_after_hwframe+x44/xae
The Fix
To resolve this issue and prevent the triggering of mmap asserts, the get_user_pages_unlocked() function is used when setting the enclave memory regions. This provides a similar pattern as using mmap_read_lock() together with get_user_pages(). By using get_user_pages_unlocked(), it allows adequate handling of mmap asserts without causing kernel bugs.
Conclusion
The CVE-2021-46927 vulnerability in the Linux kernel is now resolved by using the get_user_pages_unlocked() call in the nitro_enclaves subsystem. This fix ensures proper handling of mmap asserts, preventing kernel bugs and providing a more secure and stable solution for Linux users.
Original References
1. Linux kernel source commit 5b78ed24e8ec
2. Linux kernel documentation on mmap_lock
3. Linux kernel documentation on get_user_pages
Timeline
Published on: 02/27/2024 10:15:07 UTC
Last modified on: 04/10/2024 16:25:32 UTC