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>

authored by Ard Biesheuvel and committed by Catalin Marinas eb972eab b7737c38

Changed files
+55
drivers
misc
lkdtm
tools
testing
selftests
lkdtm
+53
drivers/misc/lkdtm/bugs.c
··· 8 8 #include "lkdtm.h" 9 9 #include <linux/cpu.h> 10 10 #include <linux/list.h> 11 + #include <linux/hrtimer.h> 11 12 #include <linux/sched.h> 12 13 #include <linux/sched/signal.h> 13 14 #include <linux/sched/task_stack.h> ··· 101 100 stop_machine(panic_stop_irqoff_fn, &v, cpu_online_mask); 102 101 } 103 102 103 + static bool wait_for_panic; 104 + 105 + static enum hrtimer_restart panic_in_hardirq(struct hrtimer *timer) 106 + { 107 + panic("from hard IRQ context"); 108 + 109 + wait_for_panic = false; 110 + return HRTIMER_NORESTART; 111 + } 112 + 113 + static void lkdtm_PANIC_IN_HARDIRQ(void) 114 + { 115 + struct hrtimer timer; 116 + 117 + wait_for_panic = true; 118 + hrtimer_setup_on_stack(&timer, panic_in_hardirq, 119 + CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); 120 + hrtimer_start(&timer, us_to_ktime(100), HRTIMER_MODE_REL_HARD); 121 + 122 + while (wait_for_panic) 123 + ; 124 + 125 + hrtimer_cancel(&timer); 126 + } 127 + 104 128 static void lkdtm_BUG(void) 105 129 { 106 130 BUG(); 131 + } 132 + 133 + static bool wait_for_bug; 134 + 135 + static enum hrtimer_restart bug_in_hardirq(struct hrtimer *timer) 136 + { 137 + BUG(); 138 + 139 + wait_for_bug = false; 140 + return HRTIMER_NORESTART; 141 + } 142 + 143 + static void lkdtm_BUG_IN_HARDIRQ(void) 144 + { 145 + struct hrtimer timer; 146 + 147 + wait_for_bug = true; 148 + hrtimer_setup_on_stack(&timer, bug_in_hardirq, 149 + CLOCK_MONOTONIC, HRTIMER_MODE_REL_HARD); 150 + hrtimer_start(&timer, us_to_ktime(100), HRTIMER_MODE_REL_HARD); 151 + 152 + while (wait_for_bug) 153 + ; 154 + 155 + hrtimer_cancel(&timer); 107 156 } 108 157 109 158 static int warn_counter; ··· 747 696 static struct crashtype crashtypes[] = { 748 697 CRASHTYPE(PANIC), 749 698 CRASHTYPE(PANIC_STOP_IRQOFF), 699 + CRASHTYPE(PANIC_IN_HARDIRQ), 750 700 CRASHTYPE(BUG), 701 + CRASHTYPE(BUG_IN_HARDIRQ), 751 702 CRASHTYPE(WARNING), 752 703 CRASHTYPE(WARNING_MESSAGE), 753 704 CRASHTYPE(EXCEPTION),
+2
tools/testing/selftests/lkdtm/tests.txt
··· 1 1 #PANIC 2 2 #PANIC_STOP_IRQOFF Crashes entire system 3 + #PANIC_IN_HARDIRQ Crashes entire system 3 4 BUG kernel BUG at 5 + #BUG_IN_HARDIRQ Crashes entire system 4 6 WARNING WARNING: 5 7 WARNING_MESSAGE message trigger 6 8 EXCEPTION