summaryrefslogtreecommitdiffstats
path: root/drivers/misc/lkdtm/stackleak.c
AgeCommit message (Collapse)AuthorFilesLines
2022-06-03Merge tag 'char-misc-5.19-rc1' of ↵Linus Torvalds1-2/+11
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char / misc / other smaller driver subsystem updates from Greg KH: "Here is the large set of char, misc, and other driver subsystem updates for 5.19-rc1. The merge request for this has been delayed as I wanted to get lots of linux-next testing due to some late arrivals of changes for the habannalabs driver. Highlights of this merge are: - habanalabs driver updates for new hardware types and fixes and other updates - IIO driver tree merge which includes loads of new IIO drivers and cleanups and additions - PHY driver tree merge with new drivers and small updates to existing ones - interconnect driver tree merge with fixes and updates - soundwire driver tree merge with some small fixes - coresight driver tree merge with small fixes and updates - mhi bus driver tree merge with lots of updates and new device support - firmware driver updates - fpga driver updates - lkdtm driver updates (with a merge conflict, more on that below) - extcon driver tree merge with small updates - lots of other tiny driver updates and fixes and cleanups, full details in the shortlog. All of these have been in linux-next for almost 2 weeks with no reported problems" * tag 'char-misc-5.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (387 commits) habanalabs: use separate structure info for each error collect data habanalabs: fix missing handle shift during mmap habanalabs: remove hdev from hl_ctx_get args habanalabs: do MMU prefetch as deferred work habanalabs: order memory manager messages habanalabs: return -EFAULT on copy_to_user error habanalabs: use NULL for eventfd habanalabs: update firmware header habanalabs: add support for notification via eventfd habanalabs: add topic to memory manager buffer habanalabs: handle race in driver fini habanalabs: add device memory scrub ability through debugfs habanalabs: use unified memory manager for CB flow habanalabs: unified memory manager new code for CB flow habanalabs/gaudi: set arbitration timeout to a high value habanalabs: add put by handle method to memory manager habanalabs: hide memory manager page shift habanalabs: Add separate poll interval value for protocol habanalabs: use get_task_pid() to take PID habanalabs: add prefetch flag to the MAP operation ...
2022-05-08lkdtm/stackleak: fix CONFIG_GCC_PLUGIN_STACKLEAK=nMark Rutland1-1/+11
Recent rework broke building LKDTM when CONFIG_GCC_PLUGIN_STACKLEAK=n. This patch fixes that breakage. Prior to recent stackleak rework, the LKDTM STACKLEAK_ERASING code could be built when the kernel was not built with stackleak support, and would run a test that would almost certainly fail (or pass by sheer cosmic coincidence), e.g. | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: checking unused part of the thread stack (15560 bytes)... | lkdtm: FAIL: the erased part is not found (checked 15560 bytes) | lkdtm: FAIL: the thread stack is NOT properly erased! | lkdtm: This is probably expected, since this kernel (5.18.0-rc2 aarch64) was built *without* CONFIG_GCC_PLUGIN_STACKLEAK=y The recent rework to the test made it more accurate by using helpers which are only defined when CONFIG_GCC_PLUGIN_STACKLEAK=y, and so when building LKDTM when CONFIG_GCC_PLUGIN_STACKLEAK=n, we get a build failure: | drivers/misc/lkdtm/stackleak.c: In function 'check_stackleak_irqoff': | drivers/misc/lkdtm/stackleak.c:30:46: error: implicit declaration of function 'stackleak_task_low_bound' [-Werror=implicit-function-declaration] | 30 | const unsigned long task_stack_low = stackleak_task_low_bound(current); | | ^~~~~~~~~~~~~~~~~~~~~~~~ | drivers/misc/lkdtm/stackleak.c:31:47: error: implicit declaration of function 'stackleak_task_high_bound'; did you mean 'stackleak_task_init'? [-Werror=implicit-function-declaration] | 31 | const unsigned long task_stack_high = stackleak_task_high_bound(current); | | ^~~~~~~~~~~~~~~~~~~~~~~~~ | | stackleak_task_init | drivers/misc/lkdtm/stackleak.c:33:48: error: 'struct task_struct' has no member named 'lowest_stack' | 33 | const unsigned long lowest_sp = current->lowest_stack; | | ^~ | drivers/misc/lkdtm/stackleak.c:74:23: error: implicit declaration of function 'stackleak_find_top_of_poison' [-Werror=implicit-function-declaration] | 74 | poison_high = stackleak_find_top_of_poison(task_stack_low, untracked_high); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ This patch fixes the issue by not compiling the body of the test when CONFIG_GCC_PLUGIN_STACKLEAK=n, and replacing this with an unconditional XFAIL message. This means the pr_expected_config() in check_stackleak_irqoff() is redundant, and so it is removed. Where an architecture does not support stackleak, the test will log: | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: XFAIL: stackleak is not supported on this arch (HAVE_ARCH_STACKLEAK=n) Where an architectures does support stackleak, but this has not been compiled in, the test will log: | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: XFAIL: stackleak is not enabled (CONFIG_GCC_PLUGIN_STACKLEAK=n) Where stackleak has been compiled in, the test behaves as usual: | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: stackleak stack usage: | high offset: 336 bytes | current: 688 bytes | lowest: 1232 bytes | tracked: 1232 bytes | untracked: 672 bytes | poisoned: 14136 bytes | low offset: 8 bytes | lkdtm: OK: the rest of the thread stack is properly erased Fixes: f4cfacd92972cc44 ("lkdtm/stackleak: rework boundary management") Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Alexander Popov <alex.popov@linux.com> Cc: Kees Cook <keescook@chromium.org> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20220506121145.1162908-1-mark.rutland@arm.com
2022-05-08lkdtm/stackleak: check stack boundariesMark Rutland1-0/+20
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
2022-05-08lkdtm/stackleak: prevent unexpected stack usageMark Rutland1-1/+23
The lkdtm_STACKLEAK_ERASING() test is instrumentable and runs with IRQs unmasked, so it's possible for unrelated code to clobber the task stack and/or manipulate current->lowest_stack while the test is running, resulting in spurious failures. The regular stackleak erasing code is non-instrumentable and runs with IRQs masked, preventing similar issues. Make the body of the test non-instrumentable, and run it with IRQs masked, avoiding such spurious failures. 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-11-mark.rutland@arm.com
2022-05-08lkdtm/stackleak: rework boundary managementMark Rutland1-39/+47
There are a few problems with the way the LKDTM STACKLEAK_ERASING test manipulates the stack pointer and boundary values: * It uses the address of a local variable to determine the current stack pointer, rather than using current_stack_pointer directly. As the local variable could be placed anywhere within the stack frame, this can be an over-estimate of the true stack pointer value. * Is uses an estimate of the current stack pointer as the upper boundary when scanning for poison, even though prior functions could have used more stack (and may have updated current->lowest stack accordingly). * A pr_info() call is made in the middle of the test. As the printk() code is out-of-line and will make use of the stack, this could clobber poison and/or adjust current->lowest_stack. It would be better to log the metadata after the body of the test to avoid such problems. These have been observed to result in spurious test failures on arm64. In addition to this there are a couple of things which are sub-optimal: * To avoid the STACK_END_MAGIC value, it conditionally modifies 'left' if this contains more than a single element, when it could instead calculate the bound unconditionally using stackleak_task_low_bound(). * It open-codes the poison scanning. It would be better if this used the same helper code as used by erasing function so that the two cannot diverge. This patch reworks the test to avoid these issues, making use of the recently introduced helpers to ensure this is aligned with the regular stackleak code. As the new code tests stack boundaries before accessing the stack, there is no need to fail early when the tracked or untracked portions of the stack extend all the way to the low stack boundary. As stackleak_find_top_of_poison() is now used to find the top of the poisoned region of the stack, the subsequent poison checking starts at this boundary and verifies that stackleak_find_top_of_poison() is working correctly. The pr_info() which logged the untracked portion of stack is now moved to the end of the function, and logs the size of all the portions of the stack relevant to the test, including the portions at the top and bottom of the stack which are not erased or scanned, and the current / lowest recorded stack usage. Tested on x86_64: | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: stackleak stack usage: | high offset: 168 bytes | current: 336 bytes | lowest: 656 bytes | tracked: 656 bytes | untracked: 400 bytes | poisoned: 15152 bytes | low offset: 8 bytes | lkdtm: OK: the rest of the thread stack is properly erased Tested on arm64: | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: stackleak stack usage: | high offset: 336 bytes | current: 656 bytes | lowest: 1232 bytes | tracked: 1232 bytes | untracked: 672 bytes | poisoned: 14136 bytes | low offset: 8 bytes | lkdtm: OK: the rest of the thread stack is properly erased Tested on arm64 with deliberate breakage to the starting stack value and poison scanning: | # echo STACKLEAK_ERASING > /sys/kernel/debug/provoke-crash/DIRECT | lkdtm: Performing direct entry STACKLEAK_ERASING | lkdtm: FAIL: non-poison value 24 bytes below poison boundary: 0x0 | lkdtm: FAIL: non-poison value 32 bytes below poison boundary: 0xffff8000083dbc00 ... | lkdtm: FAIL: non-poison value 1912 bytes below poison boundary: 0x78b4b9999e8cb15 | lkdtm: FAIL: non-poison value 1920 bytes below poison boundary: 0xffff8000083db400 | lkdtm: stackleak stack usage: | high offset: 336 bytes | current: 688 bytes | lowest: 1232 bytes | tracked: 576 bytes | untracked: 288 bytes | poisoned: 15176 bytes | low offset: 8 bytes | lkdtm: FAIL: the thread stack is NOT properly erased! | lkdtm: Unexpected! This kernel (5.18.0-rc1-00013-g1f7b1f1e29e0-dirty aarch64) was built with CONFIG_GCC_PLUGIN_STACKLEAK=y 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: Kees Cook <keescook@chromium.org> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20220427173128.2603085-10-mark.rutland@arm.com
2022-05-08lkdtm/stackleak: avoid spurious failureMark Rutland1-7/+0
The lkdtm_STACKLEAK_ERASING() test scans for a contiguous block of poison values between the low stack bound and the stack pointer, and fails if it does not find a sufficiently large block. This can happen legitimately if the scan the low stack bound, which could occur if functions called prior to lkdtm_STACKLEAK_ERASING() used a large amount of stack. If this were to occur, it means that the erased portion of the stack is smaller than the size used by the scan, but does not cause a functional problem In practice this is unlikely to happen, but as this is legitimate and would not result in a functional problem, the test should not fail in this case. Remove the spurious failure case. 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: Kees Cook <keescook@chromium.org> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20220427173128.2603085-9-mark.rutland@arm.com
2022-04-12lkdtm: Move crashtype definitions into each categoryKees Cook1-1/+10
It's long been annoying that to add a new LKDTM test one had to update lkdtm.h and core.c to get it "registered". Switch to a per-category list and update the crashtype walking code in core.c to handle it. This also means that all the lkdtm_* tests themselves can be static now. Cc: Arnd Bergmann <arnd@arndb.de> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Kees Cook <keescook@chromium.org>
2021-06-24lkdtm: Add CONFIG hints in errors where possibleKees Cook1-2/+2
For various failure conditions, try to include some details about where to look for reasons about the failure. Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20210623203936.3151093-8-keescook@chromium.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2020-02-10lkdtm/stackleak: Make the test more verboseAlexander Popov1-8/+17
Make the stack erasing test more verbose about the errors that it can detect. Signed-off-by: Alexander Popov <alex.popov@linux.com> Cc: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20200102234907.585508-1-alex.popov@linux.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2018-09-04lkdtm: Add a test for STACKLEAKAlexander Popov1-0/+73
Introduce an lkdtm test for the STACKLEAK feature: check that the current task stack is properly erased (filled with STACKLEAK_POISON). Signed-off-by: Alexander Popov <alex.popov@linux.com> Signed-off-by: Tycho Andersen <tycho@tycho.ws> Tested-by: Laura Abbott <labbott@redhat.com> Signed-off-by: Kees Cook <keescook@chromium.org>