linux/lib/test_ubsan.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/init.h>
   3#include <linux/kernel.h>
   4#include <linux/module.h>
   5
   6typedef void(*test_ubsan_fp)(void);
   7
   8static void test_ubsan_add_overflow(void)
   9{
  10        volatile int val = INT_MAX;
  11
  12        val += 2;
  13}
  14
  15static void test_ubsan_sub_overflow(void)
  16{
  17        volatile int val = INT_MIN;
  18        volatile int val2 = 2;
  19
  20        val -= val2;
  21}
  22
  23static void test_ubsan_mul_overflow(void)
  24{
  25        volatile int val = INT_MAX / 2;
  26
  27        val *= 3;
  28}
  29
  30static void test_ubsan_negate_overflow(void)
  31{
  32        volatile int val = INT_MIN;
  33
  34        val = -val;
  35}
  36
  37static void test_ubsan_divrem_overflow(void)
  38{
  39        volatile int val = 16;
  40        volatile int val2 = 0;
  41
  42        val /= val2;
  43}
  44
  45static void test_ubsan_shift_out_of_bounds(void)
  46{
  47        volatile int val = -1;
  48        int val2 = 10;
  49
  50        val2 <<= val;
  51}
  52
  53static void test_ubsan_out_of_bounds(void)
  54{
  55        volatile int i = 4, j = 5;
  56        volatile int arr[4];
  57
  58        arr[j] = i;
  59}
  60
  61static void test_ubsan_load_invalid_value(void)
  62{
  63        volatile char *dst, *src;
  64        bool val, val2, *ptr;
  65        char c = 4;
  66
  67        dst = (char *)&val;
  68        src = &c;
  69        *dst = *src;
  70
  71        ptr = &val2;
  72        val2 = val;
  73}
  74
  75static void test_ubsan_null_ptr_deref(void)
  76{
  77        volatile int *ptr = NULL;
  78        int val;
  79
  80        val = *ptr;
  81}
  82
  83static void test_ubsan_misaligned_access(void)
  84{
  85        volatile char arr[5] __aligned(4) = {1, 2, 3, 4, 5};
  86        volatile int *ptr, val = 6;
  87
  88        ptr = (int *)(arr + 1);
  89        *ptr = val;
  90}
  91
  92static void test_ubsan_object_size_mismatch(void)
  93{
  94        /* "((aligned(8)))" helps this not into be misaligned for ptr-access. */
  95        volatile int val __aligned(8) = 4;
  96        volatile long long *ptr, val2;
  97
  98        ptr = (long long *)&val;
  99        val2 = *ptr;
 100}
 101
 102static const test_ubsan_fp test_ubsan_array[] = {
 103        test_ubsan_add_overflow,
 104        test_ubsan_sub_overflow,
 105        test_ubsan_mul_overflow,
 106        test_ubsan_negate_overflow,
 107        test_ubsan_divrem_overflow,
 108        test_ubsan_shift_out_of_bounds,
 109        test_ubsan_out_of_bounds,
 110        test_ubsan_load_invalid_value,
 111        //test_ubsan_null_ptr_deref, /* exclude it because there is a crash */
 112        test_ubsan_misaligned_access,
 113        test_ubsan_object_size_mismatch,
 114};
 115
 116static int __init test_ubsan_init(void)
 117{
 118        unsigned int i;
 119
 120        for (i = 0; i < ARRAY_SIZE(test_ubsan_array); i++)
 121                test_ubsan_array[i]();
 122
 123        (void)test_ubsan_null_ptr_deref; /* to avoid unsed-function warning */
 124        return 0;
 125}
 126module_init(test_ubsan_init);
 127
 128static void __exit test_ubsan_exit(void)
 129{
 130        /* do nothing */
 131}
 132module_exit(test_ubsan_exit);
 133
 134MODULE_AUTHOR("Jinbum Park <jinb.park7@gmail.com>");
 135MODULE_LICENSE("GPL v2");
 136