KASAN provides an asynchronous mode of execution. Add reporting functionality for this mode.
Cc: Dmitry Vyukov <dvyu...@google.com> Cc: Andrey Ryabinin <aryabi...@virtuozzo.com> Cc: Alexander Potapenko <gli...@google.com> Cc: Andrey Konovalov <andreyk...@google.com> Reviewed-by: Andrey Konovalov <andreyk...@google.com> Acked-by: Catalin Marinas <catalin.mari...@arm.com> Acked-by: Andrey Konovalov <andreyk...@google.com> Tested-by: Andrey Konovalov <andreyk...@google.com> Signed-off-by: Vincenzo Frascino <vincenzo.frasc...@arm.com> Signed-off-by: Andrey Konovalov <andreyk...@google.com> --- include/linux/kasan.h | 6 ++++++ mm/kasan/kasan.h | 16 ++++++++++++++++ mm/kasan/report.c | 17 ++++++++++++++++- 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index 8b3b99d659b7..b1678a61e6a7 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -393,6 +393,12 @@ static inline void *kasan_reset_tag(const void *addr) #endif /* CONFIG_KASAN_SW_TAGS || CONFIG_KASAN_HW_TAGS*/ +#ifdef CONFIG_KASAN_HW_TAGS + +void kasan_report_async(void); + +#endif /* CONFIG_KASAN_HW_TAGS */ + #ifdef CONFIG_KASAN_SW_TAGS void __init kasan_init_sw_tags(void); #else diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h index 9d97b104c3b0..56b155ddaf30 100644 --- a/mm/kasan/kasan.h +++ b/mm/kasan/kasan.h @@ -7,17 +7,33 @@ #include <linux/stackdepot.h> #ifdef CONFIG_KASAN_HW_TAGS + #include <linux/static_key.h> + DECLARE_STATIC_KEY_FALSE(kasan_flag_stacktrace); +extern bool kasan_flag_async __ro_after_init; + static inline bool kasan_stack_collection_enabled(void) { return static_branch_unlikely(&kasan_flag_stacktrace); } + +static inline bool kasan_async_mode_enabled(void) +{ + return kasan_flag_async; +} #else + static inline bool kasan_stack_collection_enabled(void) { return true; } + +static inline bool kasan_async_mode_enabled(void) +{ + return false; +} + #endif extern bool kasan_flag_panic __ro_after_init; diff --git a/mm/kasan/report.c b/mm/kasan/report.c index 87b271206163..8b0843a2cdd7 100644 --- a/mm/kasan/report.c +++ b/mm/kasan/report.c @@ -87,7 +87,8 @@ static void start_report(unsigned long *flags) static void end_report(unsigned long *flags, unsigned long addr) { - trace_error_report_end(ERROR_DETECTOR_KASAN, addr); + if (!kasan_async_mode_enabled()) + trace_error_report_end(ERROR_DETECTOR_KASAN, addr); pr_err("==================================================================\n"); add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); spin_unlock_irqrestore(&report_lock, *flags); @@ -360,6 +361,20 @@ void kasan_report_invalid_free(void *object, unsigned long ip) end_report(&flags, (unsigned long)object); } +#ifdef CONFIG_KASAN_HW_TAGS +void kasan_report_async(void) +{ + unsigned long flags; + + start_report(&flags); + pr_err("BUG: KASAN: invalid-access\n"); + pr_err("Asynchronous mode enabled: no access details available\n"); + pr_err("\n"); + dump_stack(); + end_report(&flags, 0); +} +#endif /* CONFIG_KASAN_HW_TAGS */ + static void __kasan_report(unsigned long addr, size_t size, bool is_write, unsigned long ip) { -- 2.30.2