Re: [PATCH 4/5] lkdtm/bugs: Add basic Overflow Behavior Types test
From: Justin Stitt
Date: Tue Mar 31 2026 - 13:26:24 EST
Hi,
On Tue, Mar 31, 2026 at 9:37 AM Kees Cook <kees@xxxxxxxxxx> wrote:
>
> Exercise the end-to-end build and trap infrastructure in the kernel for
> __ob_trap, __ob_wrap, and associated sanitizer ignore patterns (i.e. idiom
> exclusions). Add a test for each of the basic overflow conditions under
> CONFIG_OVERFLOW_BEHAVIOR_TYPES=y, as well as the corner cases associated
> with promotion, casting, etc.
>
> For example, executing this test with CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN=y
> (instead of CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP=y), will show:
>
> $ echo OBT_ASSIGN_TRUNCATE_TO | cat >/sys/kernel/debug/provoke-crash/DIRECT
> $ dmesg
> ...
> lkdtm: Performing direct entry OBT_ASSIGN_TRUNCATE_TO
> UBSAN: implicit-conversion in ../drivers/misc/lkdtm/bugs.c:825:10
> cannot represent 'int' value 2147483647 during reference binding to 'u8t' (aka '__ob_trap u8'), truncated to 255
>
> Signed-off-by: Kees Cook <kees@xxxxxxxxxx>
> ---
> Cc: Arnd Bergmann <arnd@xxxxxxxx>
> Cc: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> Cc: Shuah Khan <shuah@xxxxxxxxxx>
> Cc: <linux-kselftest@xxxxxxxxxxxxxxx>
> ---
> drivers/misc/lkdtm/bugs.c | 253 ++++++++++++++++++++++++
> tools/testing/selftests/lkdtm/tests.txt | 10 +
> 2 files changed, 263 insertions(+)
>
> diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c
> index e0098f314570..f00c9099957e 100644
> --- a/drivers/misc/lkdtm/bugs.c
> +++ b/drivers/misc/lkdtm/bugs.c
> @@ -817,6 +817,249 @@ static noinline void lkdtm_CORRUPT_PAC(void)
> #endif
> }
>
> +static void lkdtm_OBT_ASSIGN_TRUNCATE_TO(void)
> +{
> + volatile int big = INT_MAX;
> + volatile int wide_low_value = 5;
> + u8 __ob_trap narrow_low_value = 0;
> + s32 __ob_trap same = 0;
> + u8 __ob_trap small = 0;
> +
> + pr_info("Performing same-width assignment to OBT\n");
> + same = big;
> +
> + pr_info("Performing small-value assignment to OBT\n");
> + narrow_low_value = wide_low_value;
> +
> + pr_info("Expecting trap on truncated assignment to OBT\n");
> + small = big;
> +
> + pr_err("FAIL: survived overflowing truncated assignment to OBT: %d -> %u (ok: %d -> %u)\n",
> + same, small, wide_low_value, narrow_low_value);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
> +
> +static void lkdtm_OBT_ASSIGN_TRUNCATE_FROM(void)
> +{
> + volatile s32 __ob_trap big = INT_MAX;
> + volatile s32 __ob_trap wide_low_value = 5;
> + u8 narrow_low_value = 0;
> + s32 same = 0;
> + u8 small = 0;
> +
> + pr_info("Performing same-width assignment from OBT\n");
> + same = big;
> +
> + pr_info("Performing small-value assignment from OBT\n");
> + narrow_low_value = wide_low_value;
> +
> + pr_info("Expecting trap on truncated assignment from OBT\n");
> + small = big;
> +
> + pr_err("FAIL: survived overflowing truncated assignment from OBT: %d -> %u (ok: %d -> %u)\n",
> + same, small, wide_low_value, narrow_low_value);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
> +
> +static void lkdtm_OBT_CAST_TRUNCATE(void)
> +{
> + volatile u32 __ob_trap big = INT_MAX;
> + u32 trunc = 0;
> + u32 small = 0;
> +
> + pr_info("Performing wrapping too-small cast\n");
> + trunc = (u16 __ob_wrap)big;
> +
> + pr_info("Expecting trap on too-small cast\n");
> + small = (s16)big;
> +
> + pr_err("FAIL: survived truncated casting: %u -> %u (ok: %u -> %u)\n",
> + big, small, big, trunc);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
> +
> +static void lkdtm_OBT_CAST_SIGNED(void)
> +{
> + volatile u32 __ob_trap big = UINT_MAX;
> + s32 neg = 0;
> + s32 small = 0;
> +
> + pr_info("Performing explicit sign-changing cast\n");
> + neg = (s32 __ob_wrap)big;
> +
> + pr_info("Expecting trap on unexpected sign-changing cast\n");
> + small = (s32)big;
> +
> + pr_err("FAIL: survived lossy sign conversion: %u -> %d (forced: %u -> %d)\n",
> + big, small, big, neg);
> + pr_expected_config(CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP);
> +}
Note to travelers and testers, we still have a compiler patch in
flight [1] that fixes a bug with sign-change instrumentation
concerning OBTs.
> +
> +static void lkdtm_OBT_MUL(void)
> +{
> + /* Promotion means no overflow checking can happen. */
> + volatile u8 __ob_trap a8 = 100;
<snip>
[1]: https://github.com/llvm/llvm-project/pull/188340
Justin