Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-q99v-mcmh-7x5m

Опубликовано: 18 мар. 2024
Источник: github
Github: Не прошло ревью

Описание

In the Linux kernel, the following vulnerability has been resolved:

mm, kmsan: fix infinite recursion due to RCU critical section

Alexander Potapenko writes in [1]: "For every memory access in the code instrumented by KMSAN we call kmsan_get_metadata() to obtain the metadata for the memory being accessed. For virtual memory the metadata pointers are stored in the corresponding struct page, therefore we need to call virt_to_page() to get them.

According to the comment in arch/x86/include/asm/page.h, virt_to_page(kaddr) returns a valid pointer iff virt_addr_valid(kaddr) is true, so KMSAN needs to call virt_addr_valid() as well.

To avoid recursion, kmsan_get_metadata() must not call instrumented code, therefore ./arch/x86/include/asm/kmsan.h forks parts of arch/x86/mm/physaddr.c to check whether a virtual address is valid or not.

But the introduction of rcu_read_lock() to pfn_valid() added instrumented RCU API calls to virt_to_page_or_null(), which is called by kmsan_get_metada...

In the Linux kernel, the following vulnerability has been resolved:

mm, kmsan: fix infinite recursion due to RCU critical section

Alexander Potapenko writes in [1]: "For every memory access in the code instrumented by KMSAN we call kmsan_get_metadata() to obtain the metadata for the memory being accessed. For virtual memory the metadata pointers are stored in the corresponding struct page, therefore we need to call virt_to_page() to get them.

According to the comment in arch/x86/include/asm/page.h, virt_to_page(kaddr) returns a valid pointer iff virt_addr_valid(kaddr) is true, so KMSAN needs to call virt_addr_valid() as well.

To avoid recursion, kmsan_get_metadata() must not call instrumented code, therefore ./arch/x86/include/asm/kmsan.h forks parts of arch/x86/mm/physaddr.c to check whether a virtual address is valid or not.

But the introduction of rcu_read_lock() to pfn_valid() added instrumented RCU API calls to virt_to_page_or_null(), which is called by kmsan_get_metadata(), so there is an infinite recursion now. I do not think it is correct to stop that recursion by doing kmsan_enter_runtime()/kmsan_exit_runtime() in kmsan_get_metadata(): that would prevent instrumented functions called from within the runtime from tracking the shadow values, which might introduce false positives."

Fix the issue by switching pfn_valid() to the _sched() variant of rcu_read_lock/unlock(), which does not require calling into RCU. Given the critical section in pfn_valid() is very small, this is a reasonable trade-off (with preemptible RCU).

KMSAN further needs to be careful to suppress calls into the scheduler, which would be another source of recursion. This can be done by wrapping the call to pfn_valid() into preempt_disable/enable_no_resched(). The downside is that this sacrifices breaking scheduling guarantees; however, a kernel compiled with KMSAN has already given up any performance guarantees due to being heavily instrumented.

Note, KMSAN code already disables tracing via Makefile, and since mmzone.h is included, it is not necessary to use the notrace variant, which is generally preferred in all other cases.

Связанные уязвимости

ubuntu
почти 2 года назад

Rejected reason: This CVE ID has been rejected or withdrawn by its CVE Numbering Authority.

CVSS3: 5.5
redhat
почти 2 года назад

A vulnerability was found in mm, kmsan (Kernel Memory Sanitizer) component of Linux Kernel, causing infinite recursion due to a RCU (Read-Copy Update) critical section when accessing memory metadata. This recursion led to system instability and leads to DoS.

nvd
почти 2 года назад

Rejected reason: This CVE ID has been rejected or withdrawn by its CVE Numbering Authority.

CVSS3: 5.5
fstec
около 2 лет назад

Уязвимость функции pfn_valid() в модуле include/linux/mmzone.h подсистемы управления памятью ядра операционной системы Linux, позволяющая нарушителю вызвать отказ в обслуживании