mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
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>
This commit is contained in:
committed by
Andrew Morton
parent
d9f74cfb5a
commit
caf55fef61
@@ -638,7 +638,7 @@ void kasan_report_async(void)
|
||||
*/
|
||||
void kasan_non_canonical_hook(unsigned long addr)
|
||||
{
|
||||
unsigned long orig_addr;
|
||||
unsigned long orig_addr, user_orig_addr;
|
||||
const char *bug_type;
|
||||
|
||||
/*
|
||||
@@ -650,6 +650,9 @@ void kasan_non_canonical_hook(unsigned long addr)
|
||||
|
||||
orig_addr = (unsigned long)kasan_shadow_to_mem((void *)addr);
|
||||
|
||||
/* Strip pointer tag before comparing against userspace ranges */
|
||||
user_orig_addr = (unsigned long)set_tag((void *)orig_addr, 0);
|
||||
|
||||
/*
|
||||
* For faults near the shadow address for NULL, we can be fairly certain
|
||||
* that this is a KASAN shadow memory access.
|
||||
@@ -661,11 +664,13 @@ void kasan_non_canonical_hook(unsigned long addr)
|
||||
* address, but make it clear that this is not necessarily what's
|
||||
* actually going on.
|
||||
*/
|
||||
if (orig_addr < PAGE_SIZE)
|
||||
if (user_orig_addr < PAGE_SIZE) {
|
||||
bug_type = "null-ptr-deref";
|
||||
else if (orig_addr < TASK_SIZE)
|
||||
orig_addr = user_orig_addr;
|
||||
} else if (user_orig_addr < TASK_SIZE) {
|
||||
bug_type = "probably user-memory-access";
|
||||
else if (addr_in_shadow((void *)addr))
|
||||
orig_addr = user_orig_addr;
|
||||
} else if (addr_in_shadow((void *)addr))
|
||||
bug_type = "probably wild-memory-access";
|
||||
else
|
||||
bug_type = "maybe wild-memory-access";
|
||||
|
||||
Reference in New Issue
Block a user