syzbot
BUG: unable to handle kernel NULL pointer dereference in print_one_line
Status:
upstream: reported C repro on 2026/11/04 06:50
Subsystems:
trace
block
Labels:
prio:low
[Documentation on labels]
Reported-by: syzbot+2fca70610179be6c24a4@syzkaller.appspotmail.com
First crash: 4d10h, last: 1d14h
✨ AI-generated root cause summary:
When blktrace events are recorded with version 1 (configured via the BLKTRACESETUP ioctl) while the blk ftrace tracer is enabled, __blk_add_trace() writes events using the v1 struct blk_io_trace layout instead of the v2 struct blk_io_trace2 layout expected by ftrace. In print_one_line(), the entry is unconditionally cast to struct blk_io_trace2, interpreting the process PID (at offset 32 in v1) as the action field (at offset 32 in v2). If this value corresponds to 14 (__BLK_TA_BOUNCE), the bounds check against ARRAY_SIZE(what2act) passes, but what2act[14].print is NULL because __BLK_TA_BOUNCE is an uninitialized entry in what2act[], leading to an instruction fetch at address 0x0 and a kernel panic.
▶
▼
✨ Full AI root cause analysis
Root Cause Analysis
1. Synopsis and Involved Entities
- Source File:
kernel/trace/blktrace.c
- Functions:
__blk_add_trace(), record_blktrace_event(), record_blktrace_event2(), print_one_line()
- Structures & Data:
struct blk_io_trace (v1 format), struct blk_io_trace2 (v2 format), what2act[] array, enum blktrace_act (include/uapi/linux/blktrace_api.h)
2. Mechanism and Lifecycle Violation
There are two interconnected defects in kernel/trace/blktrace.c that combine to cause this crash:
-
Format Mismatch in the ftrace Ring Buffer:
-
Unchecked Function Pointer Call on Uninitialized Array Slot:
what2act[] is defined using designated initializers up to [__BLK_TA_REMAP] = 15, making ARRAY_SIZE(what2act) == 16:
static const struct {
const char *act[2];
void (*print)(struct trace_seq *s, const struct trace_entry *ent, bool has_cg);
} what2act[] = {
[__BLK_TA_QUEUE] = {{ "Q", "queue" }, blk_log_generic },
...
[__BLK_TA_SPLIT] = {{ "X", "split" }, blk_log_split },
[__BLK_TA_REMAP] = {{ "A", "remap" }, blk_log_remap },
};
- In
enum blktrace_act, index 14 is __BLK_TA_BOUNCE (/* unused, was: bio was bounced */). It is completely omitted in what2act[], leaving what2act[14].act = {NULL, NULL} and what2act[14].print = NULL.
- In
print_one_line():
if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act)))
trace_seq_printf(s, "Unknown action %x\n", what);
else {
log_action(iter, what2act[what].act[long_act], has_cg);
what2act[what].print(s, iter->ent, has_cg);
}
- When
what == 14, the check what == 0 || what >= ARRAY_SIZE(what2act) evaluates to false (14 < 16).
print_one_line() fails to check whether what2act[what].print is non-NULL.
- It attempts to call
what2act[14].print(...) (NULL), triggering an instruction fetch page fault at RIP: 0x0 in kernel mode (#PF: supervisor instruction fetch in kernel mode).
Runtime Impact and Classification
- Memory Corruption (
MemoryCorruption: false):
The crash occurs directly from calling an uninitialized NULL function pointer (RIP: 0010:0x0), not a wild or corrupted pointer. In production builds without debugging sanitizers, this is a pure NULL pointer dereference and instruction fetch fault; it does not corrupt kernel memory or hijack control flow to attacker-chosen payload addresses.
- Information Leak (
InfoLeak: "none"):
No kernel heap/stack data or pointers are leaked to userspace; the read operation immediately faults and crashes.
- Denial of Service (
RawDenialOfService: true):
Dereferencing the NULL pointer causes an immediate kernel oops/panic during standard read() operations on the trace file, halting the calling process or the entire system depending on panic_on_oops configuration.
- Candidate Subsystems (
IsNetCandidate: false, IsKVMCandidate: false):
The issue is entirely within the block tracing subsystem (blktrace) and generic tracing infrastructure (ftrace).
▶
▼
Last patch testing requests (1)
Sample crash report:
BUG: kernel NULL pointer dereference, address: 0000000000000000
#PF: supervisor instruction fetch in kernel mode
#PF: error_code(0x0010) - not-present page
PGD 0 P4D 0
Oops: Oops: 0010 [#1] SMP KASAN PTI
CPU: 1 UID: 0 PID: 6058 Comm: syz-executor155 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/15/2026
RIP: 0010:0x0
Code: Unable to access opcode bytes at 0xffffffffffffffd6.
RSP: 0018:ffffc900039cf9f8 EFLAGS: 00010206
RAX: 1ffff1100f6dc81e RBX: 0000000000000000 RCX: ffff888027a8ddc0
RDX: 0000000000000001 RSI: ffff88807b428004 RDI: ffff88807b6e20f0
RBP: ffffffff8c334eb0 R08: ffff88807b6e215d R09: 1ffff1100f6dc42b
R10: dffffc0000000000 R11: 0000000000000000 R12: ffff88807b6e0000
R13: ffffffff81d21760 R14: ffff88807b6e20f0 R15: ffff88807b6e40f0
FS: 000055555b9db400(0000) GS:ffff8881234ff000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffffffffd6 CR3: 000000005d394000 CR4: 00000000003526f0
Call Trace:
<TASK>
print_one_line+0x29d/0x300 kernel/trace/blktrace.c:1757
s_show+0x142/0x320 kernel/trace/trace.c:3332
seq_read_iter+0x8d5/0xca0 fs/seq_file.c:273
seq_read+0x367/0x480 fs/seq_file.c:163
vfs_read+0x213/0xa80 fs/read_write.c:572
ksys_read+0x150/0x270 fs/read_write.c:716
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fc3268e9437
Code: 48 89 fa 4c 89 df e8 98 1e 00 00 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 1a 5b c3 0f 1f 84 00 00 00 00 00 48 8b 44 24 10 0f 05 <5b> c3 0f 1f 80 00 00 00 00 83 e2 39 83 fa 08 75 de e8 23 ff ff ff
RSP: 002b:00007ffe64d7f280 EFLAGS: 00000202 ORIG_RAX: 0000000000000000
RAX: ffffffffffffffda RBX: 000055555b9db400 RCX: 00007fc3268e9437
RDX: 0000000000001000 RSI: 00007ffe64d7f530 RDI: 0000000000000005
RBP: 0000000000000005 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000202 R12: 00007fc326926928
R13: 0000000000000004 R14: 00007ffe64d7f430 R15: 00007ffe64d7f2fc
</TASK>
Modules linked in:
CR2: 0000000000000000
---[ end trace 0000000000000000 ]---
RIP: 0010:0x0
Code: Unable to access opcode bytes at 0xffffffffffffffd6.
RSP: 0018:ffffc900039cf9f8 EFLAGS: 00010206
RAX: 1ffff1100f6dc81e RBX: 0000000000000000 RCX: ffff888027a8ddc0
RDX: 0000000000000001 RSI: ffff88807b428004 RDI: ffff88807b6e20f0
RBP: ffffffff8c334eb0 R08: ffff88807b6e215d R09: 1ffff1100f6dc42b
R10: dffffc0000000000 R11: 0000000000000000 R12: ffff88807b6e0000
R13: ffffffff81d21760 R14: ffff88807b6e20f0 R15: ffff88807b6e40f0
FS: 000055555b9db400(0000) GS:ffff8881234ff000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: ffffffffffffffd6 CR3: 000000005d394000 CR4: 00000000003526f0
* Struck through repros no longer work on HEAD.