* [PATCH] soc: apple: rtkit: fix OOB reads in crashlog parser
@ 2026-07-31 16:52 Pavitra Jha
0 siblings, 0 replies; only message in thread
From: Pavitra Jha @ 2026-07-31 16:52 UTC (permalink / raw)
To: Sven Peter, Janne Grunau
Cc: Neal Gompa, Greg Kroah-Hartman, asahi, linux-arm-kernel,
linux-kernel, Pavitra Jha, stable
apple_rtkit_crashlog_dump() parses a binary blob copied from a shared
memory region populated by the RTKit coprocessor after a crash. The
blob is treated as trusted structured data, but four distinct bugs
allow a malicious or compromised coprocessor to trigger out-of-bounds
reads against the kernel heap:
1. Section header read without tail-space guard
The main loop is guarded by (offset < size), but the section header
occupies bytes [offset, offset+16). A section starting within the
last 15 bytes of the buffer causes the memcpy at offset+12 to read
past the end of the allocation.
2. section_size not validated against remaining buffer space
section_size is a u32 read verbatim from the coprocessor blob.
It is passed directly to each handler as the 'size' argument without
checking offset + section_size <= size. Every handler therefore
operates on memory past the end of the shadow buffer. Additionally,
section_size == 0 causes an infinite loop because offset never
advances.
3. dump_mailbox: size_t underflow when section_size < 28
n_messages = (size - 28) / sizeof(entry) performs size_t arithmetic.
If the coprocessor reports section_size < 28, the subtraction wraps
to ~0UL, n_messages becomes enormous, and the subsequent memcpy loop
reads and dev_warn-logs arbitrary adjacent slab memory, constituting
a kernel heap info-leak.
KASAN confirmed (kernel 7.1.0, QEMU/x86_64, kasan_multi_shot):
BUG: KASAN: slab-out-of-bounds in apple_rtkit_crashlog_dump.cold
Read of size 24 at addr ffff88800469f08c by task insmod/60
Call Trace:
kasan_check_range
__asan_memcpy
apple_rtkit_crashlog_dump.cold
rtkit_poc_init
4. dump_version and dump_str: bare %s with no NUL guarantee
dump_version() ignores its size argument entirely and passes bfr+16
directly to dev_warn() as a %s argument. If section_size places the
section end before a NUL byte, dev_warn walks arbitrarily past the
allocation. dump_str() has the same issue in its else branch: memchr
correctly bounds the search, but the resulting pointer is then passed
to dev_warn() as %s without a NUL guarantee within the real buffer.
Fix:
- Check offset + 16 <= size before reading each section header.
- Reject section_size < 16 or offset + section_size > size before
dispatching, ensuring every handler receives a size bounded by the
real buffer. This also eliminates the infinite-loop case.
- Add an explicit size < 28 guard in dump_mailbox() to prevent the
size_t underflow regardless of the outer check.
- Replace bare %s with %.*s in dump_version() and the else branch of
dump_str(), using the (now validated) size argument as the bound.
Attacker model: any entity able to influence RTKit coprocessor firmware
or crash-log shared memory (coprocessor compromise, DMA-capable
peripheral on the same interconnect) can trigger these bugs against any
Linux system running Asahi Linux on Apple Silicon hardware.
Fixes: 9bd1d9a0d8bb ("soc: apple: Add RTKit IPC library")
Cc: stable@vger.kernel.org
Signed-off-by: Pavitra Jha <jhapavitra98@gmail.com>
---
drivers/soc/apple/rtkit-crashlog.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/soc/apple/rtkit-crashlog.c b/drivers/soc/apple/rtkit-crashlog.c
index 8319e3651..3af17c31d 100644
--- a/drivers/soc/apple/rtkit-crashlog.c
+++ b/drivers/soc/apple/rtkit-crashlog.c
@@ -81,8 +81,8 @@ static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr,
*newline = tmp;
ptr = newline + 1;
} else {
- dev_warn(rtk->dev, "RTKit: Message (id=%x): %s", idx,
- ptr);
+ dev_warn(rtk->dev, "RTKit: Message (id=%x): %.*s", idx,
+ (int)(end - ptr), ptr);
break;
}
}
@@ -91,7 +91,12 @@ static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr,
static void apple_rtkit_crashlog_dump_version(struct apple_rtkit *rtk, u8 *bfr,
size_t size)
{
- dev_warn(rtk->dev, "RTKit: Version: %s", bfr + 16);
+ if (size < 17) {
+ dev_warn(rtk->dev, "RTKit: Version section too small: 0x%zx",
+ size);
+ return;
+ }
+ dev_warn(rtk->dev, "RTKit: Version: %.*s", (int)(size - 16), bfr + 16);
}
static void apple_rtkit_crashlog_dump_time(struct apple_rtkit *rtk, u8 *bfr,
@@ -112,6 +117,11 @@ static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr,
memcpy(&type, bfr + 16, 4);
memcpy(&index, bfr + 24, 4);
+ if (size < 28) {
+ dev_warn(rtk->dev, "RTKit: Mailbox section too small: 0x%zx",
+ size);
+ return;
+ }
n_messages = (size - 28) / sizeof(entry);
dev_warn(rtk->dev, "RTKit: Mailbox history (type = %d, index = %d)",
@@ -206,8 +216,20 @@ void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size)
offset = sizeof(header);
while (offset < size) {
+ if (offset + 16 > size) {
+ dev_warn(rtk->dev,
+ "RTKit: Crashlog section header out of bounds at 0x%zx",
+ offset);
+ break;
+ }
memcpy(§ion_fourcc, bfr + offset, 4);
memcpy(§ion_size, bfr + offset + 12, 4);
+ if (section_size < 16 || offset + section_size > size) {
+ dev_warn(rtk->dev,
+ "RTKit: Crashlog section size out of bounds: %u at 0x%zx",
+ section_size, offset);
+ break;
+ }
switch (section_fourcc) {
case APPLE_RTKIT_CRASHLOG_HEADER:
--
2.53.0
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-31 16:53 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-31 16:52 [PATCH] soc: apple: rtkit: fix OOB reads in crashlog parser Pavitra Jha
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.