mm/kasan: move kasan.fault to mm/kasan/report.c
authorWoody Lin <woodylin@google.com>
Thu, 2 Sep 2021 21:57:29 +0000 (14:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 3 Sep 2021 16:58:14 +0000 (09:58 -0700)
Move the boot parameter 'kasan.fault' from hw_tags.c to report.c, so it
can support all KASAN modes - generic, and both tag-based.

Link: https://lkml.kernel.org/r/20210713010536.3161822-1-woodylin@google.com
Signed-off-by: Woody Lin <woodylin@google.com>
Reviewed-by: Marco Elver <elver@google.com>
Reviewed-by: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/dev-tools/kasan.rst
mm/kasan/hw_tags.c
mm/kasan/kasan.h
mm/kasan/report.c

index 83ec4a5..21dc03b 100644 (file)
@@ -181,9 +181,16 @@ By default, KASAN prints a bug report only for the first invalid memory access.
 With ``kasan_multi_shot``, KASAN prints a report on every invalid access. This
 effectively disables ``panic_on_warn`` for KASAN reports.
 
+Alternatively, independent of ``panic_on_warn`` the ``kasan.fault=`` boot
+parameter can be used to control panic and reporting behaviour:
+
+- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN
+  report or also panic the kernel (default: ``report``). The panic happens even
+  if ``kasan_multi_shot`` is enabled.
+
 Hardware tag-based KASAN mode (see the section about various modes below) is
 intended for use in production as a security mitigation. Therefore, it supports
-boot parameters that allow disabling KASAN or controlling its features.
+additional boot parameters that allow disabling KASAN or controlling features:
 
 - ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``).
 
@@ -199,10 +206,6 @@ boot parameters that allow disabling KASAN or controlling its features.
 - ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
   traces collection (default: ``on``).
 
-- ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN
-  report or also panic the kernel (default: ``report``). The panic happens even
-  if ``kasan_multi_shot`` is enabled.
-
 Implementation details
 ----------------------
 
index 4ea8c36..5190363 100644 (file)
@@ -37,16 +37,9 @@ enum kasan_arg_stacktrace {
        KASAN_ARG_STACKTRACE_ON,
 };
 
-enum kasan_arg_fault {
-       KASAN_ARG_FAULT_DEFAULT,
-       KASAN_ARG_FAULT_REPORT,
-       KASAN_ARG_FAULT_PANIC,
-};
-
 static enum kasan_arg kasan_arg __ro_after_init;
 static enum kasan_arg_mode kasan_arg_mode __ro_after_init;
 static enum kasan_arg_stacktrace kasan_arg_stacktrace __ro_after_init;
-static enum kasan_arg_fault kasan_arg_fault __ro_after_init;
 
 /* Whether KASAN is enabled at all. */
 DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled);
@@ -59,9 +52,6 @@ EXPORT_SYMBOL_GPL(kasan_flag_async);
 /* Whether to collect alloc/free stack traces. */
 DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
 
-/* Whether to panic or print a report and disable tag checking on fault. */
-bool kasan_flag_panic __ro_after_init;
-
 /* kasan=off/on */
 static int __init early_kasan_flag(char *arg)
 {
@@ -113,23 +103,6 @@ static int __init early_kasan_flag_stacktrace(char *arg)
 }
 early_param("kasan.stacktrace", early_kasan_flag_stacktrace);
 
-/* kasan.fault=report/panic */
-static int __init early_kasan_fault(char *arg)
-{
-       if (!arg)
-               return -EINVAL;
-
-       if (!strcmp(arg, "report"))
-               kasan_arg_fault = KASAN_ARG_FAULT_REPORT;
-       else if (!strcmp(arg, "panic"))
-               kasan_arg_fault = KASAN_ARG_FAULT_PANIC;
-       else
-               return -EINVAL;
-
-       return 0;
-}
-early_param("kasan.fault", early_kasan_fault);
-
 /* kasan_init_hw_tags_cpu() is called for each CPU. */
 void kasan_init_hw_tags_cpu(void)
 {
@@ -197,22 +170,6 @@ void __init kasan_init_hw_tags(void)
                break;
        }
 
-       switch (kasan_arg_fault) {
-       case KASAN_ARG_FAULT_DEFAULT:
-               /*
-                * Default to no panic on report.
-                * Do nothing, kasan_flag_panic keeps its default value.
-                */
-               break;
-       case KASAN_ARG_FAULT_REPORT:
-               /* Do nothing, kasan_flag_panic keeps its default value. */
-               break;
-       case KASAN_ARG_FAULT_PANIC:
-               /* Enable panic on report. */
-               kasan_flag_panic = true;
-               break;
-       }
-
        pr_info("KernelAddressSanitizer initialized\n");
 }
 
index d739cdd..fa02c88 100644 (file)
@@ -37,7 +37,6 @@ static inline bool kasan_async_mode_enabled(void)
 
 #endif
 
-extern bool kasan_flag_panic __ro_after_init;
 extern bool kasan_flag_async __ro_after_init;
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
index 8fff182..884a950 100644 (file)
@@ -39,6 +39,31 @@ static unsigned long kasan_flags;
 #define KASAN_BIT_REPORTED     0
 #define KASAN_BIT_MULTI_SHOT   1
 
+enum kasan_arg_fault {
+       KASAN_ARG_FAULT_DEFAULT,
+       KASAN_ARG_FAULT_REPORT,
+       KASAN_ARG_FAULT_PANIC,
+};
+
+static enum kasan_arg_fault kasan_arg_fault __ro_after_init = KASAN_ARG_FAULT_DEFAULT;
+
+/* kasan.fault=report/panic */
+static int __init early_kasan_fault(char *arg)
+{
+       if (!arg)
+               return -EINVAL;
+
+       if (!strcmp(arg, "report"))
+               kasan_arg_fault = KASAN_ARG_FAULT_REPORT;
+       else if (!strcmp(arg, "panic"))
+               kasan_arg_fault = KASAN_ARG_FAULT_PANIC;
+       else
+               return -EINVAL;
+
+       return 0;
+}
+early_param("kasan.fault", early_kasan_fault);
+
 bool kasan_save_enable_multi_shot(void)
 {
        return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags);
@@ -102,10 +127,8 @@ static void end_report(unsigned long *flags, unsigned long addr)
                panic_on_warn = 0;
                panic("panic_on_warn set ...\n");
        }
-#ifdef CONFIG_KASAN_HW_TAGS
-       if (kasan_flag_panic)
+       if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)
                panic("kasan.fault=panic set ...\n");
-#endif
        kasan_enable_current();
 }