mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
UPSTREAM: kasan: respect KASAN_BIT_REPORTED in all reporting routines
Currently, only kasan_report() checks the KASAN_BIT_REPORTED and
KASAN_BIT_MULTI_SHOT flags.
Make other reporting routines check these flags as well.
Also add explanatory comments.
Note that the current->kasan_depth check is split out into
report_suppressed() and only called for kasan_report().
Link: https://lkml.kernel.org/r/715e346b10b398e29ba1b425299dcd79e29d58ce.1646237226.git.andreyknvl@google.com
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Marco Elver <elver@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Bug: 254721825
(cherry picked from commit c068664c97)
Change-Id: Ie8618e0d18d6c86377dd3a0d7b910752f8662fbb
Signed-off-by: Andrey Konovalov <andreyknvl@google.com>
This commit is contained in:
committed by
Todd Kjos
parent
2ff512f673
commit
99393c3958
@@ -368,12 +368,26 @@ static void print_memory_metadata(const void *addr)
|
||||
}
|
||||
}
|
||||
|
||||
static bool report_enabled(void)
|
||||
/*
|
||||
* Used to suppress reports within kasan_disable/enable_current() critical
|
||||
* sections, which are used for marking accesses to slab metadata.
|
||||
*/
|
||||
static bool report_suppressed(void)
|
||||
{
|
||||
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
|
||||
if (current->kasan_depth)
|
||||
return false;
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to avoid reporting more than one KASAN bug unless kasan_multi_shot
|
||||
* is enabled. Note that KASAN tests effectively enable kasan_multi_shot
|
||||
* for their duration.
|
||||
*/
|
||||
static bool report_enabled(void)
|
||||
{
|
||||
if (test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
|
||||
return true;
|
||||
return !test_and_set_bit(KASAN_BIT_REPORTED, &kasan_flags);
|
||||
@@ -403,6 +417,14 @@ void kasan_report_invalid_free(void *ptr, unsigned long ip)
|
||||
unsigned long flags;
|
||||
struct kasan_report_info info;
|
||||
|
||||
/*
|
||||
* Do not check report_suppressed(), as an invalid-free cannot be
|
||||
* caused by accessing slab metadata and thus should not be
|
||||
* suppressed by kasan_disable/enable_current() critical sections.
|
||||
*/
|
||||
if (unlikely(!report_enabled()))
|
||||
return;
|
||||
|
||||
start_report(&flags, true);
|
||||
|
||||
info.type = KASAN_REPORT_INVALID_FREE;
|
||||
@@ -431,7 +453,7 @@ bool kasan_report(unsigned long addr, size_t size, bool is_write,
|
||||
unsigned long irq_flags;
|
||||
struct kasan_report_info info;
|
||||
|
||||
if (unlikely(!report_enabled())) {
|
||||
if (unlikely(report_suppressed()) || unlikely(!report_enabled())) {
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
@@ -460,6 +482,13 @@ void kasan_report_async(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
/*
|
||||
* Do not check report_suppressed(), as kasan_disable/enable_current()
|
||||
* critical sections do not affect Hardware Tag-Based KASAN.
|
||||
*/
|
||||
if (unlikely(!report_enabled()))
|
||||
return;
|
||||
|
||||
start_report(&flags, false);
|
||||
pr_err("BUG: KASAN: invalid-access\n");
|
||||
pr_err("Asynchronous fault: no details available\n");
|
||||
|
||||
Reference in New Issue
Block a user