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_shift_out_of_bounds(void) 46 { 47 volatile int val = -1; 48 int val2 = 10; 49 50 val2 <<= val; 51 } 52 53 static 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 61 static 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 75 static void test_ubsan_null_ptr_deref(void) 76 { 77 volatile int *ptr = NULL; 78 int val; 79 80 val = *ptr; 81 } 82 83 static 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 92 static 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 102 static 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 116 static 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 } 126 module_init(test_ubsan_init); 127 128 static void __exit test_ubsan_exit(void) 129 { 130 /* do nothing */ 131 } 132 module_exit(test_ubsan_exit); 133 134 MODULE_AUTHOR("Jinbum Park <jinb.park7@gmail.com>"); 135 MODULE_LICENSE("GPL v2"); 136