|
11 | 11 | #include <linux/sched/signal.h>
|
12 | 12 | #include <linux/sched/task_stack.h>
|
13 | 13 | #include <linux/uaccess.h>
|
| 14 | +#include <linux/slab.h> |
14 | 15 |
|
15 | 16 | #ifdef CONFIG_X86_32
|
16 | 17 | #include <asm/desc.h>
|
@@ -175,6 +176,80 @@ void lkdtm_HUNG_TASK(void)
|
175 | 176 | schedule();
|
176 | 177 | }
|
177 | 178 |
|
| 179 | +volatile unsigned int huge = INT_MAX - 2; |
| 180 | +volatile unsigned int ignored; |
| 181 | + |
| 182 | +void lkdtm_OVERFLOW_SIGNED(void) |
| 183 | +{ |
| 184 | + int value; |
| 185 | + |
| 186 | + value = huge; |
| 187 | + pr_info("Normal signed addition ...\n"); |
| 188 | + value += 1; |
| 189 | + ignored = value; |
| 190 | + |
| 191 | + pr_info("Overflowing signed addition ...\n"); |
| 192 | + value += 4; |
| 193 | + ignored = value; |
| 194 | +} |
| 195 | + |
| 196 | + |
| 197 | +void lkdtm_OVERFLOW_UNSIGNED(void) |
| 198 | +{ |
| 199 | + unsigned int value; |
| 200 | + |
| 201 | + value = huge; |
| 202 | + pr_info("Normal unsigned addition ...\n"); |
| 203 | + value += 1; |
| 204 | + ignored = value; |
| 205 | + |
| 206 | + pr_info("Overflowing unsigned addition ...\n"); |
| 207 | + value += 4; |
| 208 | + ignored = value; |
| 209 | +} |
| 210 | + |
| 211 | +/* Intentially using old-style flex array definition of 1 byte. */ |
| 212 | +struct array_bounds_flex_array { |
| 213 | + int one; |
| 214 | + int two; |
| 215 | + char data[1]; |
| 216 | +}; |
| 217 | + |
| 218 | +struct array_bounds { |
| 219 | + int one; |
| 220 | + int two; |
| 221 | + char data[8]; |
| 222 | + int three; |
| 223 | +}; |
| 224 | + |
| 225 | +void lkdtm_ARRAY_BOUNDS(void) |
| 226 | +{ |
| 227 | + struct array_bounds_flex_array *not_checked; |
| 228 | + struct array_bounds *checked; |
| 229 | + volatile int i; |
| 230 | + |
| 231 | + not_checked = kmalloc(sizeof(*not_checked) * 2, GFP_KERNEL); |
| 232 | + checked = kmalloc(sizeof(*checked) * 2, GFP_KERNEL); |
| 233 | + |
| 234 | + pr_info("Array access within bounds ...\n"); |
| 235 | + /* For both, touch all bytes in the actual member size. */ |
| 236 | + for (i = 0; i < sizeof(checked->data); i++) |
| 237 | + checked->data[i] = 'A'; |
| 238 | + /* |
| 239 | + * For the uninstrumented flex array member, also touch 1 byte |
| 240 | + * beyond to verify it is correctly uninstrumented. |
| 241 | + */ |
| 242 | + for (i = 0; i < sizeof(not_checked->data) + 1; i++) |
| 243 | + not_checked->data[i] = 'A'; |
| 244 | + |
| 245 | + pr_info("Array access beyond bounds ...\n"); |
| 246 | + for (i = 0; i < sizeof(checked->data) + 1; i++) |
| 247 | + checked->data[i] = 'B'; |
| 248 | + |
| 249 | + kfree(not_checked); |
| 250 | + kfree(checked); |
| 251 | +} |
| 252 | + |
178 | 253 | void lkdtm_CORRUPT_LIST_ADD(void)
|
179 | 254 | {
|
180 | 255 | /*
|
|
0 commit comments