Recently, a new vulnerability has been resolved in the Linux kernel. This vulnerability, assigned as CVE-2024-56610, is related to the use of KCSAN (Kernel Concurrency Sanitizer) on PREEMPT_RT enabled kernels. This article provides a comprehensive analysis of the issue, including code snippets, links to original references, and details of the exploit.

Overview

KCSAN is a dynamic data race detector, and it is an important part of the Linux kernel's debugging and testing infrastructure. This vulnerability specifically targets KCSAN's report filtering mechanism, where the report_filterlist_lock non-raw spinlock has been observed to cause issues, leading to hard lockup on PREEMPT_RT kernels.

The main issue arises when KCSAN tries to filter a report by checking the filter list. This list is protected by the report_filterlist_lock *non-raw* spinlock, which can result in a sleeping function call from an invalid context, such as:

BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48

Fix: Turning report_filterlist_lock into a raw_spinlock

In order to fix this vulnerability, the report_filterlist_lock non-raw spinlock has been converted to a raw_spinlock. This change helps in preventing potential problems due to sleep on PREEMPT_RT kernels.

Code changes include

-static DEFINE_SPINLOCK(report_filterlist_lock);
+static DEFINE_RAW_SPINLOCK(report_filterlist_lock);
...
-static void report_filterlist_entry_free(
+static void __report_list_entry_free(struct report_filterlist_entry *entry)
{
-	kfree(entry);
+	kfree_rcu(entry, rcu);
}
...
-long kcsan_set_report_skip_count(const char __user *buf, size_t count)
{
	...
-	spin_lock(&report_filterlist_lock);
+	raw_spin_lock(&report_filterlist_lock);
...
		if (entry)
-			report_filterlist_entry_free(entry);
+			call_rcu(&entry->rcu, report_filterlist_timeout_cancel_cb);
	...
-	spin_unlock(&report_filterlist_lock);
+	raw_spin_unlock(&report_filterlist_lock);
}

When converting to a raw_spinlock, special care must be taken in allocating memory for the filter list. This is because KCSAN may report data races in any context. Thus, memory allocation should be done optimistically before the critical section, and then discarded if unused.

References

- kcsan: Turn report_filterlist_lock into a raw_spinlock Patch
- KCSAN Documentation

Summary

CVE-2024-56610 is a vulnerability that affects the Linux kernel KCSAN report filtering mechanism, specifically on PREEMPT_RT enabled kernels. By converting report_filterlist_lock non-raw spinlock to a raw_spinlock, the issue has been resolved, preventing potential problems due to sleep on RT kernels. The fix also requires being cautious about memory allocation for the filter list, ensuring that it is done optimistically before the critical section, and discarded if unused.

Timeline

Published on: 12/27/2024 15:15:20 UTC
Last modified on: 01/20/2025 06:24:06 UTC