Messages in this thread | | | From | Andrey Konovalov <> | Date | Tue, 20 Aug 2019 20:23:17 +0200 | Subject | Re: [PATCH] mm/kasan: Fix false positive invalid-free reports with CONFIG_KASAN_SW_TAGS=y |
| |
On Mon, Aug 19, 2019 at 7:26 PM Andrey Ryabinin <aryabinin@virtuozzo.com> wrote: > > The code like this: > > ptr = kmalloc(size, GFP_KERNEL); > page = virt_to_page(ptr); > offset = offset_in_page(ptr); > kfree(page_address(page) + offset); > > may produce false-positive invalid-free reports on the kernel with > CONFIG_KASAN_SW_TAGS=y. > > In the example above we loose the original tag assigned to 'ptr', > so kfree() gets the pointer with 0xFF tag. In kfree() we check that > 0xFF tag is different from the tag in shadow hence print false report. > > Instead of just comparing tags, do the following: > 1) Check that shadow doesn't contain KASAN_TAG_INVALID. Otherwise it's > double-free and it doesn't matter what tag the pointer have. > > 2) If pointer tag is different from 0xFF, make sure that tag in the shadow > is the same as in the pointer. > > Fixes: 7f94ffbc4c6a ("kasan: add hooks implementation for tag-based mode") > Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com> > Reported-by: Walter Wu <walter-zh.wu@mediatek.com> > Reported-by: Mark Rutland <mark.rutland@arm.com> > Cc: <stable@vger.kernel.org>
Reviewed-by: Andrey Konovalov <andreyknvl@google.com>
> --- > mm/kasan/common.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > diff --git a/mm/kasan/common.c b/mm/kasan/common.c > index 895dc5e2b3d5..3b8cde0cb5b2 100644 > --- a/mm/kasan/common.c > +++ b/mm/kasan/common.c > @@ -406,8 +406,14 @@ static inline bool shadow_invalid(u8 tag, s8 shadow_byte) > if (IS_ENABLED(CONFIG_KASAN_GENERIC)) > return shadow_byte < 0 || > shadow_byte >= KASAN_SHADOW_SCALE_SIZE; > - else > - return tag != (u8)shadow_byte; > + > + /* else CONFIG_KASAN_SW_TAGS: */ > + if ((u8)shadow_byte == KASAN_TAG_INVALID) > + return true; > + if ((tag != KASAN_TAG_KERNEL) && (tag != (u8)shadow_byte)) > + return true; > + > + return false; > } > > static bool __kasan_slab_free(struct kmem_cache *cache, void *object, > -- > 2.21.0 >
| |