]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
lkdtm/bugs: Adjust recursion test to avoid elision
authorKees Cook <keescook@chromium.org>
Sat, 6 Apr 2019 15:59:19 +0000 (08:59 -0700)
committerKees Cook <keescook@chromium.org>
Sun, 7 Apr 2019 17:38:31 +0000 (10:38 -0700)
While I was able to trick gcc into keeping a pathological recursion,
Clang was not so easily fooled. Instead, switch to using "volatile" and
side-effects to keep the stack variable allocated and to run the function.
Additionally renames "OVERFLOW" to "EXHAUST_STACK" to better describe the
test.

Signed-off-by: Kees Cook <keescook@chromium.org>
drivers/misc/lkdtm/bugs.c
drivers/misc/lkdtm/core.c
drivers/misc/lkdtm/lkdtm.h

index 7eebbdfbcacd0a51aef6f1d0c70e794b45ac3c03..17f839dee976626561ed3f780e5fb491dfdaed4b 100644 (file)
@@ -32,12 +32,20 @@ static int recur_count = REC_NUM_DEFAULT;
 
 static DEFINE_SPINLOCK(lock_me_up);
 
-static int recursive_loop(int remaining)
+/*
+ * 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())
+ * */
+static int noinline recursive_loop(int remaining)
 {
-       char buf[REC_STACK_SIZE];
+       volatile char buf[REC_STACK_SIZE];
 
-       /* Make sure compiler does not optimize this away. */
-       memset(buf, (remaining & 0xff) | 0x1, REC_STACK_SIZE);
+       memset((void *)buf, remaining & 0xFF, sizeof(buf));
+       pr_info("loop %d/%d ...\n", (int)buf[remaining % sizeof(buf)],
+               recur_count);
        if (!remaining)
                return 0;
        else
@@ -81,9 +89,12 @@ void lkdtm_LOOP(void)
                ;
 }
 
-void lkdtm_OVERFLOW(void)
+void lkdtm_EXHAUST_STACK(void)
 {
-       (void) recursive_loop(recur_count);
+       pr_info("Calling function with %d frame size to depth %d ...\n",
+               REC_STACK_SIZE, recur_count);
+       recursive_loop(recur_count);
+       pr_info("FAIL: survived without exhausting stack?!\n");
 }
 
 static noinline void __lkdtm_CORRUPT_STACK(void *stack)
index b51cf182b031951406fd6b5f0b3f057fa81ea765..4f3a6e1cd331108ff8c24d55ba6cb9d0b140fa57 100644 (file)
@@ -119,12 +119,12 @@ static const struct crashtype crashtypes[] = {
        CRASHTYPE(WARNING),
        CRASHTYPE(EXCEPTION),
        CRASHTYPE(LOOP),
-       CRASHTYPE(OVERFLOW),
+       CRASHTYPE(EXHAUST_STACK),
+       CRASHTYPE(CORRUPT_STACK),
+       CRASHTYPE(CORRUPT_STACK_STRONG),
        CRASHTYPE(CORRUPT_LIST_ADD),
        CRASHTYPE(CORRUPT_LIST_DEL),
        CRASHTYPE(CORRUPT_USER_DS),
-       CRASHTYPE(CORRUPT_STACK),
-       CRASHTYPE(CORRUPT_STACK_STRONG),
        CRASHTYPE(STACK_GUARD_PAGE_LEADING),
        CRASHTYPE(STACK_GUARD_PAGE_TRAILING),
        CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
index b69ee004a3f71b09e813d01565747e7ac23d6349..23dc565b4307af16cb1fa477f5649a41416446b8 100644 (file)
@@ -13,7 +13,7 @@ void lkdtm_BUG(void);
 void lkdtm_WARNING(void);
 void lkdtm_EXCEPTION(void);
 void lkdtm_LOOP(void);
-void lkdtm_OVERFLOW(void);
+void lkdtm_EXHAUST_STACK(void);
 void lkdtm_CORRUPT_STACK(void);
 void lkdtm_CORRUPT_STACK_STRONG(void);
 void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void);