Message ID | 20231213233605.661251-16-iii@linux.ibm.com (mailing list archive) |
---|---|
State | Handled Elsewhere |
Headers | show |
Series | kmsan: Enable on s390 | expand |
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@linux.ibm.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> > --- > 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)
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)
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@linux.ibm.com> --- mm/slub.c | 2 ++ 1 file changed, 2 insertions(+)