lkdtm/bugs: Don't expect thread termination without CONFIG_UBSAN_TRAP
authorChristophe Leroy <christophe.leroy@csgroup.eu>
Mon, 11 Apr 2022 19:13:39 +0000 (21:13 +0200)
committerKees Cook <keescook@chromium.org>
Tue, 12 Apr 2022 23:16:48 +0000 (16:16 -0700)
When you don't select CONFIG_UBSAN_TRAP, you get:

  # echo ARRAY_BOUNDS > /sys/kernel/debug/provoke-crash/DIRECT
[  102.265827] ================================================================================
[  102.278433] UBSAN: array-index-out-of-bounds in drivers/misc/lkdtm/bugs.c:342:16
[  102.287207] index 8 is out of range for type 'char [8]'
[  102.298722] ================================================================================
[  102.313712] lkdtm: FAIL: survived array bounds overflow!
[  102.318770] lkdtm: Unexpected! This kernel (5.16.0-rc1-s3k-dev-01884-g720dcf79314a ppc) was built with CONFIG_UBSAN_BOUNDS=y

It is not correct because when CONFIG_UBSAN_TRAP is not selected
you can't expect array bounds overflow to kill the thread.

Modify the logic so that when the kernel is built with
CONFIG_UBSAN_BOUNDS but without CONFIG_UBSAN_TRAP, you get a warning
about CONFIG_UBSAN_TRAP not been selected instead.

This also require a fix of pr_expected_config(), otherwise the
following error is encountered.

  CC      drivers/misc/lkdtm/bugs.o
drivers/misc/lkdtm/bugs.c: In function 'lkdtm_ARRAY_BOUNDS':
drivers/misc/lkdtm/bugs.c:351:2: error: 'else' without a previous 'if'
  351 |  else
      |  ^~~~

Fixes: c75be56e35b2 ("lkdtm/bugs: Add ARRAY_BOUNDS to selftests")
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/363b58690e907c677252467a94fe49444c80ea76.1649704381.git.christophe.leroy@csgroup.eu
drivers/misc/lkdtm/bugs.c
drivers/misc/lkdtm/lkdtm.h

index 4f2808b..8cb342c 100644 (file)
@@ -351,7 +351,10 @@ void lkdtm_ARRAY_BOUNDS(void)
        kfree(not_checked);
        kfree(checked);
        pr_err("FAIL: survived array bounds overflow!\n");
-       pr_expected_config(CONFIG_UBSAN_BOUNDS);
+       if (IS_ENABLED(CONFIG_UBSAN_BOUNDS))
+               pr_expected_config(CONFIG_UBSAN_TRAP);
+       else
+               pr_expected_config(CONFIG_UBSAN_BOUNDS);
 }
 
 void lkdtm_CORRUPT_LIST_ADD(void)
index 305fc2e..90f87b1 100644 (file)
@@ -9,19 +9,19 @@
 extern char *lkdtm_kernel_info;
 
 #define pr_expected_config(kconfig)                            \
-{                                                              \
+do {                                                           \
        if (IS_ENABLED(kconfig))                                \
                pr_err("Unexpected! This %s was built with " #kconfig "=y\n", \
                        lkdtm_kernel_info);                     \
        else                                                    \
                pr_warn("This is probably expected, since this %s was built *without* " #kconfig "=y\n", \
                        lkdtm_kernel_info);                     \
-}
+} while (0)
 
 #ifndef MODULE
 int lkdtm_check_bool_cmdline(const char *param);
 #define pr_expected_config_param(kconfig, param)               \
-{                                                              \
+do {                                                           \
        if (IS_ENABLED(kconfig)) {                              \
                switch (lkdtm_check_bool_cmdline(param)) {      \
                case 0:                                         \
@@ -52,7 +52,7 @@ int lkdtm_check_bool_cmdline(const char *param);
                        break;                                  \
                }                                               \
        }                                                       \
-}
+} while (0)
 #else
 #define pr_expected_config_param(kconfig, param) pr_expected_config(kconfig)
 #endif