December 3, 2025 at 23:18, "Andrey Konovalov" <andreyknvl@gmail.com mailto:andreyknvl@gmail.com?to=%22Andrey%20Konovalov%22%20%3Candreyknvl%40gmail.com%3E > wrote:
From: Jiayuan Chen jiayuan.chen@linux.dev Subject: mm/kasan: fix incorrect unpoisoning in vrealloc for KASAN Date: Fri, 28 Nov 2025 19:15:14 +0800
Hi Jiayuan,
Please CC kasan-dev@googlegroups.com when sending KASAN patches.
Sorry about that. I missed it.
Syzkaller reported a memory out-of-bounds bug [1]. This patch fixes two issues:
- In vrealloc, we were missing the KASAN_VMALLOC_VM_ALLOC flag when
unpoisoning the extended region. This flag is required to correctly associate the allocation with KASAN's vmalloc tracking.
Note: In contrast, vzalloc (via __vmalloc_node_range_noprof) explicitly sets KASAN_VMALLOC_VM_ALLOC and calls kasan_unpoison_vmalloc() with it. vrealloc must behave consistently — especially when reusing existing vmalloc regions — to ensure KASAN can track allocations correctly.
- When vrealloc reuses an existing vmalloc region (without allocating new
pages), KASAN previously generated a new tag, which broke tag-based memory access tracking. We now add a 'reuse_tag' parameter to __kasan_unpoison_vmalloc() to preserve the original tag in such cases.
I think we actually could assign a new tag to detect accesses through the old pointer. Just gotta retag the whole region with this tag. But this is a separate thing; filed https://bugzilla.kernel.org/show_bug.cgi?id=220829 for this.
Thank you for your advice. I tested the following modification, and it works.
if (size <= alloced_size) { - kasan_unpoison_vmalloc(p + old_size, size - old_size, - KASAN_VMALLOC_PROT_NORMAL); + p = kasan_unpoison_vmalloc(p, size, + KASAN_VMALLOC_PROT_NORMAL | KASAN_VMALLOC_VM_ALLOC); /* * No need to zero memory here, as unused memory will have * already been zeroed at initial allocation time or during * realloc shrink time. */ vm->requested_size = size; return (void *)p; }
[...]
Would be good to have tests for vrealloc too. Filed https://bugzilla.kernel.org/show_bug.cgi?id=220830 for this.
Thanks, I will add test for vrealloc in kasan_test_c.c.
kasan_unpoison(start, size, false); return (void *)start; } --- a/mm/vmalloc.c~mm-kasan-fix-incorrect-unpoisoning-in-vrealloc-for-kasan +++ a/mm/vmalloc.c @@ -4175,8 +4175,8 @@ void *vrealloc_node_align_noprof(const v
- We already have the bytes available in the allocation; use them.
*/ if (size <= alloced_size) {
- kasan_unpoison_vmalloc(p + old_size, size - old_size,
- KASAN_VMALLOC_PROT_NORMAL);
- kasan_unpoison_vrealloc(p, size,
- KASAN_VMALLOC_PROT_NORMAL | KASAN_VMALLOC_VM_ALLOC);
Orthogonal to this series, but is it allowed to call vrealloc on executable mappings? If so, we need to only set KASAN_VMALLOC_PROT_NORMAL for non-executable mappings. And kasan_poison_vmalloc should not be called for them as well (so we likely need to pass a protection flag to it to avoid exposing this logic).
Currently, vmalloc implicitly sets kasan_flags |= KASAN_VMALLOC_VM_ALLOC, meaning the allocated memory cannot be used for executable code segments. I think we could require users to explicitly pass a flag indicating whether KASAN should be enabled — this would make the function’s intent clearer and more explicit to the caller.
Kees, I see you worked on vrealloc annotations, do you happen to know?