1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/init.h> 3 #include <linux/kernel.h> 4 #include <linux/module.h> 5 6 typedef void(*test_ubsan_fp)(void); 7 8 static void test_ubsan_add_overflow(void) 9 { 10 volatile int val = INT_MAX; 11 12 val += 2; 13 } 14 15 static void test_ubsan_sub_overflow(void) 16 { 17 volatile int val = INT_MIN; 18 volatile int val2 = 2; 19 20 val -= val2; 21 } 22 23 static void test_ubsan_mul_overflow(void) 24 { 25 volatile int val = INT_MAX / 2; 26 27 val *= 3; 28 } 29 30 static void test_ubsan_negate_overflow(void) 31 { 32 volatile int val = INT_MIN; 33 34 val = -val; 35 } 36 37 static void test_ubsan_divrem_overflow(void) 38 { 39 volatile int val = 16; 40 volatile int val2 = 0; 41 42 val /= val2; 43 } 44 45 static void test_ubsan_vla_bound_not_positive(void) 46 { 47 volatile int size = -1; 48 char buf[size]; 49 50 (void)buf; 51 } 52 53 static void test_ubsan_shift_out_of_bounds(void) 54 { 55 volatile int val = -1; 56 int val2 = 10; 57 58 val2 <<= val; 59 } 60 61 static 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 69 static 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 83 static void test_ubsan_null_ptr_deref(void) 84 { 85 volatile int *ptr = NULL; 86 int val; 87 88 val = *ptr; 89 } 90 91 static 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 100 static 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 110 static 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 125 static 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 } 135 module_init(test_ubsan_init); 136 137 static void __exit test_ubsan_exit(void) 138 { 139 /* do nothing */ 140 } 141 module_exit(test_ubsan_exit); 142 143 MODULE_AUTHOR("Jinbum Park <jinb.park7@gmail.com>"); 144 MODULE_LICENSE("GPL v2"); 145