Skip to content

Commit 7e76b75

Browse files
AlekseiNikiforovIBMakpm00
authored andcommitted
mm/kmsan: fix kmsan kmalloc hook when no stack depots are allocated yet
If no stack depot is allocated yet, due to masking out __GFP_RECLAIM flags kmsan called from kmalloc cannot allocate stack depot. kmsan fails to record origin and report issues. This may result in KMSAN failing to report issues. Reusing flags from kmalloc without modifying them should be safe for kmsan. For example, such chain of calls is possible: test_uninit_kmalloc -> kmalloc -> __kmalloc_cache_noprof -> slab_alloc_node -> slab_post_alloc_hook -> kmsan_slab_alloc -> kmsan_internal_poison_memory. Only when it is called in a context without flags present should __GFP_RECLAIM flags be masked. With this change all kmsan tests start working reliably. Eric reported: : Yes, KMSAN seems to be at least partially broken currently. Besides the : fact that the kmsan KUnit test is currently failing (which I reported at : https://lore.kernel.org/r/20250911175145.GA1376@sol), I've confirmed that : the poly1305 KUnit test causes a KMSAN warning with Aleksei's patch : applied but does not cause a warning without it. The warning did get : reached via syzbot somehow : (https://lore.kernel.org/r/751b3d80293a6f599bb07770afcef24f623c7da0.1761026343.git.xiaopei01@kylinos.cn/), : so KMSAN must still work in some cases. But it didn't work for me. Link: https://lkml.kernel.org/r/20250930115600.709776-2-aleksei.nikiforov@linux.ibm.com Link: https://lkml.kernel.org/r/20251022030213.GA35717@sol Fixes: 97769a5 ("mm, bpf: Introduce try_alloc_pages() for opportunistic page allocation") Signed-off-by: Aleksei Nikiforov <aleksei.nikiforov@linux.ibm.com> Reviewed-by: Alexander Potapenko <glider@google.com> Tested-by: Eric Biggers <ebiggers@kernel.org> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Dmitriy Vyukov <dvyukov@google.com> Cc: Ilya Leoshkevich <iii@linux.ibm.com> Cc: Marco Elver <elver@google.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent fc745ff commit 7e76b75

3 files changed

Lines changed: 5 additions & 6 deletions

File tree

mm/kmsan/core.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,6 @@ depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags,
7272

7373
nr_entries = stack_trace_save(entries, KMSAN_STACK_DEPTH, 0);
7474

75-
/* Don't sleep. */
76-
flags &= ~(__GFP_DIRECT_RECLAIM | __GFP_KSWAPD_RECLAIM);
77-
7875
handle = stack_depot_save(entries, nr_entries, flags);
7976
return stack_depot_set_extra_bits(handle, extra);
8077
}

mm/kmsan/hooks.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ void kmsan_slab_free(struct kmem_cache *s, void *object)
8484
if (s->ctor)
8585
return;
8686
kmsan_enter_runtime();
87-
kmsan_internal_poison_memory(object, s->object_size, GFP_KERNEL,
87+
kmsan_internal_poison_memory(object, s->object_size,
88+
GFP_KERNEL & ~(__GFP_RECLAIM),
8889
KMSAN_POISON_CHECK | KMSAN_POISON_FREE);
8990
kmsan_leave_runtime();
9091
}
@@ -114,7 +115,8 @@ void kmsan_kfree_large(const void *ptr)
114115
kmsan_enter_runtime();
115116
page = virt_to_head_page((void *)ptr);
116117
KMSAN_WARN_ON(ptr != page_address(page));
117-
kmsan_internal_poison_memory((void *)ptr, page_size(page), GFP_KERNEL,
118+
kmsan_internal_poison_memory((void *)ptr, page_size(page),
119+
GFP_KERNEL & ~(__GFP_RECLAIM),
118120
KMSAN_POISON_CHECK | KMSAN_POISON_FREE);
119121
kmsan_leave_runtime();
120122
}

mm/kmsan/shadow.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ void kmsan_free_page(struct page *page, unsigned int order)
208208
return;
209209
kmsan_enter_runtime();
210210
kmsan_internal_poison_memory(page_address(page), page_size(page),
211-
GFP_KERNEL,
211+
GFP_KERNEL & ~(__GFP_RECLAIM),
212212
KMSAN_POISON_CHECK | KMSAN_POISON_FREE);
213213
kmsan_leave_runtime();
214214
}

0 commit comments

Comments
 (0)