Commit 76bc99e8 authored by Andrey Konovalov's avatar Andrey Konovalov Committed by Linus Torvalds

kasan: fix HW_TAGS boot parameters

The initially proposed KASAN command line parameters are redundant.

This change drops the complex "kasan.mode=off/prod/full" parameter and
adds a simpler kill switch "kasan=off/on" instead.  The new parameter
together with the already existing ones provides a cleaner way to
express the same set of features.

The full set of parameters with this change:

  kasan=off/on             - whether KASAN is enabled
  kasan.fault=report/panic - whether to only print a report or also panic
  kasan.stacktrace=off/on  - whether to collect alloc/free stack traces

Default values:

  kasan=on
  kasan.fault=report
  kasan.stacktrace=on  (if CONFIG_DEBUG_KERNEL=y)
  kasan.stacktrace=off (otherwise)

Link: https://linux-review.googlesource.com/id/Ib3694ed90b1e8ccac6cf77dfd301847af4aba7b8
Link: https://lkml.kernel.org/r/4e9c4a4bdcadc168317deb2419144582a9be6e61.1610736745.git.andreyknvl@google.comSigned-off-by: default avatarAndrey Konovalov <andreyknvl@google.com>
Reviewed-by: default avatarVincenzo Frascino <vincenzo.frascino@arm.com>
Reviewed-by: default avatarMarco Elver <elver@google.com>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
Cc: Peter Collingbourne <pcc@google.com>
Cc: Evgenii Stepanov <eugenis@google.com>
Cc: Branislav Rankov <Branislav.Rankov@arm.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 5dabd171
...@@ -160,29 +160,14 @@ intended for use in production as a security mitigation. Therefore it supports ...@@ -160,29 +160,14 @@ intended for use in production as a security mitigation. Therefore it supports
boot parameters that allow to disable KASAN competely or otherwise control boot parameters that allow to disable KASAN competely or otherwise control
particular KASAN features. particular KASAN features.
The things that can be controlled are: - ``kasan=off`` or ``=on`` controls whether KASAN is enabled (default: ``on``).
1. Whether KASAN is enabled at all. - ``kasan.stacktrace=off`` or ``=on`` disables or enables alloc and free stack
2. Whether KASAN collects and saves alloc/free stacks. traces collection (default: ``on`` for ``CONFIG_DEBUG_KERNEL=y``, otherwise
3. Whether KASAN panics on a detected bug or not. ``off``).
The ``kasan.mode`` boot parameter allows to choose one of three main modes: - ``kasan.fault=report`` or ``=panic`` controls whether to only print a KASAN
report or also panic the kernel (default: ``report``).
- ``kasan.mode=off`` - KASAN is disabled, no tag checks are performed
- ``kasan.mode=prod`` - only essential production features are enabled
- ``kasan.mode=full`` - all KASAN features are enabled
The chosen mode provides default control values for the features mentioned
above. However it's also possible to override the default values by providing:
- ``kasan.stacktrace=off`` or ``=on`` - enable alloc/free stack collection
(default: ``on`` for ``mode=full``,
otherwise ``off``)
- ``kasan.fault=report`` or ``=panic`` - only print KASAN report or also panic
(default: ``report``)
If ``kasan.mode`` parameter is not provided, it defaults to ``full`` when
``CONFIG_DEBUG_KERNEL`` is enabled, and to ``prod`` otherwise.
For developers For developers
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
......
...@@ -19,11 +19,10 @@ ...@@ -19,11 +19,10 @@
#include "kasan.h" #include "kasan.h"
enum kasan_arg_mode { enum kasan_arg {
KASAN_ARG_MODE_DEFAULT, KASAN_ARG_DEFAULT,
KASAN_ARG_MODE_OFF, KASAN_ARG_OFF,
KASAN_ARG_MODE_PROD, KASAN_ARG_ON,
KASAN_ARG_MODE_FULL,
}; };
enum kasan_arg_stacktrace { enum kasan_arg_stacktrace {
...@@ -38,7 +37,7 @@ enum kasan_arg_fault { ...@@ -38,7 +37,7 @@ enum kasan_arg_fault {
KASAN_ARG_FAULT_PANIC, KASAN_ARG_FAULT_PANIC,
}; };
static enum kasan_arg_mode kasan_arg_mode __ro_after_init; static enum kasan_arg kasan_arg __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; static enum kasan_arg_fault kasan_arg_fault __ro_after_init;
...@@ -52,26 +51,24 @@ DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace); ...@@ -52,26 +51,24 @@ DEFINE_STATIC_KEY_FALSE(kasan_flag_stacktrace);
/* Whether panic or disable tag checking on fault. */ /* Whether panic or disable tag checking on fault. */
bool kasan_flag_panic __ro_after_init; bool kasan_flag_panic __ro_after_init;
/* kasan.mode=off/prod/full */ /* kasan=off/on */
static int __init early_kasan_mode(char *arg) static int __init early_kasan_flag(char *arg)
{ {
if (!arg) if (!arg)
return -EINVAL; return -EINVAL;
if (!strcmp(arg, "off")) if (!strcmp(arg, "off"))
kasan_arg_mode = KASAN_ARG_MODE_OFF; kasan_arg = KASAN_ARG_OFF;
else if (!strcmp(arg, "prod")) else if (!strcmp(arg, "on"))
kasan_arg_mode = KASAN_ARG_MODE_PROD; kasan_arg = KASAN_ARG_ON;
else if (!strcmp(arg, "full"))
kasan_arg_mode = KASAN_ARG_MODE_FULL;
else else
return -EINVAL; return -EINVAL;
return 0; return 0;
} }
early_param("kasan.mode", early_kasan_mode); early_param("kasan", early_kasan_flag);
/* kasan.stack=off/on */ /* kasan.stacktrace=off/on */
static int __init early_kasan_flag_stacktrace(char *arg) static int __init early_kasan_flag_stacktrace(char *arg)
{ {
if (!arg) if (!arg)
...@@ -113,8 +110,8 @@ void kasan_init_hw_tags_cpu(void) ...@@ -113,8 +110,8 @@ void kasan_init_hw_tags_cpu(void)
* as this function is only called for MTE-capable hardware. * as this function is only called for MTE-capable hardware.
*/ */
/* If KASAN is disabled, do nothing. */ /* If KASAN is disabled via command line, don't initialize it. */
if (kasan_arg_mode == KASAN_ARG_MODE_OFF) if (kasan_arg == KASAN_ARG_OFF)
return; return;
hw_init_tags(KASAN_TAG_MAX); hw_init_tags(KASAN_TAG_MAX);
...@@ -124,43 +121,28 @@ void kasan_init_hw_tags_cpu(void) ...@@ -124,43 +121,28 @@ void kasan_init_hw_tags_cpu(void)
/* kasan_init_hw_tags() is called once on boot CPU. */ /* kasan_init_hw_tags() is called once on boot CPU. */
void __init kasan_init_hw_tags(void) void __init kasan_init_hw_tags(void)
{ {
/* If hardware doesn't support MTE, do nothing. */ /* If hardware doesn't support MTE, don't initialize KASAN. */
if (!system_supports_mte()) if (!system_supports_mte())
return; return;
/* Choose KASAN mode if kasan boot parameter is not provided. */ /* If KASAN is disabled via command line, don't initialize it. */
if (kasan_arg_mode == KASAN_ARG_MODE_DEFAULT) { if (kasan_arg == KASAN_ARG_OFF)
if (IS_ENABLED(CONFIG_DEBUG_KERNEL))
kasan_arg_mode = KASAN_ARG_MODE_FULL;
else
kasan_arg_mode = KASAN_ARG_MODE_PROD;
}
/* Preset parameter values based on the mode. */
switch (kasan_arg_mode) {
case KASAN_ARG_MODE_DEFAULT:
/* Shouldn't happen as per the check above. */
WARN_ON(1);
return; return;
case KASAN_ARG_MODE_OFF:
/* If KASAN is disabled, do nothing. */
return;
case KASAN_ARG_MODE_PROD:
static_branch_enable(&kasan_flag_enabled);
break;
case KASAN_ARG_MODE_FULL:
static_branch_enable(&kasan_flag_enabled);
static_branch_enable(&kasan_flag_stacktrace);
break;
}
/* Now, optionally override the presets. */ /* Enable KASAN. */
static_branch_enable(&kasan_flag_enabled);
switch (kasan_arg_stacktrace) { switch (kasan_arg_stacktrace) {
case KASAN_ARG_STACKTRACE_DEFAULT: case KASAN_ARG_STACKTRACE_DEFAULT:
/*
* Default to enabling stack trace collection for
* debug kernels.
*/
if (IS_ENABLED(CONFIG_DEBUG_KERNEL))
static_branch_enable(&kasan_flag_stacktrace);
break; break;
case KASAN_ARG_STACKTRACE_OFF: case KASAN_ARG_STACKTRACE_OFF:
static_branch_disable(&kasan_flag_stacktrace); /* Do nothing, kasan_flag_stacktrace keeps its default value. */
break; break;
case KASAN_ARG_STACKTRACE_ON: case KASAN_ARG_STACKTRACE_ON:
static_branch_enable(&kasan_flag_stacktrace); static_branch_enable(&kasan_flag_stacktrace);
...@@ -169,11 +151,16 @@ void __init kasan_init_hw_tags(void) ...@@ -169,11 +151,16 @@ void __init kasan_init_hw_tags(void)
switch (kasan_arg_fault) { switch (kasan_arg_fault) {
case KASAN_ARG_FAULT_DEFAULT: case KASAN_ARG_FAULT_DEFAULT:
/*
* Default to no panic on report.
* Do nothing, kasan_flag_panic keeps its default value.
*/
break; break;
case KASAN_ARG_FAULT_REPORT: case KASAN_ARG_FAULT_REPORT:
kasan_flag_panic = false; /* Do nothing, kasan_flag_panic keeps its default value. */
break; break;
case KASAN_ARG_FAULT_PANIC: case KASAN_ARG_FAULT_PANIC:
/* Enable panic on report. */
kasan_flag_panic = true; kasan_flag_panic = true;
break; break;
} }
......
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