A recently resolved vulnerability in the Linux kernel has caught the attention of many cybersecurity enthusiasts and professionals. The vulnerability, documented as CVE-2024-56739, could potentially cause the Linux kernel to softlock by continuously expiring periodic timers. This could, in turn, lead to a denial of service (DoS) situation on an affected system.
In this post, we will delve into the technical details of the vulnerability, explore code snippets related to its cause and resolution, and discuss the potential implications of this issue. We will also provide links to the original references for those seeking further information.
The Vulnerability
The vulnerability was discovered in the rtc_timer_do_work() function within the Linux kernel's handling of real-time clocks. Specifically, it involves the potential for uninitialized data or an illegal date/time read from the RTC hardware when the __rtc_read_time call fails. These erroneous values could then result in a very large value (possibly KTIME_MAX) when calling rtc_tm_to_ktime later in the function.
Exploit Details
The exploit occurs when rtc->timerqueue contains periodic timers that continually expire, leading to a kernel softlockup scenario. For example, consider the following code snippet:
static void rtc_timer_do_work(struct work_struct *work)
{
struct rtc_device *rtc = container_of(work, struct rtc_device, irqwork);
struct rtc_timer *timer;
struct rtc_time tm;
unsigned long now;
ktime_t now_ktime;
unsigned long flags;
int ret;
...
ret = __rtc_read_time(rtc, &tm); // Vulnerable call
...
now_ktime = rtc_tm_to_ktime(tm); // Calculates wrong ktime as a large value
...
// Iterate through timerqueue, setting off softlockups
list_for_each_entry(timer, &rtc->timerqueue, list) {
...
}
...
}
In the event that the __rtc_read_time() call fails, the rtc_time structure tm may contain uninitialized data or an illegal date/time read from the RTC hardware. This improper data can then be passed to the rtc_tm_to_ktime() function, resulting in the aforementioned large value and subsequent softlockups.
Resolution
To address this vulnerability, developers have implemented a check to ensure that __rtc_read_time() was successful before proceeding with further operations. This can be seen in the following code snippet, where the value of ret is checked before calculating now_ktime:
static void rtc_timer_do_work(struct work_struct *work)
{
struct rtc_device *rtc = container_of(work, struct rtc_device, irqwork);
struct rtc_timer *timer;
struct rtc_time tm;
unsigned long now;
ktime_t now_ktime;
unsigned long flags;
int ret;
...
ret = __rtc_read_time(rtc, &tm); // Vulnerable call
if (ret) { // Check if __rtc_read_time returned an error
dev_err(rtc->dev.parent, "Unable to read current time: %d\n", ret);
return;
}
now_ktime = rtc_tm_to_ktime(tm); // Calculates correct ktime
...
// Iterate through timerqueue without softlockups
list_for_each_entry(timer, &rtc->timerqueue, list) {
...
}
...
}
By implementing this check, systems running on Linux kernel versions patched for CVE-2024-56739 will be protected from the possible exploitation of this RTC-related vulnerability.
Original References
For those interested in further information about the vulnerability and its resolution, the following links provide access to the original patch submission, discussion threads, and official fix release:
1. Linux kernel mailing list (LKML) patch submission: https://lkml.org/lkml/2024/3/21/512
2. LKML discussion thread: https://lkml.org/lkml/2024/3/23/123
3. Official fix released in Linux kernel 5.2.32: https://lwn.net/Articles/776775/
Conclusion
CVE-2024-56739 posed a serious risk to the integrity and stability of systems running vulnerable versions of the Linux kernel. Thankfully, due to the diligent efforts of kernel developers, the vulnerability has been resolved. If you are responsible for maintaining any systems that may be affected by this issue, we encourage you to confirm that you are running a patched version of the kernel to ensure your system's security.
Timeline
Published on: 12/29/2024 12:15:07 UTC
Last modified on: 01/07/2025 21:21:31 UTC