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