aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/lkdtm
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2021-10-07 10:12:35 +0200
committerKees Cook <keescook@chromium.org>2021-12-16 15:54:37 -0800
commit026c6fa1a525ca3f8a615052e45d766208989597 (patch)
tree26f7606b3b20ab481382ba3508b1a2433e6f2c94 /drivers/misc/lkdtm
parent861dc0d7fd972f2064ff48b211955717163a11e0 (diff)
downloadlinux-026c6fa1a525ca3f8a615052e45d766208989597.tar.gz
lkdtm: avoid printk() in recursive_loop()
The recursive_loop() function is intended as a diagnostic to ensure that exhausting the stack is caught and mitigated. Currently, it uses pr_info() to ensure that the function has side effects that the compiler cannot simply optimize away, so that the stack footprint does not get reduced inadvertently. The typical mitigation for stack overflow is to kill the task, and this overflow may occur inside the call to pr_info(), which means it could be holding the console lock when this happens. This means that the console lock is never going to be released again, preventing the diagnostic prints related to the stack overflow handling from being visible on the console. So let's replace the call to pr_info() with a call to memzero_explicit(), which is not a 'magic' function name like memset() or memcpy(), which the compiler may replace with plain loads and stores. To ensure that the stack frames are nested rather than tail-called, put the call to memzero_explicit() after the recursive call. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20211007081235.382697-1-ardb@kernel.org
Diffstat (limited to 'drivers/misc/lkdtm')
-rw-r--r--drivers/misc/lkdtm/bugs.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c
index f4cb94a9aa9cf..f21854ac5cc2b 100644
--- a/drivers/misc/lkdtm/bugs.c
+++ b/drivers/misc/lkdtm/bugs.c
@@ -41,20 +41,22 @@ static DEFINE_SPINLOCK(lock_me_up);
* Make sure compiler does not optimize this function or stack frame away:
* - function marked noinline
* - stack variables are marked volatile
- * - stack variables are written (memset()) and read (pr_info())
- * - function has external effects (pr_info())
- * */
+ * - stack variables are written (memset()) and read (buf[..] passed as arg)
+ * - function may have external effects (memzero_explicit())
+ * - no tail recursion possible
+ */
static int noinline recursive_loop(int remaining)
{
volatile char buf[REC_STACK_SIZE];
+ volatile int ret;
memset((void *)buf, remaining & 0xFF, sizeof(buf));
- pr_info("loop %d/%d ...\n", (int)buf[remaining % sizeof(buf)],
- recur_count);
if (!remaining)
- return 0;
+ ret = 0;
else
- return recursive_loop(remaining - 1);
+ ret = recursive_loop((int)buf[remaining % sizeof(buf)] - 1);
+ memzero_explicit((void *)buf, sizeof(buf));
+ return ret;
}
/* If the depth is negative, use the default, otherwise keep parameter. */