]>
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 | ||
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 | ||
31750600 | 91 | static void test_ubsan_misaligned_access(void) |
854686f4 JP |
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 <[email protected]>"); | |
144 | MODULE_LICENSE("GPL v2"); |