linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Maninder Singh <maninder1.s@samsung.com>
To: ryabinin.a.a@gmail.com, glider@google.com, andreyknvl@gmail.com,
	akpm@linux-foundation.org, dvyukov@google.com
Cc: kasan-dev@googlegroups.com, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, a.sahrawat@samsung.com,
	Maninder Singh <maninder1.s@samsung.com>,
	Vaneet Narang <v.narang@samsung.com>
Subject: [PATCH 1/2] mm/kasan: avoid duplicate KASAN issues from reporting
Date: Thu, 22 Apr 2021 13:45:16 +0530	[thread overview]
Message-ID: <1619079317-1131-1-git-send-email-maninder1.s@samsung.com> (raw)
In-Reply-To: CGME20210422081531epcas5p23d6c72ebf28a23b2efc150d581319ffa@epcas5p2.samsung.com

when KASAN multishot is ON and some buggy code hits same code path
of KASAN issue repetetively, it can flood logs on console.

Check for allocaton, free and backtrace path at time of KASAN error,
if these are same then it is duplicate error and avoid these prints
from KASAN.

Co-developed-by: Vaneet Narang <v.narang@samsung.com>
Signed-off-by: Vaneet Narang <v.narang@samsung.com>
Signed-off-by: Maninder Singh <maninder1.s@samsung.com>
---
 mm/kasan/kasan.h  |  6 +++++
 mm/kasan/report.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
index 78cf99247139..d14ccce246ba 100644
--- a/mm/kasan/kasan.h
+++ b/mm/kasan/kasan.h
@@ -102,6 +102,12 @@ struct kasan_access_info {
 	unsigned long ip;
 };
 
+struct kasan_record {
+	depot_stack_handle_t	bt_handle;
+	depot_stack_handle_t	alloc_handle;
+	depot_stack_handle_t	free_handle;
+};
+
 /* The layout of struct dictated by compiler */
 struct kasan_source_location {
 	const char *filename;
diff --git a/mm/kasan/report.c b/mm/kasan/report.c
index 87b271206163..4576de76991b 100644
--- a/mm/kasan/report.c
+++ b/mm/kasan/report.c
@@ -39,6 +39,10 @@ static unsigned long kasan_flags;
 #define KASAN_BIT_REPORTED	0
 #define KASAN_BIT_MULTI_SHOT	1
 
+#define MAX_RECORDS		(200)
+static struct kasan_record kasan_records[MAX_RECORDS];
+static int stored_kasan_records;
+
 bool kasan_save_enable_multi_shot(void)
 {
 	return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
@@ -360,6 +364,65 @@ void kasan_report_invalid_free(void *object, unsigned long ip)
 	end_report(&flags, (unsigned long)object);
 }
 
+/*
+ * @save_report()
+ *
+ * returns false if same record is already saved.
+ * returns true if its new record and saved in database of KASAN.
+ */
+static bool save_report(void *addr, struct kasan_access_info *info, u8 tag, unsigned long *flags)
+{
+	struct kasan_record record = {0};
+	depot_stack_handle_t bt_handle;
+	int i = 0;
+	const char *bug_type;
+	struct kasan_alloc_meta *alloc_meta;
+	struct kasan_track *free_track;
+	struct page *page;
+	bool ret = true;
+
+	kasan_disable_current();
+	spin_lock_irqsave(&report_lock, *flags);
+
+	bug_type = kasan_get_bug_type(info);
+	page = kasan_addr_to_page(addr);
+	bt_handle = kasan_save_stack(GFP_KERNEL);
+
+	if (page && PageSlab(page)) {
+		struct kmem_cache *cache = page->slab_cache;
+		void *object = nearest_obj(cache, page, addr);
+
+		alloc_meta = kasan_get_alloc_meta(cache, object);
+		free_track = kasan_get_free_track(cache, object, tag);
+		record.alloc_handle = alloc_meta->alloc_track.stack;
+		if (free_track)
+			record.free_handle = free_track->stack;
+	}
+
+	record.bt_handle = bt_handle;
+
+	for (i = 0; i < stored_kasan_records; i++) {
+		if (record.bt_handle != kasan_records[i].bt_handle)
+			continue;
+		if (record.alloc_handle != kasan_records[i].alloc_handle)
+			continue;
+		if (!strncmp("use-after-free", bug_type, 15) &&
+			(record.free_handle != kasan_records[i].free_handle))
+			continue;
+
+		ret = false;
+		goto done;
+	}
+
+	memcpy(&kasan_records[stored_kasan_records], &record, sizeof(struct kasan_record));
+	stored_kasan_records++;
+
+done:
+	spin_unlock_irqrestore(&report_lock, *flags);
+	kasan_enable_current();
+	return ret;
+}
+
 static void __kasan_report(unsigned long addr, size_t size, bool is_write,
 				unsigned long ip)
 {
@@ -388,6 +451,10 @@ static void __kasan_report(unsigned long addr, size_t size, bool is_write,
 	info.is_write = is_write;
 	info.ip = ip;
 
+	if (addr_has_metadata(untagged_addr) &&
+		!save_report(untagged_addr, &info, get_tag(tagged_addr), &flags))
+		return;
+
 	start_report(&flags);
 
 	print_error_description(&info);
-- 
2.17.1


       reply	other threads:[~2021-04-22  9:17 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CGME20210422081531epcas5p23d6c72ebf28a23b2efc150d581319ffa@epcas5p2.samsung.com>
2021-04-22  8:15 ` Maninder Singh [this message]
     [not found]   ` <CGME20210422081536epcas5p417c144cce0235933a1cd0f29ad55470a@epcas5p4.samsung.com>
2021-04-22  8:15     ` [PATCH 2/2] mm/kasan: proc interface to read KASAN errors at any time Maninder Singh
2021-04-22 10:04       ` Dmitry Vyukov
2021-04-22 10:38         ` Alexander Potapenko
2021-04-22  9:58   ` [PATCH 1/2] mm/kasan: avoid duplicate KASAN issues from reporting Dmitry Vyukov
2021-04-22  9:59     ` Dmitry Vyukov
2021-04-22 14:10   ` Marco Elver
2021-04-22 15:06     ` Andrey Konovalov

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=1619079317-1131-1-git-send-email-maninder1.s@samsung.com \
    --to=maninder1.s@samsung.com \
    --cc=a.sahrawat@samsung.com \
    --cc=akpm@linux-foundation.org \
    --cc=andreyknvl@gmail.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ryabinin.a.a@gmail.com \
    --cc=v.narang@samsung.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).