From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from xmbghk7.mail.qq.com (xmbghk7.mail.qq.com [43.163.128.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE5163B1B3 for ; Sun, 28 Jun 2026 19:03:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=43.163.128.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782673386; cv=none; b=MUzRbR876MEF/kmNvdOWiiJGcQf/zI4FyfbQG0aUzciW9VDnG1NzRDKe0cbJZfNRFQChfqW5qLab4adT1u61RvMbPd6P6c6EjnmrASbHwCdsTnU/gp3J4lf/75Cg+T8R7unVk6V1NpmZoUGmANUk8VWTPy2KE/vRDbrjDXSePac= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782673386; c=relaxed/simple; bh=gu69BDg/+fz80XwohwxcPL1VMq/yw8lVB3Aw2DnYxGI=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=kmit/ZSY33eU15Js068tkhYQaLVNfwy93POoeHNeF4hXFf+/cbqm7mI3Aq9IU7u90TNJ+sCoyWRWsZ64gAWgn/NOklnkfMv8YKxGGN6diXfIJ2C2SeKkkknp/VUiYO2jq2WZWnnIyTagMU+d5nz2FGHK6UAy0jyxexz9irYPO8k= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com; spf=pass smtp.mailfrom=qq.com; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b=KAajApia; arc=none smtp.client-ip=43.163.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=qq.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=qq.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=qq.com header.i=@qq.com header.b="KAajApia" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512; t=1782673380; bh=Q0OuEOSBTnle59S1VFKjbe+83DfHFSINdzolkLWYgoQ=; h=Date:Subject:To:Cc:References:From:In-Reply-To; b=KAajApia6z9ja7abXqtWccH4QFZqVEK10lyKiosuIoDzoCvxCr6p6StQNZzCss1Kc Gh6bYDuD3zZnVvwYgKXjT9p+lWAXhEB7vPCEEDoToA5KIE7M65vRHMEsC3xIFjeG3o oJ4nN4wXMbmM2BaFTov5Nnf9RpSXRg8O4QXkdORs= Received: from [192.168.1.102] ([223.77.180.178]) by newxmesmtplogicsvrsza53-0.qq.com (NewEsmtp) with SMTP id B91262A; Mon, 29 Jun 2026 03:02:57 +0800 X-QQ-mid: xmsmtpt1782673377th0bbo7p1 Message-ID: X-QQ-XMAILINFO: OVFdYp27KdlJLKFcKUe8y9aZJpIfcITC6t8mYIYmeMYasdnVQ4h8Vz6weQBmUX gKOUX61b+6G8I1wVs0VueEAE1FwnChTnv/JGNwxv5JY8BcKscaMvpvFrRYHN7o3+umhNmzdvhCA4 6ss7xont/SwVNXakohJivOuvRkGvCRm2KRcbTM8Db7ohgg86ivB7YtaH+5HGiFATEIH8A6GNCxcS CmM3vnoF6vWXJWtl2VltQbmGioRooApGkyx0qbkCT+I3absfLsoNh3CI4XctLqcNf1E+HfwkEFpW +sw16BsbZhSk2I7XiwrPAtIqUMEYxpssBsIk3kkZlMboX9Er6OQfaxOm3MeoPGukC9M4Y+L8umWw Sm4qpZrKcd2dcq+t7WI9yLg6ULAuxeWoTbHGCVuKGB4urJLTZsKSys8f7MIf6MfZru+dZRPNY1j8 LgkKRcIwd0zF/DqXianr6fPdAqTHNocoqpgSnzrfSirHLm1EiMR5pPWD7sudvKjP2sex2SKixBB4 yKrHHpnFTBoWZgwv8Iam3/1AiivextvnJBlQ3KBp+MWJU4hjGcMGBw+dgzs9441QnXYbfv2hOq/a sAwa9sXpNW2BeoEsL29geyI1FNdubYzgAEGHeOfGUQ0gsUVpls8mMBGEIzmiqcaU7Et91atmkgeY rmuJnXQrI/Iv1u1Cw0GFHj9e6UUCvMIFjWjj9IhX/VvI9kNlPVJ6GSUdc7NIb+1TlYZ15DhELbR7 bnNlp4iJo4rz1cDDnl6fT9GMAOrecs1l3N79BCZx+F/2KkFunUzutU0Isn/ySEjNgg0pJWzbwam/ /DHGRhUiPeWz//q9MwrBNmrvzRINOh7f2PDL8b9reUJXYWlLo6tPpTNkdiqC/0EpnWe8FrWnL/p3 0WMZExmIVrpbTfQn/cJ7Nu81K78TF5K92heLgkYxSqzZ9Wf4Po7wYmc6RBXaRdvR8RFSK+WKockh Hkh+W5sJ8RmNaMoSW/mFAIIkQuZgyFjzqmSMKYNN81NnGS2rNDJsgp8fvmYS+rmH2XI7A8dj/T5i w3QmMprpv/hMmOTEt4FZNbap9VzZqIBB3Q0dGzBweVnt2c3PTbU0IgNJ/KX4bc8Bf3bJrBZQ== X-QQ-XMRINFO: Mp0Kj//9VHAxzExpfF+O8yhSrljjwrznVg== X-OQ-MSGID: Date: Mon, 29 Jun 2026 03:02:57 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v3] riscv: stacktrace: fix stack-out-of-bounds in walk_stackframe() To: Jiakai Xu , linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org Cc: Albert Ou , Alexandre Ghiti , Chunyan Zhang , Matthew Bystrin , Palmer Dabbelt , Paul Walmsley , Rui Qi , Samuel Holland , Jiakai Xu References: <20260625123906.211981-1-xujiakai2025@iscas.ac.cn> From: XIAO WU In-Reply-To: <20260625123906.211981-1-xujiakai2025@iscas.ac.cn> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi Jiakai, I came across the Sashiko AI review of this patch and was able to reproduce the overflow_stack OOB issue it flagged — a KASAN stack-out-of-bounds in walk_stackframe() on riscv64 QEMU. The Sashiko review is at: https://sashiko.dev/#/patchset/20260625123906.211981-1-xujiakai2025@iscas.ac.cn > @@ -52,19 +56,32 @@ void notrace walk_stackframe(struct task_struct *task, struct pt_regs *regs, >          pc = task->thread.ra; >      } > > +    if (!task) > +        task = current; > + > +    if (sp >= (unsigned long)task_stack_page(task) && > +        sp < (unsigned long)task_stack_page(task) + THREAD_SIZE) { > +        high = (unsigned long)task_pt_regs(task); > +    } else if (IS_ENABLED(CONFIG_IRQ_STACKS)) { > +        high = (unsigned long)this_cpu_read(irq_stack_ptr) + > +               IRQ_STACK_SIZE; > +    } else { > +        high = (unsigned long)task_pt_regs(task); > +    } When the stack pointer falls outside the task stack — for example when unwinding from the overflow_stack during a stack overflow panic, or when reading /proc//stack for a remote task whose saved SP happens to be on the overflow_stack — this code falls through to the `IS_ENABLED(CONFIG_IRQ_STACKS)` branch and uses the IRQ stack boundary as the upper limit. The IRQ stack is 32KB (IRQ_STACK_SIZE) while the overflow_stack is only 4KB (OVERFLOW_STACK_SIZE).  Using the IRQ stack boundary when the SP is actually on the overflow_stack lets the unwinder read well past the end of the valid overflow_stack allocation, triggering a KASAN stack-out-of-bounds. === Reproduction === Kernel: 6.17.0-rc3-gab53ade87879 #1 PREEMPT Arch:   riscv64 (qemu-system-riscv64, riscv-virtio,qemu DT) Config: CONFIG_KASAN=y Trigger: read /proc//stack for a remote task (e.g. via ptrace). === Crash Log === [  862.045445][ T5937] BUG: KASAN: stack-out-of-bounds in walk_stackframe+0x5c4/0x66e [  862.046336][ T5937] Read of size 8 at addr ff200000076676c8 by task poc/5937 [  862.048426][ T5937] CPU: 1 UID: 0 PID: 5937 Comm: poc Not tainted 6.17.0-rc3-gab53ade87879 #1 PREEMPT [  862.048684][ T5937] Hardware name: riscv-virtio,qemu (DT) [  862.048684][ T5937] Call Trace: [  862.049044][ T5937] [] dump_backtrace+0x2e/0x3c [  862.049257][ T5937] [] show_stack+0x30/0x3c [  862.049427][ T5937] [] dump_stack_lvl+0x11a/0x1b0 [  862.049628][ T5937] [] print_report+0x29a/0x5b8 [  862.049838][ T5937] [] kasan_report+0xf0/0x21c [  862.050031][ T5937] [] __asan_report_load8_noabort+0x12/0x1a [  862.050267][ T5937] [] walk_stackframe+0x5c4/0x66e [  862.050432][ T5937] [] arch_stack_walk+0x1c/0x26 [  862.050644][ T5937] [] stack_trace_save_tsk+0x164/0x1f2 [  862.050867][ T5937] [] proc_pid_stack+0x170/0x282 [  862.051032][ T5937] [] proc_single_show+0xea/0x1ca [  862.051205][ T5937] [] seq_read_iter+0x438/0x1098 [  862.051585][ T5937] [] vfs_read+0x2f0/0xaf8 [  862.052052][ T5937] [] ksys_read+0x126/0x238 [  862.052550][ T5937] [] handle_exception+0x150/0x15c [  862.053115][ T5937] The buggy address belongs to a 8-page vmalloc region [  862.093883][ T5937] ================================================================== === PoC === Build:  riscv64-linux-gnu-gcc -o poc poc.c -static Run:    ./poc    (on riscv64) // SPDX-License-Identifier: GPL-2.0-only // PoC: Trigger KASAN stack-out-of-bounds in walk_stackframe() on RISC-V #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static const char *prog; static void fail(const char *msg) {     fprintf(stderr, "[FAIL] %s: %s: %m\n", msg, prog);     exit(1); } static void info(const char *msg) {     fprintf(stderr, "[INFO] %s\n", msg); } static void check_dmesg(const char *label) {     char line[4096];     FILE *f;     int found = 0;     f = popen("dmesg 2>/dev/null | tail -200", "r");     if (!f) return;     while (fgets(line, sizeof(line), f)) {         if (strstr(line, "KASAN") ||             strstr(line, "stack-out-of-bounds") ||             strstr(line, "walk_stackframe") ||             strstr(line, "out-of-bounds") ||             strstr(line, "Oops") ||             strstr(line, "kernel BUG") ||             strstr(line, "Kernel panic") ||             strstr(line, "Call Trace")) {             if (!found) {                 fprintf(stderr, "\n=== Dmesg output after %s ===\n", label);                 found = 1;             }             fprintf(stderr, "%s", line);         }     }     pclose(f);     if (found) fprintf(stderr, "=== End dmesg ===\n\n"); } /* Approach: self stack trace with deep directory recursion */ static void try_self_stack_trace(void) {     pid_t pid = fork();     if (pid < 0) return;     if (pid == 0) {         char dir[256];         int i;         getcwd(dir, sizeof(dir));         for (i = 0; i < 500; i++) {             char subdir[300];             snprintf(subdir, sizeof(subdir), "%s/d%d", dir, i);             mkdir(subdir, 0755);             chdir(subdir);         }         for (i = 0; i < 1000; i++) {             FILE *f = fopen("/proc/self/stack", "r");             if (f) {                 char buf[4096];                 while (fgets(buf, sizeof(buf), f)) { }                 fclose(f);             }             char path[64];             snprintf(path, sizeof(path), "/proc/%d/stack", getpid());             f = fopen(path, "r");             if (f) {                 char buf[4096];                 while (fgets(buf, sizeof(buf), f)) { }                 fclose(f);             }         }         _exit(0);     }     waitpid(pid, NULL, 0);     check_dmesg("self_stack_trace"); } /* Approach: remote task stack trace via ptrace */ static void try_remote_task(void) {     pid_t child = fork();     int status, i;     if (child < 0) return;     if (child == 0) {         if (ptrace(PTRACE_TRACEME, 0, NULL, NULL) < 0)             _exit(1);         raise(SIGSTOP);         struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 };         nanosleep(&ts, NULL);         _exit(0);     }     waitpid(child, &status, 0);     if (!WIFSTOPPED(status)) waitpid(child, &status, 0);     for (i = 0; i < 100; i++) {         char path[64];         FILE *f;         snprintf(path, sizeof(path), "/proc/%d/stack", child);         f = fopen(path, "r");         if (f) {             char buf[4096];             while (fgets(buf, sizeof(buf), f)) { }             fclose(f);         }     }     ptrace(PTRACE_CONT, child, NULL, NULL);     waitpid(child, &status, 0);     check_dmesg("remote_task"); } int main(int argc, char **argv) {     prog = argv[0];     info("=== RISC-V walk_stackframe() stack OOB PoC ===");     info("Bug: overflow_stack (4KB) unwinding uses IRQ stack bound (32KB)");     info("");     system("dmesg -c > /dev/null 2>&1 || true");     try_self_stack_trace();     try_remote_task();     info("Final dmesg check...");     check_dmesg("final");     info("PoC completed.");     return 0; } Thanks, Xiao