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_vla_bound_not_positive(void)
  46{
  47        volatile int size = -1;
  48        char buf[size];
  49
  50        (void)buf;
  51}
  52
  53static void test_ubsan_shift_out_of_bounds(void)
  54{
  55        volatile int val = -1;
  56        int val2 = 10;
  57
  58        val2 <<= val;
  59}
  60
  61static void test_ubsan_out_of_bounds(void)
  62{
  63        volatile int i = 4, j = 5;
  64        volatile int arr[i];
  65
  66        arr[j] = i;
  67}
  68
  69static void test_ubsan_load_invalid_value(void)
  70{
  71        volatile char *dst, *src;
  72        bool val, val2, *ptr;
  73        char c = 4;
  74
  75        dst = (char *)&val;
  76        src = &c;
  77        *dst = *src;
  78
  79        ptr = &val2;
  80        val2 = val;
  81}
  82
  83static void test_ubsan_null_ptr_deref(void)
  84{
  85        volatile int *ptr = NULL;
  86        int val;
  87
  88        val = *ptr;
  89}
  90
  91static void test_ubsan_misaligned_access(void)
  92{
  93        volatile char arr[5] __aligned(4) = {1, 2, 3, 4, 5};
  94        volatile int *ptr, val = 6;
  95
  96        ptr = (int *)(arr + 1);
  97        *ptr = val;
  98}
  99
 100static void test_ubsan_object_size_mismatch(void)
 101{
 102        /* "((aligned(8)))" helps this not into be misaligned for ptr-access. */
 103        volatile int val __aligned(8) = 4;
 104        volatile long long *ptr, val2;
 105
 106        ptr = (long long *)&val;
 107        val2 = *ptr;
 108}
 109
 110static const test_ubsan_fp test_ubsan_array[] = {
 111        test_ubsan_add_overflow,
 112        test_ubsan_sub_overflow,
 113        test_ubsan_mul_overflow,
 114        test_ubsan_negate_overflow,
 115        test_ubsan_divrem_overflow,
 116        test_ubsan_vla_bound_not_positive,
 117        test_ubsan_shift_out_of_bounds,
 118        test_ubsan_out_of_bounds,
 119        test_ubsan_load_invalid_value,
 120        //test_ubsan_null_ptr_deref, /* exclude it because there is a crash */
 121        test_ubsan_misaligned_access,
 122        test_ubsan_object_size_mismatch,
 123};
 124
 125static int __init test_ubsan_init(void)
 126{
 127        unsigned int i;
 128
 129        for (i = 0; i < ARRAY_SIZE(test_ubsan_array); i++)
 130                test_ubsan_array[i]();
 131
 132        (void)test_ubsan_null_ptr_deref; /* to avoid unsed-function warning */
 133        return 0;
 134}
 135module_init(test_ubsan_init);
 136
 137static void __exit test_ubsan_exit(void)
 138{
 139        /* do nothing */
 140}
 141module_exit(test_ubsan_exit);
 142
 143MODULE_AUTHOR("Jinbum Park <jinb.park7@gmail.com>");
 144MODULE_LICENSE("GPL v2");
 145