diff options
| author | Ard Biesheuvel <ardb@kernel.org> | 2025-12-06 20:01:16 +0100 |
|---|---|---|
| committer | Catalin Marinas <catalin.marinas@arm.com> | 2025-12-15 12:05:37 +0000 |
| commit | eb972eab0794dedeef5b3b1845e5f9a78793f184 (patch) | |
| tree | 58d2d287c6214025a6262de84dac4a09016e0423 | |
| parent | b7737c38e7cb611c2fbd87af3b09afeb92c96fe7 (diff) | |
lkdtm/bugs: Add cases for BUG and PANIC occurring in hardirq context
Add lkdtm cases to trigger a BUG() or panic() from hardirq context. This
is useful for testing pstore behavior being invoked from such contexts.
Reviewed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
| -rw-r--r-- | drivers/misc/lkdtm/bugs.c | 53 | ||||
| -rw-r--r-- | tools/testing/selftests/lkdtm/tests.txt | 2 |
2 files changed, 55 insertions, 0 deletions
diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index 376047beea3d..fa05d77acb55 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -8,6 +8,7 @@ #include "lkdtm.h" #include <linux/cpu.h> #include <linux/list.h> +#include <linux/hrtimer.h> #include <linux/sched.h> #include <linux/sched/signal.h> #include <linux/sched/task_stack.h> @@ -100,11 +101,61 @@ static void lkdtm_PANIC_STOP_IRQOFF(void) stop_machine(panic_stop_irqoff_fn, &v, cpu_online_mask); } +static bool wait_for_panic; + +static enum hrtimer_restart panic_in_hardirq(struct hrtimer *timer) +{ + panic("from hard IRQ context"); + + wait_for_panic = false; + return HRTIMER_NORESTART; +} + +static void lkdtm_PANIC_IN_HARDIRQ(void) +{ + struct hrtimer timer; + + wait_for_panic = true; + hrtimer_setup_on_stack(&timer, panic_in_hardirq, + CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); + hrtimer_start(&timer, us_to_ktime(100), HRTIMER_MODE_REL_HARD); + + while (wait_for_panic) + ; + + hrtimer_cancel(&timer); +} + static void lkdtm_BUG(void) { BUG(); } +static bool wait_for_bug; + +static enum hrtimer_restart bug_in_hardirq(struct hrtimer *timer) +{ + BUG(); + + wait_for_bug = false; + return HRTIMER_NORESTART; +} + +static void lkdtm_BUG_IN_HARDIRQ(void) +{ + struct hrtimer timer; + + wait_for_bug = true; + hrtimer_setup_on_stack(&timer, bug_in_hardirq, + CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); + hrtimer_start(&timer, us_to_ktime(100), HRTIMER_MODE_REL_HARD); + + while (wait_for_bug) + ; + + hrtimer_cancel(&timer); +} + static int warn_counter; static void lkdtm_WARNING(void) @@ -696,7 +747,9 @@ static noinline void lkdtm_CORRUPT_PAC(void) static struct crashtype crashtypes[] = { CRASHTYPE(PANIC), CRASHTYPE(PANIC_STOP_IRQOFF), + CRASHTYPE(PANIC_IN_HARDIRQ), CRASHTYPE(BUG), + CRASHTYPE(BUG_IN_HARDIRQ), CRASHTYPE(WARNING), CRASHTYPE(WARNING_MESSAGE), CRASHTYPE(EXCEPTION), diff --git a/tools/testing/selftests/lkdtm/tests.txt b/tools/testing/selftests/lkdtm/tests.txt index cff124c1eddd..67cd53715d93 100644 --- a/tools/testing/selftests/lkdtm/tests.txt +++ b/tools/testing/selftests/lkdtm/tests.txt @@ -1,6 +1,8 @@ #PANIC #PANIC_STOP_IRQOFF Crashes entire system +#PANIC_IN_HARDIRQ Crashes entire system BUG kernel BUG at +#BUG_IN_HARDIRQ Crashes entire system WARNING WARNING: WARNING_MESSAGE message trigger EXCEPTION |
