On 12/14/23 00:24, Ilya Leoshkevich wrote: > Even though the KMSAN warnings generated by memchr_inv() are suppressed > by metadata_access_enable(), its return value may still be poisoned. > > The reason is that the last iteration of memchr_inv() returns > `*start != value ? start : NULL`, where *start is poisoned. Because of > this, somewhat counterintuitively, the shadow value computed by > visitSelectInst() is equal to `(uintptr_t)start`. > > The intention behind guarding memchr_inv() behind > metadata_access_enable() is to touch poisoned metadata without > triggering KMSAN, so unpoison its return value. > > Signed-off-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> Acked-by: Vlastimil Babka <vbabka@xxxxxxx> > --- > mm/slub.c | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/mm/slub.c b/mm/slub.c > index 2d29d368894c..802702748925 100644 > --- a/mm/slub.c > +++ b/mm/slub.c > @@ -1076,6 +1076,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct slab *slab, > metadata_access_enable(); > fault = memchr_inv(kasan_reset_tag(start), value, bytes); > metadata_access_disable(); > + kmsan_unpoison_memory(&fault, sizeof(fault)); > if (!fault) > return 1; > > @@ -1182,6 +1183,7 @@ static void slab_pad_check(struct kmem_cache *s, struct slab *slab) > metadata_access_enable(); > fault = memchr_inv(kasan_reset_tag(pad), POISON_INUSE, remainder); > metadata_access_disable(); > + kmsan_unpoison_memory(&fault, sizeof(fault)); > if (!fault) > return; > while (end > fault && end[-1] == POISON_INUSE)