Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

kasan: fix bug type classification for SW_TAGS mode

kasan_non_canonical_hook() derives orig_addr from kasan_shadow_to_mem(),
but the pointer tag may remain in the top byte. In SW_TAGS mode this
tagged address is compared against PAGE_SIZE and TASK_SIZE, which leads to
incorrect bug classification.

As a result, NULL pointer dereferences may be reported as
"wild-memory-access".

Strip the tag before performing these range checks and use the untagged
value when reporting addresses in these ranges.

Before:
[ ] Unable to handle kernel paging request at virtual address ffef800000000000
[ ] KASAN: maybe wild-memory-access in range [0xff00000000000000-0xff0000000000000f]

After:
[ ] Unable to handle kernel paging request at virtual address ffef800000000000
[ ] KASAN: null-ptr-deref in range [0x0000000000000000-0x000000000000000f]

Link: https://lkml.kernel.org/r/20260305185659.20807-1-ryabinin.a.a@gmail.com
Signed-off-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Andrey Ryabinin and committed by
Andrew Morton
caf55fef d9f74cfb

+9 -4
+9 -4
mm/kasan/report.c
··· 638 638 */ 639 639 void kasan_non_canonical_hook(unsigned long addr) 640 640 { 641 - unsigned long orig_addr; 641 + unsigned long orig_addr, user_orig_addr; 642 642 const char *bug_type; 643 643 644 644 /* ··· 649 649 return; 650 650 651 651 orig_addr = (unsigned long)kasan_shadow_to_mem((void *)addr); 652 + 653 + /* Strip pointer tag before comparing against userspace ranges */ 654 + user_orig_addr = (unsigned long)set_tag((void *)orig_addr, 0); 652 655 653 656 /* 654 657 * For faults near the shadow address for NULL, we can be fairly certain ··· 664 661 * address, but make it clear that this is not necessarily what's 665 662 * actually going on. 666 663 */ 667 - if (orig_addr < PAGE_SIZE) 664 + if (user_orig_addr < PAGE_SIZE) { 668 665 bug_type = "null-ptr-deref"; 669 - else if (orig_addr < TASK_SIZE) 666 + orig_addr = user_orig_addr; 667 + } else if (user_orig_addr < TASK_SIZE) { 670 668 bug_type = "probably user-memory-access"; 671 - else if (addr_in_shadow((void *)addr)) 669 + orig_addr = user_orig_addr; 670 + } else if (addr_in_shadow((void *)addr)) 672 671 bug_type = "probably wild-memory-access"; 673 672 else 674 673 bug_type = "maybe wild-memory-access";