Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lkdtm/stackleak: check stack boundaries

The stackleak code relies upon the current SP and lowest recorded SP
falling within expected task stack boundaries.

Check this at the start of the test.

Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Alexander Popov <alex.popov@linux.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Will Deacon <will@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220427173128.2603085-12-mark.rutland@arm.com

authored by

Mark Rutland and committed by
Kees Cook
f171d695 f03a5093

+20
+20
drivers/misc/lkdtm/stackleak.c
··· 36 36 bool test_failed = false; 37 37 38 38 /* 39 + * Check that the current and lowest recorded stack pointer values fall 40 + * within the expected task stack boundaries. These tests should never 41 + * fail unless the boundaries are incorrect or we're clobbering the 42 + * STACK_END_MAGIC, and in either casee something is seriously wrong. 43 + */ 44 + if (current_sp < task_stack_low || current_sp >= task_stack_high) { 45 + pr_err("FAIL: current_stack_pointer (0x%lx) outside of task stack bounds [0x%lx..0x%lx]\n", 46 + current_sp, task_stack_low, task_stack_high - 1); 47 + test_failed = true; 48 + goto out; 49 + } 50 + if (lowest_sp < task_stack_low || lowest_sp >= task_stack_high) { 51 + pr_err("FAIL: current->lowest_stack (0x%lx) outside of task stack bounds [0x%lx..0x%lx]\n", 52 + lowest_sp, task_stack_low, task_stack_high - 1); 53 + test_failed = true; 54 + goto out; 55 + } 56 + 57 + /* 39 58 * Depending on what has run prior to this test, the lowest recorded 40 59 * stack pointer could be above or below the current stack pointer. 41 60 * Start from the lowest of the two. ··· 106 87 poison_high - task_stack_low, 107 88 task_stack_low - task_stack_base); 108 89 90 + out: 109 91 if (test_failed) { 110 92 pr_err("FAIL: the thread stack is NOT properly erased!\n"); 111 93 pr_expected_config(CONFIG_GCC_PLUGIN_STACKLEAK);