mm-commits.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: akpm@linux-foundation.org, andreyknvl@google.com,
	aryabinin@virtuozzo.com, Branislav.Rankov@arm.com,
	catalin.marinas@arm.com, dvyukov@google.com, elver@google.com,
	eugenis@google.com, glider@google.com, gor@linux.ibm.com,
	kevin.brodsky@arm.com, linux-mm@kvack.org,
	mm-commits@vger.kernel.org, torvalds@linux-foundation.org,
	vincenzo.frascino@arm.com, will.deacon@arm.com
Subject: [patch 38/60] kasan, mm: reset tags when accessing metadata
Date: Tue, 22 Dec 2020 12:02:17 -0800	[thread overview]
Message-ID: <20201222200217.9hOE1mcZ2%akpm@linux-foundation.org> (raw)
In-Reply-To: <20201222115844.d30aaef7df6f5b120d3e0c3d@linux-foundation.org>

From: Andrey Konovalov <andreyknvl@google.com>
Subject: kasan, mm: reset tags when accessing metadata

Kernel allocator code accesses metadata for slab objects, that may lie
out-of-bounds of the object itself, or be accessed when an object is
freed.  Such accesses trigger tag faults and lead to false-positive
reports with hardware tag-based KASAN.

Software KASAN modes disable instrumentation for allocator code via
KASAN_SANITIZE Makefile macro, and rely on kasan_enable/disable_current()
annotations which are used to ignore KASAN reports.

With hardware tag-based KASAN neither of those options are available, as
it doesn't use compiler instrumetation, no tag faults are ignored, and MTE
is disabled after the first one.

Instead, reset tags when accessing metadata (currently only for SLUB).

Link: https://lkml.kernel.org/r/a0f3cefbc49f34c843b664110842de4db28179d0.1606161801.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Acked-by: Marco Elver <elver@google.com>
Reviewed-by: Alexander Potapenko <glider@google.com>
Tested-by: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Branislav Rankov <Branislav.Rankov@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Evgenii Stepanov <eugenis@google.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---

 mm/page_alloc.c  |    4 +++-
 mm/page_poison.c |    2 +-
 mm/slub.c        |   29 ++++++++++++++++-------------
 3 files changed, 20 insertions(+), 15 deletions(-)

--- a/mm/page_alloc.c~kasan-mm-reset-tags-when-accessing-metadata
+++ a/mm/page_alloc.c
@@ -1204,8 +1204,10 @@ static void kernel_init_free_pages(struc
 
 	/* s390's use of memset() could override KASAN redzones. */
 	kasan_disable_current();
-	for (i = 0; i < numpages; i++)
+	for (i = 0; i < numpages; i++) {
+		page_kasan_tag_reset(page + i);
 		clear_highpage(page + i);
+	}
 	kasan_enable_current();
 }
 
--- a/mm/page_poison.c~kasan-mm-reset-tags-when-accessing-metadata
+++ a/mm/page_poison.c
@@ -25,7 +25,7 @@ static void poison_page(struct page *pag
 
 	/* KASAN still think the page is in-use, so skip it. */
 	kasan_disable_current();
-	memset(addr, PAGE_POISON, PAGE_SIZE);
+	memset(kasan_reset_tag(addr), PAGE_POISON, PAGE_SIZE);
 	kasan_enable_current();
 	kunmap_atomic(addr);
 }
--- a/mm/slub.c~kasan-mm-reset-tags-when-accessing-metadata
+++ a/mm/slub.c
@@ -249,7 +249,7 @@ static inline void *freelist_ptr(const s
 {
 #ifdef CONFIG_SLAB_FREELIST_HARDENED
 	/*
-	 * When CONFIG_KASAN_SW_TAGS is enabled, ptr_addr might be tagged.
+	 * When CONFIG_KASAN_SW/HW_TAGS is enabled, ptr_addr might be tagged.
 	 * Normally, this doesn't cause any issues, as both set_freepointer()
 	 * and get_freepointer() are called with a pointer with the same tag.
 	 * However, there are some issues with CONFIG_SLUB_DEBUG code. For
@@ -275,6 +275,7 @@ static inline void *freelist_dereference
 
 static inline void *get_freepointer(struct kmem_cache *s, void *object)
 {
+	object = kasan_reset_tag(object);
 	return freelist_dereference(s, object + s->offset);
 }
 
@@ -304,6 +305,7 @@ static inline void set_freepointer(struc
 	BUG_ON(object == fp); /* naive detection of double free or corruption */
 #endif
 
+	freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr);
 	*(void **)freeptr_addr = freelist_ptr(s, fp, freeptr_addr);
 }
 
