Commit c9d1af2b authored by Woody Lin's avatar Woody Lin Committed by Linus Torvalds

mm/kasan: move kasan.fault to mm/kasan/report.c

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.comSigned-off-by: default avatarWoody Lin <woodylin@google.com>
Reviewed-by: default avatarMarco Elver <elver@google.com>
Reviewed-by: default avatarAndrey 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f181234a
...@@ -181,9 +181,16 @@ By default, KASAN prints a bug report only for the first invalid memory access. ...@@ -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 With ``kasan_multi_shot``, KASAN prints a report on every invalid access. This
effectively disables ``panic_on_warn`` for KASAN reports. 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 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 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``). - ``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. ...@@ -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 - ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
traces collection (default: ``on``). 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 Implementation details
---------------------- ----------------------
......
...@@ -37,16 +37,9 @@ enum kasan_arg_stacktrace { ...@@ -37,16 +37,9 @@ enum kasan_arg_stacktrace {
KASAN_ARG_STACKTRACE_ON, 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 kasan_arg __ro_after_init;
static enum kasan_arg_mode kasan_arg_mode __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_stacktrace kasan_arg_stacktrace __ro_after_init;
static enum kasan_arg_fault kasan_arg_fault __ro_after_init;
/* Whether KASAN is enabled at all. */ /* Whether KASAN is enabled at all. */
DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled); DEFINE_STATIC_KEY_FALSE(kasan_flag_enabled);
...@@ -59,9 +52,6 @@ EXPORT_SYMBOL_GPL(kasan_flag_async); ...@@ -59,9 +52,6 @@ EXPORT_SYMBOL_GPL(kasan_flag_async);
/* Whether to collect alloc/free stack traces. */ /* Whether to collect alloc/free stack traces. */
DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace); 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 */ /* kasan=off/on */
static int __init early_kasan_flag(char *arg) static int __init early_kasan_flag(char *arg)
{ {
...@@ -113,23 +103,6 @@ static int __init early_kasan_flag_stacktrace(char *arg) ...@@ -113,23 +103,6 @@ static int __init early_kasan_flag_stacktrace(char *arg)
} }
early_param("kasan.stacktrace", early_kasan_flag_stacktrace); 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. */ /* kasan_init_hw_tags_cpu() is called for each CPU. */
void kasan_init_hw_tags_cpu(void) void kasan_init_hw_tags_cpu(void)
{ {
...@@ -197,22 +170,6 @@ void __init kasan_init_hw_tags(void) ...@@ -197,22 +170,6 @@ void __init kasan_init_hw_tags(void)
break; 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"); pr_info("KernelAddressSanitizer initialized\n");
} }
......
...@@ -37,7 +37,6 @@ static inline bool kasan_async_mode_enabled(void) ...@@ -37,7 +37,6 @@ static inline bool kasan_async_mode_enabled(void)
#endif #endif
extern bool kasan_flag_panic __ro_after_init;
extern bool kasan_flag_async __ro_after_init; extern bool kasan_flag_async __ro_after_init;
#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
......
...@@ -39,6 +39,31 @@ static unsigned long kasan_flags; ...@@ -39,6 +39,31 @@ static unsigned long kasan_flags;
#define KASAN_BIT_REPORTED 0 #define KASAN_BIT_REPORTED 0
#define KASAN_BIT_MULTI_SHOT 1 #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) bool kasan_save_enable_multi_shot(void)
{ {
return test_and_set_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags); 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) ...@@ -102,10 +127,8 @@ static void end_report(unsigned long *flags, unsigned long addr)
panic_on_warn = 0; panic_on_warn = 0;
panic("panic_on_warn set ...\n"); panic("panic_on_warn set ...\n");
} }
#ifdef CONFIG_KASAN_HW_TAGS if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)
if (kasan_flag_panic)
panic("kasan.fault=panic set ...\n"); panic("kasan.fault=panic set ...\n");
#endif
kasan_enable_current(); kasan_enable_current();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment