Hi,

On Tue, Mar 31, 2026 at 9:37 AM Kees Cook <[email protected]> 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 <[email protected]>
> ---
> Cc: Arnd Bergmann <[email protected]>
> Cc: Greg Kroah-Hartman <[email protected]>
> Cc: Shuah Khan <[email protected]>
> Cc: <[email protected]>
> ---
>  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

Reply via email to