@@ -538,8 +540,8 @@ static void print_section(char *level, c
 			  unsigned int length)
 {
 	metadata_access_enable();
-	print_hex_dump(level, text, DUMP_PREFIX_ADDRESS, 16, 1, addr,
-			length, 1);
+	print_hex_dump(level, kasan_reset_tag(text), DUMP_PREFIX_ADDRESS,
+			16, 1, addr, length, 1);
 	metadata_access_disable();
 }
 
@@ -570,7 +572,7 @@ static struct track *get_track(struct km
 
 	p = object + get_info_end(s);
 
-	return p + alloc;
+	return kasan_reset_tag(p + alloc);
 }
 
 static void set_track(struct kmem_cache *s, void *object,
@@ -583,7 +585,8 @@ static void set_track(struct kmem_cache
 		unsigned int nr_entries;
 
 		metadata_access_enable();
-		nr_entries = stack_trace_save(p->addrs, TRACK_ADDRS_COUNT, 3);
+		nr_entries = stack_trace_save(kasan_reset_tag(p->addrs),
+					      TRACK_ADDRS_COUNT, 3);
 		metadata_access_disable();
 
 		if (nr_entries < TRACK_ADDRS_COUNT)
@@ -747,7 +750,7 @@ static __printf(3, 4) void slab_err(stru
 
 static void init_object(struct kmem_cache *s, void *object, u8 val)
 {
-	u8 *p = object;
+	u8 *p = kasan_reset_tag(object);
 
 	if (s->flags & SLAB_RED_ZONE)
 		memset(p - s->red_left_pad, val, s->red_left_pad);
@@ -777,7 +780,7 @@ static int check_bytes_and_report(struct
 	u8 *addr = page_address(page);
 
 	metadata_access_enable();
-	fault = memchr_inv(start, value, bytes);
+	fault = memchr_inv(kasan_reset_tag(start), value, bytes);
 	metadata_access_disable();
 	if (!fault)
 		return 1;
@@ -873,7 +876,7 @@ static int slab_pad_check(struct kmem_ca
 
 	pad = end - remainder;
 	metadata_access_enable();
-	fault = memchr_inv(pad, POISON_INUSE, remainder);
+	fault = memchr_inv(kasan_reset_tag(pad), POISON_INUSE, remainder);
 	metadata_access_disable();
 	if (!fault)
 		return 1;
@@ -1118,7 +1121,7 @@ void setup_page_debug(struct kmem_cache
 		return;
 
 	metadata_access_enable();
-	memset(addr, POISON_INUSE, page_size(page));
+	memset(kasan_reset_tag(addr), POISON_INUSE, page_size(page));
 	metadata_access_disable();
 }
 
@@ -1566,10 +1569,10 @@ static inline bool slab_free_freelist_ho
 			 * Clear the object and the metadata, but don't touch
 			 * the redzone.
 			 */
-			memset(object, 0, s->object_size);
+			memset(kasan_reset_tag(object), 0, s->object_size);
 			rsize = (s->flags & SLAB_RED_ZONE) ? s->red_left_pad
 							   : 0;
-			memset((char *)object + s->inuse, 0,
+			memset((char *)kasan_reset_tag(object) + s->inuse, 0,
 			       s->size - s->inuse - rsize);
 
 		}
@@ -2881,10 +2884,10 @@ redo:
 		stat(s, ALLOC_FASTPATH);
 	}
 
-	maybe_wipe_obj_freeptr(s, object);
+	maybe_wipe_obj_freeptr(s, kasan_reset_tag(object));
 
 	if (unlikely(slab_want_init_on_alloc(gfpflags, s)) && object)
-		memset(object, 0, s->object_size);
+		memset(kasan_reset_tag(object), 0, s->object_size);
 
 	slab_post_alloc_hook(s, objcg, gfpflags, 1, &object);
 
_

  parent reply	other threads:[~2020-12-22 20:02 UTC|newest]

Thread overview: 62+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-22 19:58 incoming Andrew Morton
2020-12-22 20:00 ` [patch 01/60] kasan: drop unnecessary GPL text from comment headers Andrew Morton
2020-12-22 20:00 ` [patch 02/60] kasan: KASAN_VMALLOC depends on KASAN_GENERIC Andrew Morton
2020-12-22 20:00 ` [patch 03/60] kasan: group vmalloc code Andrew Morton
2020-12-22 20:00 ` [patch 04/60] kasan: shadow declarations only for software modes Andrew Morton
2020-12-22 20:00 ` [patch 05/60] kasan: rename (un)poison_shadow to (un)poison_range Andrew Morton
2020-12-22 20:00 ` [patch 06/60] kasan: rename KASAN_SHADOW_* to KASAN_GRANULE_* Andrew Morton
2020-12-22 20:00 ` [patch 07/60] kasan: only build init.c for software modes Andrew Morton
2020-12-22 20:00 ` [patch 08/60] kasan: split out shadow.c from common.c Andrew Morton
2020-12-22 20:00 ` [patch 09/60] kasan: define KASAN_MEMORY_PER_SHADOW_PAGE Andrew Morton
2020-12-22 20:00 ` [patch 10/60] kasan: rename report and tags files Andrew Morton
2020-12-22 20:00 ` [patch 11/60] kasan: don't duplicate config dependencies Andrew Morton
2020-12-22 20:00 ` [patch 12/60] kasan: hide invalid free check implementation Andrew Morton
2020-12-22 20:00 ` [patch 13/60] kasan: decode stack frame only with KASAN_STACK_ENABLE Andrew Morton
2020-12-22 20:00 ` [patch 14/60] kasan, arm64: only init shadow for software modes Andrew Morton
2020-12-22 20:00 ` [patch 15/60] kasan, arm64: only use kasan_depth " Andrew Morton
2020-12-22 20:01 ` [patch 16/60] kasan, arm64: move initialization message Andrew Morton
2020-12-22 20:01 ` [patch 17/60] kasan, arm64: rename kasan_init_tags and mark as __init Andrew Morton
2020-12-22 20:01 ` [patch 18/60] kasan: rename addr_has_shadow to addr_has_metadata Andrew Morton
2020-12-22 20:01 ` [patch 19/60] kasan: rename print_shadow_for_address to print_memory_metadata Andrew Morton
2020-12-22 20:01 ` [patch 20/60] kasan: rename SHADOW layout macros to META Andrew Morton
2020-12-22 20:01 ` [patch 21/60] kasan: separate metadata_fetch_row for each mode Andrew Morton
2020-12-22 20:01 ` [patch 22/60] kasan: introduce CONFIG_KASAN_HW_TAGS Andrew Morton
2020-12-22 20:01 ` [patch 23/60] arm64: enable armv8.5-a asm-arch option Andrew Morton
2020-12-22 20:01 ` [patch 24/60] arm64: mte: add in-kernel MTE helpers Andrew Morton
2020-12-22 20:01 ` [patch 25/60] arm64: mte: reset the page tag in page->flags Andrew Morton
2020-12-22 20:01 ` [patch 26/60] arm64: mte: add in-kernel tag fault handler Andrew Morton
2020-12-22 20:01 ` [patch 27/60] arm64: kasan: allow enabling in-kernel MTE Andrew Morton
2020-12-22 20:01 ` [patch 28/60] arm64: mte: convert gcr_user into an exclude mask Andrew Morton
2020-12-22 20:01 ` [patch 29/60] arm64: mte: switch GCR_EL1 in kernel entry and exit Andrew Morton
2020-12-22 20:01 ` [patch 30/60] kasan, mm: untag page address in free_reserved_area Andrew Morton
2020-12-22 20:01 ` [patch 31/60] arm64: kasan: align allocations for HW_TAGS Andrew Morton
2020-12-22 20:01 ` [patch 32/60] arm64: kasan: add arch layer for memory tagging helpers Andrew Morton
2020-12-22 20:01 ` [patch 33/60] kasan: define KASAN_GRANULE_SIZE for HW_TAGS Andrew Morton
2020-12-22 20:02 ` [patch 34/60] kasan, x86, s390: update undef CONFIG_KASAN Andrew Morton
2020-12-22 20:02 ` [patch 35/60] kasan, arm64: expand CONFIG_KASAN checks Andrew Morton
2020-12-22 20:02 ` [patch 36/60] kasan, arm64: implement HW_TAGS runtime Andrew Morton
2020-12-22 20:02 ` [patch 37/60] kasan, arm64: print report from tag fault handler Andrew Morton
2020-12-22 20:02 ` Andrew Morton [this message]
2020-12-22 20:02 ` [patch 39/60] kasan, arm64: enable CONFIG_KASAN_HW_TAGS Andrew Morton
2020-12-22 20:02 ` [patch 40/60] kasan: add documentation for hardware tag-based mode Andrew Morton
2020-12-22 20:02 ` [patch 41/60] kselftest/arm64: check GCR_EL1 after context switch Andrew Morton
2020-12-22 20:02 ` [patch 42/60] kasan: simplify quarantine_put call site Andrew Morton
2020-12-22 20:02 ` [patch 43/60] kasan: rename get_alloc/free_info Andrew Morton
2020-12-22 20:02 ` [patch 44/60] kasan: introduce set_alloc_info Andrew Morton
2020-12-22 20:02 ` [patch 45/60] kasan, arm64: unpoison stack only with CONFIG_KASAN_STACK Andrew Morton
2020-12-22 20:02 ` [patch 46/60] kasan: allow VMAP_STACK for HW_TAGS mode Andrew Morton
2020-12-22 20:02 ` [patch 47/60] kasan: remove __kasan_unpoison_stack Andrew Morton
2020-12-22 20:02 ` [patch 48/60] kasan: inline kasan_reset_tag for tag-based modes Andrew Morton
2020-12-22 20:02 ` [patch 49/60] kasan: inline random_tag for HW_TAGS Andrew Morton
2020-12-22 20:02 ` [patch 50/60] kasan: open-code kasan_unpoison_slab Andrew Morton
2020-12-22 20:03 ` [patch 51/60] kasan: inline (un)poison_range and check_invalid_free Andrew Morton
2020-12-22 20:03 ` [patch 52/60] kasan: add and integrate kasan boot parameters Andrew Morton
2020-12-22 20:03 ` [patch 53/60] kasan, mm: check kasan_enabled in annotations Andrew Morton
2020-12-22 20:03 ` [patch 54/60] kasan, mm: rename kasan_poison_kfree Andrew Morton
2020-12-22 20:03 ` [patch 55/60] kasan: don't round_up too much Andrew Morton
2020-12-22 20:03 ` [patch 56/60] kasan: simplify assign_tag and set_tag calls Andrew Morton
2020-12-22 20:03 ` [patch 57/60] kasan: clarify comment in __kasan_kfree_large Andrew Morton
2020-12-22 20:03 ` [patch 58/60] kasan: sanitize objects when metadata doesn't fit Andrew Morton
2020-12-22 20:03 ` [patch 59/60] kasan, mm: allow cache merging with no metadata Andrew Morton
2020-12-22 20:03 ` [patch 60/60] kasan: update documentation Andrew Morton
2020-12-22 21:43 ` incoming Linus Torvalds

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201222200217.9hOE1mcZ2%akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=Branislav.Rankov@arm.com \
    --cc=andreyknvl@google.com \
    --cc=aryabinin@virtuozzo.com \
    --cc=catalin.marinas@arm.com \
    --cc=dvyukov@google.com \
    --cc=elver@google.com \
    --cc=eugenis@google.com \
    --cc=glider@google.com \
    --cc=gor@linux.ibm.com \
    --cc=kevin.brodsky@arm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=mm-commits@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    --cc=vincenzo.frascino@arm.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).