Re: [BUG] KASAN: stack-out-of-bounds Write in cpu_init_exception_handling
From: Bradley Morgan
Date: Thu Aug 20 2026 - 09:27:27 EST
On 20 August 2026 10:40:33 BST, Jaeyoung Chung <jjy600901@xxxxxxxxx> wrote:
>Hello,
>
>We found a "KASAN: stack-out-of-bounds Write in
>cpu_init_exception_handling" on
>Linux v7.2. The issue was found by our own race fuzzer. We have not
>analyzed the
>root cause, so we do not have a proposed fix to offer.
>
>To reproduce the race reliably, we applied the delay patch below to the
>kernel and ran the C reproducer as root inside an x86_64 QEMU guest. The
>crash log we observed, the delay patch and the reproducer are all included
>below.
>
>We used the syzbot kernel config, disabled the two options below, and
>built
>it with clang-20:
>
> https://syzkaller.appspot.com/text?tag=KernelConfig&x=1941312e3e971b07
>
> ./scripts/config --file .config --disable MODVERSIONS --disable GENDWARFKSYMS
> make LLVM=1 olddefconfig
>
>We could not reproduce this on a different config, so the report may
>depend on
>the exact stack layout the syzbot config produces.
>
>We hope this report is useful. Please let us know if any further
>information would help.
>
>Reported-by: Eulgyu Kim <eulgyukim@xxxxxxxxx>
>Reported-by: Jaeyoung Chung <jjy600901@xxxxxxxxx>
>
Hi, do you have any fixes suggested? Or would you like me (or tglx, or
whoever) to make one.
>Kernel delay patch:
>==================================================================
>diff --git a/kernel/cpu.c b/kernel/cpu.c
>index b3c8553d7bd6..9eaea7b14027 100644
>--- a/kernel/cpu.c
>+++ b/kernel/cpu.c
>@@ -17,6 +17,7 @@
> #include <linux/oom.h>
> #include <linux/rcupdate.h>
> #include <linux/delay.h>
>+#include <linux/sched.h>
> #include <linux/export.h>
> #include <linux/bug.h>
> #include <linux/kthread.h>
>@@ -833,6 +834,9 @@ static int cpuhp_bringup_ap(unsigned int cpu)
> struct cpuhp_cpu_state *st = per_cpu_ptr(&cpuhp_state, cpu);
> int ret;
>
>+ if (!strncmp(current->comm, "syzrepro0", 9)) {
>+ mdelay(80);
>+ }
> /*
> * Some architectures have to walk the irq descriptors to
> * setup the vector space for the cpu which comes online.
>@@ -1385,6 +1389,9 @@ static int cpuhp_down_callbacks(unsigned int cpu, struct cpuhp_cpu_state *st,
>
> ret = cpuhp_invoke_callback_range(false, cpu, st, target);
> if (ret) {
>+ if (!strncmp(current->comm, "syzrepro", 8)) {
>+ mdelay(20);
>+ }
> pr_debug("CPU DOWN failed (%d) CPU %u state %s (%d)\n",
> ret, cpu, cpuhp_get_step(st->state)->name,
> st->state);
>
>==================================================================
>
>C reproducer:
>==================================================================
>#define _GNU_SOURCE
>#include <fcntl.h>
>#include <pthread.h>
>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>
>#include <sys/prctl.h>
>#include <unistd.h>
>
>#define SYSCHK(x) ({ long __r = (long)(x); if (__r == -1L) { perror(#x);
>exit(1); } __r; })
>
>#define ONLINE "/sys/devices/system/cpu/cpu1/online"
>#define STATE "/sys/devices/system/cpu/cpu1/hotplug/state"
>#define FAIL "/sys/devices/system/cpu/cpu1/hotplug/fail"
>#define STATES "/sys/devices/system/cpu/hotplug/states"
>
>static int bringup;
>static char failval[16];
>static volatile int window, stop;
>
>static int rd(const char *path, char *buf, size_t len)
>{
> int fd = SYSCHK(open(path, O_RDONLY));
> int n = SYSCHK(read(fd, buf, len - 1));
>
> close(fd);
> buf[n] = 0;
> return n;
>}
>
>static void wr(const char *path, const char *val)
>{
> int fd = SYSCHK(open(path, O_WRONLY));
>
> write(fd, val, strlen(val));
> close(fd);
>}
>
>static int state_id(const char *name)
>{
> char buf[8192], *line, *save, *c;
> int id = -1;
>
> rd(STATES, buf, sizeof(buf));
> for (line = strtok_r(buf, "\n", &save); line;
> line = strtok_r(NULL, "\n", &save)) {
> c = strchr(line, ':');
> if (c && !strcmp(c + 2, name))
> id = atoi(line);
> }
> return id;
>}
>
>static void *arm_thread(void *arg)
>{
> char buf[64];
>
> prctl(PR_SET_NAME, "syzrepro1", 0, 0, 0);
> while (!stop) {
> if (!window) {
> usleep(300);
> continue;
> }
> rd(STATE, buf, sizeof(buf));
> if (atoi(buf) == bringup)
> wr(FAIL, failval);
> usleep(200);
> }
> return NULL;
>}
>
>int main(void)
>{
> pthread_t t1;
> int i, fail_state;
>
> prctl(PR_SET_NAME, "syzrepro0", 0, 0, 0);
>
> bringup = state_id("cpu:bringup");
> fail_state = state_id("timers:prepare");
> if (bringup < 0 || fail_state < 0 || fail_state >= bringup) {
> fprintf(stderr, "state lookup failed: bringup=%d fail=%d\n",
> bringup, fail_state);
> return 1;
> }
> snprintf(failval, sizeof(failval), "%d", fail_state);
>
> wr(FAIL, "-1");
> pthread_create(&t1, NULL, arm_thread, NULL);
>
> for (i = 0; i < 200; i++) {
> wr(ONLINE, "0");
> window = 1;
> wr(ONLINE, "1");
> window = 0;
> usleep(2000);
> }
>
> stop = 1;
> pthread_join(t1, NULL);
> return 0;
>}
>==================================================================
>
>Crash log:
>==================================================================
>BUG: KASAN: stack-out-of-bounds in __set_tss_desc arch/x86/include/asm/desc.h:183 [inline]
>BUG: KASAN: stack-out-of-bounds in cpu_init_exception_handling+0x301/0x950 arch/x86/kernel/cpu/common.c:2418
>Write of size 16 at addr ffffc90000177ea0 by task swapper/1/0
>
>CPU: 1 UID: 0 PID: 0 Comm: swapper/1 Not tainted 7.2.0-dirty #10 PREEMPT(full)
>Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
>1.13.0-1ubuntu1.1 04/01/2014
>Call Trace:
> <TASK>
> dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
> print_address_description+0x55/0x1e0 mm/kasan/report.c:378
> print_report+0x64/0x70 mm/kasan/report.c:482
> kasan_report+0x118/0x150 mm/kasan/report.c:595
> check_region_inline mm/kasan/generic.c:-1 [inline]
> kasan_check_range+0x2b0/0x2c0 mm/kasan/generic.c:200
> __asan_memset+0x22/0x50 mm/kasan/shadow.c:84
> __set_tss_desc arch/x86/include/asm/desc.h:183 [inline]
> cpu_init_exception_handling+0x301/0x950 arch/x86/kernel/cpu/common.c:2418
> start_secondary+0x17/0x110 arch/x86/kernel/smpboot.c:248
> common_startup_64+0x13e/0x157
> </TASK>
>
>The buggy address belongs to stack of task swapper/1/0
> and is located at offset 128 in frame:
> cpu_init_exception_handling+0x0/0x950 arch/x86/include/asm/msr.h:-1
>
>This frame has 5 objects:
> [32, 42) 'gdt_descr.i8.i'
> [64, 74) 'gdt_descr.i.i'
> [96, 106) 'gdt.i'
> [128, 144) 'tss.i'
> [160, 168) 'd.i'
>
>The buggy address belongs to a 8-page vmalloc region starting at
>0xffffc90000170000 allocated at copy_process+0x7d9/0x3dc0
>kernel/fork.c:2115
>The buggy address belongs to the physical page:
>page: refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x100697
>flags: 0x57ff00000000000(node=1|zone=2|lastcpupid=0x7ff)
>raw: 057ff00000000000 ffffea000401a5c8 ffffea000401a5c8 0000000000000000
>raw: 0000000000000000 0000000000000000 00000001ffffffff 0000000000000000
>page dumped because: kasan: bad access detected
>page_owner tracks the page as allocated
>page last allocated via order 0, migratetype Unmovable, gfp_mask
>0x29c2(GFP_NOWAIT|__GFP_HIGHMEM|__GFP_IO|__GFP_FS|__GFP_ZERO), pid 1, tgid
>1 (swapper/0), ts 1601422137, free_ts 0
> set_page_owner include/linux/page_owner.h:32 [inline]
> post_alloc_hook+0x205/0x260 mm/page_alloc.c:1859
> prep_new_page mm/page_alloc.c:1867 [inline]
> get_page_from_freelist+0x2366/0x23f0 mm/page_alloc.c:3946
> __alloc_frozen_pages_noprof+0x181/0x370 mm/page_alloc.c:5304
> __alloc_pages_noprof+0x10/0x100 mm/page_alloc.c:5338
> __alloc_pages_node_noprof include/linux/gfp.h:291 [inline]
> alloc_pages_node_noprof include/linux/gfp.h:318 [inline]
> vm_area_alloc_pages mm/vmalloc.c:3691 [inline]
> __vmalloc_area_node mm/vmalloc.c:3914 [inline]
> __vmalloc_node_range_noprof+0x7c7/0x1750 mm/vmalloc.c:4104
> __vmalloc_node_noprof+0xc2/0x110 mm/vmalloc.c:4165
> alloc_thread_stack_node kernel/fork.c:359 [inline]
> dup_task_struct+0x2aa/0x910 kernel/fork.c:929
> copy_process+0x7d9/0x3dc0 kernel/fork.c:2115
> fork_idle+0xb3/0x240 kernel/fork.c:2658
> idle_init kernel/smpboot.c:53 [inline]
> idle_threads_init+0xd0/0x150 kernel/smpboot.c:72
> smp_init+0x16/0x110 kernel/smp.c:1029
> kernel_init_freeable+0x289/0x3e0 init/main.c:1650
> kernel_init+0x1d/0x1d0 init/main.c:1548
> ret_from_fork+0x509/0xb70 arch/x86/kernel/process.c:158
> ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
>page_owner free stack trace missing
>
>Memory state around the buggy address:
> ffffc90000177d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ffffc90000177e00: 00 00 00 00 f1 f1 f1 f1 00 02 f2 f2 00 02 f2 f2
>>ffffc90000177e80: 00 02 f2 f2 00 f3 f2 f2 00 f3 f3 f3 00 00 00 00
> ^
> ffffc90000177f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> ffffc90000177f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>==================================================================
>
>
>
>
Thanks!