| From: Andrey Konovalov <andreyknvl@google.com> |
| Subject: kasan: disable LOCKDEP when printing reports |
| |
| If LOCKDEP detects a bug while KASAN is printing a report and if |
| panic_on_warn is set, KASAN will not be able to finish. Disable LOCKDEP |
| while KASAN is printing a report. |
| |
| See https://bugzilla.kernel.org/show_bug.cgi?id=202115 for an example |
| of the issue. |
| |
| Link: https://lkml.kernel.org/r/c48a2a3288200b07e1788b77365c2f02784cfeb4.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> |
| --- |
| |
| mm/kasan/report.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| --- a/mm/kasan/report.c~kasan-disable-lockdep-when-printing-reports |
| +++ a/mm/kasan/report.c |
| @@ -13,6 +13,7 @@ |
| #include <linux/ftrace.h> |
| #include <linux/init.h> |
| #include <linux/kernel.h> |
| +#include <linux/lockdep.h> |
| #include <linux/mm.h> |
| #include <linux/printk.h> |
| #include <linux/sched.h> |
| @@ -148,6 +149,8 @@ static void start_report(unsigned long * |
| disable_trace_on_warning(); |
| /* Update status of the currently running KASAN test. */ |
| update_kunit_status(sync); |
| + /* Do not allow LOCKDEP mangling KASAN reports. */ |
| + lockdep_off(); |
| /* Make sure we don't end up in loop. */ |
| kasan_disable_current(); |
| spin_lock_irqsave(&report_lock, *flags); |
| @@ -160,12 +163,13 @@ static void end_report(unsigned long *fl |
| trace_error_report_end(ERROR_DETECTOR_KASAN, |
| (unsigned long)addr); |
| pr_err("==================================================================\n"); |
| - add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); |
| spin_unlock_irqrestore(&report_lock, *flags); |
| if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags)) |
| panic("panic_on_warn set ...\n"); |
| if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC) |
| panic("kasan.fault=panic set ...\n"); |
| + add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); |
| + lockdep_on(); |
| kasan_enable_current(); |
| } |
| |
| _ |