Commit | Line | Data |
---|---|---|
854686f4 JP |
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 | ||
854686f4 JP |
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; | |
9d7ca61b | 56 | volatile int arr[4]; |
854686f4 JP |
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 | ||
31750600 | 83 | static void test_ubsan_misaligned_access(void) |
854686f4 JP |
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, | |
854686f4 JP |
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"); |