Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lkdtm: Move crashtype definitions into each category

It's long been annoying that to add a new LKDTM test one had to update
lkdtm.h and core.c to get it "registered". Switch to a per-category
list and update the crashtype walking code in core.c to handle it.

This also means that all the lkdtm_* tests themselves can be static now.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Kees Cook <keescook@chromium.org>

+301 -292
+60 -26
drivers/misc/lkdtm/bugs.c
··· 68 68 recur_count = *recur_param; 69 69 } 70 70 71 - void lkdtm_PANIC(void) 71 + static void lkdtm_PANIC(void) 72 72 { 73 73 panic("dumptest"); 74 74 } 75 75 76 - void lkdtm_BUG(void) 76 + static void lkdtm_BUG(void) 77 77 { 78 78 BUG(); 79 79 } 80 80 81 81 static int warn_counter; 82 82 83 - void lkdtm_WARNING(void) 83 + static void lkdtm_WARNING(void) 84 84 { 85 85 WARN_ON(++warn_counter); 86 86 } 87 87 88 - void lkdtm_WARNING_MESSAGE(void) 88 + static void lkdtm_WARNING_MESSAGE(void) 89 89 { 90 90 WARN(1, "Warning message trigger count: %d\n", ++warn_counter); 91 91 } 92 92 93 - void lkdtm_EXCEPTION(void) 93 + static void lkdtm_EXCEPTION(void) 94 94 { 95 95 *((volatile int *) 0) = 0; 96 96 } 97 97 98 - void lkdtm_LOOP(void) 98 + static void lkdtm_LOOP(void) 99 99 { 100 100 for (;;) 101 101 ; 102 102 } 103 103 104 - void lkdtm_EXHAUST_STACK(void) 104 + static void lkdtm_EXHAUST_STACK(void) 105 105 { 106 106 pr_info("Calling function with %lu frame size to depth %d ...\n", 107 107 REC_STACK_SIZE, recur_count); ··· 115 115 } 116 116 117 117 /* This should trip the stack canary, not corrupt the return address. */ 118 - noinline void lkdtm_CORRUPT_STACK(void) 118 + static noinline void lkdtm_CORRUPT_STACK(void) 119 119 { 120 120 /* Use default char array length that triggers stack protection. */ 121 121 char data[8] __aligned(sizeof(void *)); ··· 125 125 } 126 126 127 127 /* Same as above but will only get a canary with -fstack-protector-strong */ 128 - noinline void lkdtm_CORRUPT_STACK_STRONG(void) 128 + static noinline void lkdtm_CORRUPT_STACK_STRONG(void) 129 129 { 130 130 union { 131 131 unsigned short shorts[4]; ··· 139 139 static pid_t stack_pid; 140 140 static unsigned long stack_addr; 141 141 142 - void lkdtm_REPORT_STACK(void) 142 + static void lkdtm_REPORT_STACK(void) 143 143 { 144 144 volatile uintptr_t magic; 145 145 pid_t pid = task_pid_nr(current); ··· 222 222 } 223 223 } 224 224 225 - void lkdtm_REPORT_STACK_CANARY(void) 225 + static void lkdtm_REPORT_STACK_CANARY(void) 226 226 { 227 227 /* Use default char array length that triggers stack protection. */ 228 228 char data[8] __aligned(sizeof(void *)) = { }; ··· 230 230 __lkdtm_REPORT_STACK_CANARY((void *)&data); 231 231 } 232 232 233 - void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void) 233 + static void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void) 234 234 { 235 235 static u8 data[5] __attribute__((aligned(4))) = {1, 2, 3, 4, 5}; 236 236 u32 *p; ··· 245 245 pr_err("XFAIL: arch has CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS\n"); 246 246 } 247 247 248 - void lkdtm_SOFTLOCKUP(void) 248 + static void lkdtm_SOFTLOCKUP(void) 249 249 { 250 250 preempt_disable(); 251 251 for (;;) 252 252 cpu_relax(); 253 253 } 254 254 255 - void lkdtm_HARDLOCKUP(void) 255 + static void lkdtm_HARDLOCKUP(void) 256 256 { 257 257 local_irq_disable(); 258 258 for (;;) 259 259 cpu_relax(); 260 260 } 261 261 262 - void lkdtm_SPINLOCKUP(void) 262 + static void lkdtm_SPINLOCKUP(void) 263 263 { 264 264 /* Must be called twice to trigger. */ 265 265 spin_lock(&lock_me_up); ··· 267 267 __release(&lock_me_up); 268 268 } 269 269 270 - void lkdtm_HUNG_TASK(void) 270 + static void lkdtm_HUNG_TASK(void) 271 271 { 272 272 set_current_state(TASK_UNINTERRUPTIBLE); 273 273 schedule(); ··· 276 276 volatile unsigned int huge = INT_MAX - 2; 277 277 volatile unsigned int ignored; 278 278 279 - void lkdtm_OVERFLOW_SIGNED(void) 279 + static void lkdtm_OVERFLOW_SIGNED(void) 280 280 { 281 281 int value; 282 282 ··· 291 291 } 292 292 293 293 294 - void lkdtm_OVERFLOW_UNSIGNED(void) 294 + static void lkdtm_OVERFLOW_UNSIGNED(void) 295 295 { 296 296 unsigned int value; 297 297 ··· 319 319 int three; 320 320 }; 321 321 322 - void lkdtm_ARRAY_BOUNDS(void) 322 + static void lkdtm_ARRAY_BOUNDS(void) 323 323 { 324 324 struct array_bounds_flex_array *not_checked; 325 325 struct array_bounds *checked; ··· 357 357 pr_expected_config(CONFIG_UBSAN_BOUNDS); 358 358 } 359 359 360 - void lkdtm_CORRUPT_LIST_ADD(void) 360 + static void lkdtm_CORRUPT_LIST_ADD(void) 361 361 { 362 362 /* 363 363 * Initially, an empty list via LIST_HEAD: ··· 397 397 } 398 398 } 399 399 400 - void lkdtm_CORRUPT_LIST_DEL(void) 400 + static void lkdtm_CORRUPT_LIST_DEL(void) 401 401 { 402 402 LIST_HEAD(test_head); 403 403 struct lkdtm_list item; ··· 425 425 } 426 426 427 427 /* Test that VMAP_STACK is actually allocating with a leading guard page */ 428 - void lkdtm_STACK_GUARD_PAGE_LEADING(void) 428 + static void lkdtm_STACK_GUARD_PAGE_LEADING(void) 429 429 { 430 430 const unsigned char *stack = task_stack_page(current); 431 431 const unsigned char *ptr = stack - 1; ··· 439 439 } 440 440 441 441 /* Test that VMAP_STACK is actually allocating with a trailing guard page */ 442 - void lkdtm_STACK_GUARD_PAGE_TRAILING(void) 442 + static void lkdtm_STACK_GUARD_PAGE_TRAILING(void) 443 443 { 444 444 const unsigned char *stack = task_stack_page(current); 445 445 const unsigned char *ptr = stack + THREAD_SIZE; ··· 452 452 pr_err("FAIL: accessed page after stack! (byte: %x)\n", byte); 453 453 } 454 454 455 - void lkdtm_UNSET_SMEP(void) 455 + static void lkdtm_UNSET_SMEP(void) 456 456 { 457 457 #if IS_ENABLED(CONFIG_X86_64) && !IS_ENABLED(CONFIG_UML) 458 458 #define MOV_CR4_DEPTH 64 ··· 518 518 #endif 519 519 } 520 520 521 - void lkdtm_DOUBLE_FAULT(void) 521 + static void lkdtm_DOUBLE_FAULT(void) 522 522 { 523 523 #if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML) 524 524 /* ··· 566 566 } 567 567 #endif 568 568 569 - noinline void lkdtm_CORRUPT_PAC(void) 569 + static noinline void lkdtm_CORRUPT_PAC(void) 570 570 { 571 571 #ifdef CONFIG_ARM64 572 572 #define CORRUPT_PAC_ITERATE 10 ··· 594 594 pr_err("XFAIL: this test is arm64-only\n"); 595 595 #endif 596 596 } 597 + 598 + static struct crashtype crashtypes[] = { 599 + CRASHTYPE(PANIC), 600 + CRASHTYPE(BUG), 601 + CRASHTYPE(WARNING), 602 + CRASHTYPE(WARNING_MESSAGE), 603 + CRASHTYPE(EXCEPTION), 604 + CRASHTYPE(LOOP), 605 + CRASHTYPE(EXHAUST_STACK), 606 + CRASHTYPE(CORRUPT_STACK), 607 + CRASHTYPE(CORRUPT_STACK_STRONG), 608 + CRASHTYPE(REPORT_STACK), 609 + CRASHTYPE(REPORT_STACK_CANARY), 610 + CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), 611 + CRASHTYPE(SOFTLOCKUP), 612 + CRASHTYPE(HARDLOCKUP), 613 + CRASHTYPE(SPINLOCKUP), 614 + CRASHTYPE(HUNG_TASK), 615 + CRASHTYPE(OVERFLOW_SIGNED), 616 + CRASHTYPE(OVERFLOW_UNSIGNED), 617 + CRASHTYPE(ARRAY_BOUNDS), 618 + CRASHTYPE(CORRUPT_LIST_ADD), 619 + CRASHTYPE(CORRUPT_LIST_DEL), 620 + CRASHTYPE(STACK_GUARD_PAGE_LEADING), 621 + CRASHTYPE(STACK_GUARD_PAGE_TRAILING), 622 + CRASHTYPE(UNSET_SMEP), 623 + CRASHTYPE(DOUBLE_FAULT), 624 + CRASHTYPE(CORRUPT_PAC), 625 + }; 626 + 627 + struct crashtype_category bugs_crashtypes = { 628 + .crashtypes = crashtypes, 629 + .len = ARRAY_SIZE(crashtypes), 630 + };
+10 -1
drivers/misc/lkdtm/cfi.c
··· 22 22 /* 23 23 * This tries to call an indirect function with a mismatched prototype. 24 24 */ 25 - void lkdtm_CFI_FORWARD_PROTO(void) 25 + static void lkdtm_CFI_FORWARD_PROTO(void) 26 26 { 27 27 /* 28 28 * Matches lkdtm_increment_void()'s prototype, but not ··· 41 41 pr_err("FAIL: survived mismatched prototype function call!\n"); 42 42 pr_expected_config(CONFIG_CFI_CLANG); 43 43 } 44 + 45 + static struct crashtype crashtypes[] = { 46 + CRASHTYPE(CFI_FORWARD_PROTO), 47 + }; 48 + 49 + struct crashtype_category cfi_crashtypes = { 50 + .crashtypes = crashtypes, 51 + .len = ARRAY_SIZE(crashtypes), 52 + };
+31 -107
drivers/misc/lkdtm/core.c
··· 86 86 #endif 87 87 }; 88 88 89 - 90 - /* Crash types. */ 91 - struct crashtype { 92 - const char *name; 93 - void (*func)(void); 94 - }; 95 - 96 - #define CRASHTYPE(_name) \ 97 - { \ 98 - .name = __stringify(_name), \ 99 - .func = lkdtm_ ## _name, \ 100 - } 101 - 102 - /* Define the possible types of crashes that can be triggered. */ 103 - static const struct crashtype crashtypes[] = { 104 - CRASHTYPE(PANIC), 105 - CRASHTYPE(BUG), 106 - CRASHTYPE(WARNING), 107 - CRASHTYPE(WARNING_MESSAGE), 108 - CRASHTYPE(EXCEPTION), 109 - CRASHTYPE(LOOP), 110 - CRASHTYPE(EXHAUST_STACK), 111 - CRASHTYPE(CORRUPT_STACK), 112 - CRASHTYPE(CORRUPT_STACK_STRONG), 113 - CRASHTYPE(REPORT_STACK), 114 - CRASHTYPE(REPORT_STACK_CANARY), 115 - CRASHTYPE(CORRUPT_LIST_ADD), 116 - CRASHTYPE(CORRUPT_LIST_DEL), 117 - CRASHTYPE(STACK_GUARD_PAGE_LEADING), 118 - CRASHTYPE(STACK_GUARD_PAGE_TRAILING), 119 - CRASHTYPE(UNSET_SMEP), 120 - CRASHTYPE(CORRUPT_PAC), 121 - CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), 122 - CRASHTYPE(SLAB_LINEAR_OVERFLOW), 123 - CRASHTYPE(VMALLOC_LINEAR_OVERFLOW), 124 - CRASHTYPE(WRITE_AFTER_FREE), 125 - CRASHTYPE(READ_AFTER_FREE), 126 - CRASHTYPE(WRITE_BUDDY_AFTER_FREE), 127 - CRASHTYPE(READ_BUDDY_AFTER_FREE), 128 - CRASHTYPE(SLAB_INIT_ON_ALLOC), 129 - CRASHTYPE(BUDDY_INIT_ON_ALLOC), 130 - CRASHTYPE(SLAB_FREE_DOUBLE), 131 - CRASHTYPE(SLAB_FREE_CROSS), 132 - CRASHTYPE(SLAB_FREE_PAGE), 133 - CRASHTYPE(SOFTLOCKUP), 134 - CRASHTYPE(HARDLOCKUP), 135 - CRASHTYPE(SPINLOCKUP), 136 - CRASHTYPE(HUNG_TASK), 137 - CRASHTYPE(OVERFLOW_SIGNED), 138 - CRASHTYPE(OVERFLOW_UNSIGNED), 139 - CRASHTYPE(ARRAY_BOUNDS), 140 - CRASHTYPE(EXEC_DATA), 141 - CRASHTYPE(EXEC_STACK), 142 - CRASHTYPE(EXEC_KMALLOC), 143 - CRASHTYPE(EXEC_VMALLOC), 144 - CRASHTYPE(EXEC_RODATA), 145 - CRASHTYPE(EXEC_USERSPACE), 146 - CRASHTYPE(EXEC_NULL), 147 - CRASHTYPE(ACCESS_USERSPACE), 148 - CRASHTYPE(ACCESS_NULL), 149 - CRASHTYPE(WRITE_RO), 150 - CRASHTYPE(WRITE_RO_AFTER_INIT), 151 - CRASHTYPE(WRITE_KERN), 152 - CRASHTYPE(WRITE_OPD), 153 - CRASHTYPE(REFCOUNT_INC_OVERFLOW), 154 - CRASHTYPE(REFCOUNT_ADD_OVERFLOW), 155 - CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW), 156 - CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_OVERFLOW), 157 - CRASHTYPE(REFCOUNT_DEC_ZERO), 158 - CRASHTYPE(REFCOUNT_DEC_NEGATIVE), 159 - CRASHTYPE(REFCOUNT_DEC_AND_TEST_NEGATIVE), 160 - CRASHTYPE(REFCOUNT_SUB_AND_TEST_NEGATIVE), 161 - CRASHTYPE(REFCOUNT_INC_ZERO), 162 - CRASHTYPE(REFCOUNT_ADD_ZERO), 163 - CRASHTYPE(REFCOUNT_INC_SATURATED), 164 - CRASHTYPE(REFCOUNT_DEC_SATURATED), 165 - CRASHTYPE(REFCOUNT_ADD_SATURATED), 166 - CRASHTYPE(REFCOUNT_INC_NOT_ZERO_SATURATED), 167 - CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_SATURATED), 168 - CRASHTYPE(REFCOUNT_DEC_AND_TEST_SATURATED), 169 - CRASHTYPE(REFCOUNT_SUB_AND_TEST_SATURATED), 170 - CRASHTYPE(REFCOUNT_TIMING), 171 - CRASHTYPE(ATOMIC_TIMING), 172 - CRASHTYPE(USERCOPY_HEAP_SIZE_TO), 173 - CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), 174 - CRASHTYPE(USERCOPY_HEAP_WHITELIST_TO), 175 - CRASHTYPE(USERCOPY_HEAP_WHITELIST_FROM), 176 - CRASHTYPE(USERCOPY_STACK_FRAME_TO), 177 - CRASHTYPE(USERCOPY_STACK_FRAME_FROM), 178 - CRASHTYPE(USERCOPY_STACK_BEYOND), 179 - CRASHTYPE(USERCOPY_KERNEL), 180 - CRASHTYPE(STACKLEAK_ERASING), 181 - CRASHTYPE(CFI_FORWARD_PROTO), 182 - CRASHTYPE(FORTIFIED_OBJECT), 183 - CRASHTYPE(FORTIFIED_SUBOBJECT), 184 - CRASHTYPE(FORTIFIED_STRSCPY), 185 - CRASHTYPE(DOUBLE_FAULT), 89 + /* List of possible types for crashes that can be triggered. */ 90 + static const struct crashtype_category *crashtype_categories[] = { 91 + &bugs_crashtypes, 92 + &heap_crashtypes, 93 + &perms_crashtypes, 94 + &refcount_crashtypes, 95 + &usercopy_crashtypes, 96 + &stackleak_crashtypes, 97 + &cfi_crashtypes, 98 + &fortify_crashtypes, 186 99 #ifdef CONFIG_PPC_64S_HASH_MMU 187 - CRASHTYPE(PPC_SLB_MULTIHIT), 100 + &powerpc_crashtypes, 188 101 #endif 189 102 }; 190 - 191 103 192 104 /* Global kprobe entry and crashtype. */ 193 105 static struct kprobe *lkdtm_kprobe; ··· 135 223 /* Return the crashtype number or NULL if the name is invalid */ 136 224 static const struct crashtype *find_crashtype(const char *name) 137 225 { 138 - int i; 226 + int cat, idx; 139 227 140 - for (i = 0; i < ARRAY_SIZE(crashtypes); i++) { 141 - if (!strcmp(name, crashtypes[i].name)) 142 - return &crashtypes[i]; 228 + for (cat = 0; cat < ARRAY_SIZE(crashtype_categories); cat++) { 229 + for (idx = 0; idx < crashtype_categories[cat]->len; idx++) { 230 + struct crashtype *crashtype; 231 + 232 + crashtype = &crashtype_categories[cat]->crashtypes[idx]; 233 + if (!strcmp(name, crashtype->name)) 234 + return crashtype; 235 + } 143 236 } 144 237 145 238 return NULL; ··· 264 347 static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf, 265 348 size_t count, loff_t *off) 266 349 { 350 + int n, cat, idx; 351 + ssize_t out; 267 352 char *buf; 268 - int i, n, out; 269 353 270 354 buf = (char *)__get_free_page(GFP_KERNEL); 271 355 if (buf == NULL) 272 356 return -ENOMEM; 273 357 274 358 n = scnprintf(buf, PAGE_SIZE, "Available crash types:\n"); 275 - for (i = 0; i < ARRAY_SIZE(crashtypes); i++) { 276 - n += scnprintf(buf + n, PAGE_SIZE - n, "%s\n", 277 - crashtypes[i].name); 359 + 360 + for (cat = 0; cat < ARRAY_SIZE(crashtype_categories); cat++) { 361 + for (idx = 0; idx < crashtype_categories[cat]->len; idx++) { 362 + struct crashtype *crashtype; 363 + 364 + crashtype = &crashtype_categories[cat]->crashtypes[idx]; 365 + n += scnprintf(buf + n, PAGE_SIZE - n, "%s\n", 366 + crashtype->name); 367 + } 278 368 } 279 369 buf[n] = '\0'; 280 370
+14 -3
drivers/misc/lkdtm/fortify.c
··· 10 10 11 11 static volatile int fortify_scratch_space; 12 12 13 - void lkdtm_FORTIFIED_OBJECT(void) 13 + static void lkdtm_FORTIFIED_OBJECT(void) 14 14 { 15 15 struct target { 16 16 char a[10]; ··· 31 31 pr_expected_config(CONFIG_FORTIFY_SOURCE); 32 32 } 33 33 34 - void lkdtm_FORTIFIED_SUBOBJECT(void) 34 + static void lkdtm_FORTIFIED_SUBOBJECT(void) 35 35 { 36 36 struct target { 37 37 char a[10]; ··· 67 67 * strscpy and generate a panic because there is a write overflow (i.e. src 68 68 * length is greater than dst length). 69 69 */ 70 - void lkdtm_FORTIFIED_STRSCPY(void) 70 + static void lkdtm_FORTIFIED_STRSCPY(void) 71 71 { 72 72 char *src; 73 73 char dst[5]; ··· 134 134 135 135 kfree(src); 136 136 } 137 + 138 + static struct crashtype crashtypes[] = { 139 + CRASHTYPE(FORTIFIED_OBJECT), 140 + CRASHTYPE(FORTIFIED_SUBOBJECT), 141 + CRASHTYPE(FORTIFIED_STRSCPY), 142 + }; 143 + 144 + struct crashtype_category fortify_crashtypes = { 145 + .crashtypes = crashtypes, 146 + .len = ARRAY_SIZE(crashtypes), 147 + };
+30 -11
drivers/misc/lkdtm/heap.c
··· 26 26 * This should always be caught because there is an unconditional unmapped 27 27 * page after vmap allocations. 28 28 */ 29 - void lkdtm_VMALLOC_LINEAR_OVERFLOW(void) 29 + static void lkdtm_VMALLOC_LINEAR_OVERFLOW(void) 30 30 { 31 31 char *one, *two; 32 32 ··· 48 48 * This should get caught by either memory tagging, KASan, or by using 49 49 * CONFIG_SLUB_DEBUG=y and slub_debug=ZF (or CONFIG_SLUB_DEBUG_ON=y). 50 50 */ 51 - void lkdtm_SLAB_LINEAR_OVERFLOW(void) 51 + static void lkdtm_SLAB_LINEAR_OVERFLOW(void) 52 52 { 53 53 size_t len = 1020; 54 54 u32 *data = kmalloc(len, GFP_KERNEL); ··· 60 60 kfree(data); 61 61 } 62 62 63 - void lkdtm_WRITE_AFTER_FREE(void) 63 + static void lkdtm_WRITE_AFTER_FREE(void) 64 64 { 65 65 int *base, *again; 66 66 size_t len = 1024; ··· 86 86 pr_info("Hmm, didn't get the same memory range.\n"); 87 87 } 88 88 89 - void lkdtm_READ_AFTER_FREE(void) 89 + static void lkdtm_READ_AFTER_FREE(void) 90 90 { 91 91 int *base, *val, saw; 92 92 size_t len = 1024; ··· 130 130 kfree(val); 131 131 } 132 132 133 - void lkdtm_WRITE_BUDDY_AFTER_FREE(void) 133 + static void lkdtm_WRITE_BUDDY_AFTER_FREE(void) 134 134 { 135 135 unsigned long p = __get_free_page(GFP_KERNEL); 136 136 if (!p) { ··· 150 150 schedule(); 151 151 } 152 152 153 - void lkdtm_READ_BUDDY_AFTER_FREE(void) 153 + static void lkdtm_READ_BUDDY_AFTER_FREE(void) 154 154 { 155 155 unsigned long p = __get_free_page(GFP_KERNEL); 156 156 int saw, *val; ··· 187 187 kfree(val); 188 188 } 189 189 190 - void lkdtm_SLAB_INIT_ON_ALLOC(void) 190 + static void lkdtm_SLAB_INIT_ON_ALLOC(void) 191 191 { 192 192 u8 *first; 193 193 u8 *val; ··· 219 219 kfree(val); 220 220 } 221 221 222 - void lkdtm_BUDDY_INIT_ON_ALLOC(void) 222 + static void lkdtm_BUDDY_INIT_ON_ALLOC(void) 223 223 { 224 224 u8 *first; 225 225 u8 *val; ··· 252 252 free_page((unsigned long)val); 253 253 } 254 254 255 - void lkdtm_SLAB_FREE_DOUBLE(void) 255 + static void lkdtm_SLAB_FREE_DOUBLE(void) 256 256 { 257 257 int *val; 258 258 ··· 269 269 kmem_cache_free(double_free_cache, val); 270 270 } 271 271 272 - void lkdtm_SLAB_FREE_CROSS(void) 272 + static void lkdtm_SLAB_FREE_CROSS(void) 273 273 { 274 274 int *val; 275 275 ··· 285 285 kmem_cache_free(b_cache, val); 286 286 } 287 287 288 - void lkdtm_SLAB_FREE_PAGE(void) 288 + static void lkdtm_SLAB_FREE_PAGE(void) 289 289 { 290 290 unsigned long p = __get_free_page(GFP_KERNEL); 291 291 ··· 319 319 kmem_cache_destroy(a_cache); 320 320 kmem_cache_destroy(b_cache); 321 321 } 322 + 323 + static struct crashtype crashtypes[] = { 324 + CRASHTYPE(SLAB_LINEAR_OVERFLOW), 325 + CRASHTYPE(VMALLOC_LINEAR_OVERFLOW), 326 + CRASHTYPE(WRITE_AFTER_FREE), 327 + CRASHTYPE(READ_AFTER_FREE), 328 + CRASHTYPE(WRITE_BUDDY_AFTER_FREE), 329 + CRASHTYPE(READ_BUDDY_AFTER_FREE), 330 + CRASHTYPE(SLAB_INIT_ON_ALLOC), 331 + CRASHTYPE(BUDDY_INIT_ON_ALLOC), 332 + CRASHTYPE(SLAB_FREE_DOUBLE), 333 + CRASHTYPE(SLAB_FREE_CROSS), 334 + CRASHTYPE(SLAB_FREE_PAGE), 335 + }; 336 + 337 + struct crashtype_category heap_crashtypes = { 338 + .crashtypes = crashtypes, 339 + .len = ARRAY_SIZE(crashtypes), 340 + };
+32 -102
drivers/misc/lkdtm/lkdtm.h
··· 57 57 #define pr_expected_config_param(kconfig, param) pr_expected_config(kconfig) 58 58 #endif 59 59 60 - /* bugs.c */ 61 - void __init lkdtm_bugs_init(int *recur_param); 62 - void lkdtm_PANIC(void); 63 - void lkdtm_BUG(void); 64 - void lkdtm_WARNING(void); 65 - void lkdtm_WARNING_MESSAGE(void); 66 - void lkdtm_EXCEPTION(void); 67 - void lkdtm_LOOP(void); 68 - void lkdtm_EXHAUST_STACK(void); 69 - void lkdtm_CORRUPT_STACK(void); 70 - void lkdtm_CORRUPT_STACK_STRONG(void); 71 - void lkdtm_REPORT_STACK(void); 72 - void lkdtm_REPORT_STACK_CANARY(void); 73 - void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void); 74 - void lkdtm_SOFTLOCKUP(void); 75 - void lkdtm_HARDLOCKUP(void); 76 - void lkdtm_SPINLOCKUP(void); 77 - void lkdtm_HUNG_TASK(void); 78 - void lkdtm_OVERFLOW_SIGNED(void); 79 - void lkdtm_OVERFLOW_UNSIGNED(void); 80 - void lkdtm_ARRAY_BOUNDS(void); 81 - void lkdtm_CORRUPT_LIST_ADD(void); 82 - void lkdtm_CORRUPT_LIST_DEL(void); 83 - void lkdtm_STACK_GUARD_PAGE_LEADING(void); 84 - void lkdtm_STACK_GUARD_PAGE_TRAILING(void); 85 - void lkdtm_UNSET_SMEP(void); 86 - void lkdtm_DOUBLE_FAULT(void); 87 - void lkdtm_CORRUPT_PAC(void); 60 + /* Crash types. */ 61 + struct crashtype { 62 + const char *name; 63 + void (*func)(void); 64 + }; 88 65 89 - /* heap.c */ 66 + #define CRASHTYPE(_name) \ 67 + { \ 68 + .name = __stringify(_name), \ 69 + .func = lkdtm_ ## _name, \ 70 + } 71 + 72 + /* Category's collection of crashtypes. */ 73 + struct crashtype_category { 74 + struct crashtype *crashtypes; 75 + size_t len; 76 + }; 77 + 78 + /* Each category's crashtypes list. */ 79 + extern struct crashtype_category bugs_crashtypes; 80 + extern struct crashtype_category heap_crashtypes; 81 + extern struct crashtype_category perms_crashtypes; 82 + extern struct crashtype_category refcount_crashtypes; 83 + extern struct crashtype_category usercopy_crashtypes; 84 + extern struct crashtype_category stackleak_crashtypes; 85 + extern struct crashtype_category cfi_crashtypes; 86 + extern struct crashtype_category fortify_crashtypes; 87 + extern struct crashtype_category powerpc_crashtypes; 88 + 89 + /* Each category's init/exit routines. */ 90 + void __init lkdtm_bugs_init(int *recur_param); 90 91 void __init lkdtm_heap_init(void); 91 92 void __exit lkdtm_heap_exit(void); 92 - void lkdtm_VMALLOC_LINEAR_OVERFLOW(void); 93 - void lkdtm_SLAB_LINEAR_OVERFLOW(void); 94 - void lkdtm_WRITE_AFTER_FREE(void); 95 - void lkdtm_READ_AFTER_FREE(void); 96 - void lkdtm_WRITE_BUDDY_AFTER_FREE(void); 97 - void lkdtm_READ_BUDDY_AFTER_FREE(void); 98 - void lkdtm_SLAB_INIT_ON_ALLOC(void); 99 - void lkdtm_BUDDY_INIT_ON_ALLOC(void); 100 - void lkdtm_SLAB_FREE_DOUBLE(void); 101 - void lkdtm_SLAB_FREE_CROSS(void); 102 - void lkdtm_SLAB_FREE_PAGE(void); 103 - 104 - /* perms.c */ 105 93 void __init lkdtm_perms_init(void); 106 - void lkdtm_WRITE_RO(void); 107 - void lkdtm_WRITE_RO_AFTER_INIT(void); 108 - void lkdtm_WRITE_KERN(void); 109 - void lkdtm_WRITE_OPD(void); 110 - void lkdtm_EXEC_DATA(void); 111 - void lkdtm_EXEC_STACK(void); 112 - void lkdtm_EXEC_KMALLOC(void); 113 - void lkdtm_EXEC_VMALLOC(void); 114 - void lkdtm_EXEC_RODATA(void); 115 - void lkdtm_EXEC_USERSPACE(void); 116 - void lkdtm_EXEC_NULL(void); 117 - void lkdtm_ACCESS_USERSPACE(void); 118 - void lkdtm_ACCESS_NULL(void); 119 - 120 - /* refcount.c */ 121 - void lkdtm_REFCOUNT_INC_OVERFLOW(void); 122 - void lkdtm_REFCOUNT_ADD_OVERFLOW(void); 123 - void lkdtm_REFCOUNT_INC_NOT_ZERO_OVERFLOW(void); 124 - void lkdtm_REFCOUNT_ADD_NOT_ZERO_OVERFLOW(void); 125 - void lkdtm_REFCOUNT_DEC_ZERO(void); 126 - void lkdtm_REFCOUNT_DEC_NEGATIVE(void); 127 - void lkdtm_REFCOUNT_DEC_AND_TEST_NEGATIVE(void); 128 - void lkdtm_REFCOUNT_SUB_AND_TEST_NEGATIVE(void); 129 - void lkdtm_REFCOUNT_INC_ZERO(void); 130 - void lkdtm_REFCOUNT_ADD_ZERO(void); 131 - void lkdtm_REFCOUNT_INC_SATURATED(void); 132 - void lkdtm_REFCOUNT_DEC_SATURATED(void); 133 - void lkdtm_REFCOUNT_ADD_SATURATED(void); 134 - void lkdtm_REFCOUNT_INC_NOT_ZERO_SATURATED(void); 135 - void lkdtm_REFCOUNT_ADD_NOT_ZERO_SATURATED(void); 136 - void lkdtm_REFCOUNT_DEC_AND_TEST_SATURATED(void); 137 - void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void); 138 - void lkdtm_REFCOUNT_TIMING(void); 139 - void lkdtm_ATOMIC_TIMING(void); 140 - 141 - /* rodata.c */ 142 - void lkdtm_rodata_do_nothing(void); 143 - 144 - /* usercopy.c */ 145 94 void __init lkdtm_usercopy_init(void); 146 95 void __exit lkdtm_usercopy_exit(void); 147 - void lkdtm_USERCOPY_HEAP_SIZE_TO(void); 148 - void lkdtm_USERCOPY_HEAP_SIZE_FROM(void); 149 - void lkdtm_USERCOPY_HEAP_WHITELIST_TO(void); 150 - void lkdtm_USERCOPY_HEAP_WHITELIST_FROM(void); 151 - void lkdtm_USERCOPY_STACK_FRAME_TO(void); 152 - void lkdtm_USERCOPY_STACK_FRAME_FROM(void); 153 - void lkdtm_USERCOPY_STACK_BEYOND(void); 154 - void lkdtm_USERCOPY_KERNEL(void); 155 96 156 - /* stackleak.c */ 157 - void lkdtm_STACKLEAK_ERASING(void); 158 - 159 - /* cfi.c */ 160 - void lkdtm_CFI_FORWARD_PROTO(void); 161 - 162 - /* fortify.c */ 163 - void lkdtm_FORTIFIED_OBJECT(void); 164 - void lkdtm_FORTIFIED_SUBOBJECT(void); 165 - void lkdtm_FORTIFIED_STRSCPY(void); 166 - 167 - /* powerpc.c */ 168 - void lkdtm_PPC_SLB_MULTIHIT(void); 97 + /* Special declaration for function-in-rodata. */ 98 + void lkdtm_rodata_do_nothing(void); 169 99 170 100 #endif
+34 -13
drivers/misc/lkdtm/perms.c
··· 103 103 pr_err("FAIL: func returned\n"); 104 104 } 105 105 106 - void lkdtm_WRITE_RO(void) 106 + static void lkdtm_WRITE_RO(void) 107 107 { 108 108 /* Explicitly cast away "const" for the test and make volatile. */ 109 109 volatile unsigned long *ptr = (unsigned long *)&rodata; ··· 113 113 pr_err("FAIL: survived bad write\n"); 114 114 } 115 115 116 - void lkdtm_WRITE_RO_AFTER_INIT(void) 116 + static void lkdtm_WRITE_RO_AFTER_INIT(void) 117 117 { 118 118 volatile unsigned long *ptr = &ro_after_init; 119 119 ··· 132 132 pr_err("FAIL: survived bad write\n"); 133 133 } 134 134 135 - void lkdtm_WRITE_KERN(void) 135 + static void lkdtm_WRITE_KERN(void) 136 136 { 137 137 size_t size; 138 138 volatile unsigned char *ptr; ··· 149 149 do_overwritten(); 150 150 } 151 151 152 - void lkdtm_WRITE_OPD(void) 152 + static void lkdtm_WRITE_OPD(void) 153 153 { 154 154 size_t size = sizeof(func_desc_t); 155 155 void (*func)(void) = do_nothing; ··· 166 166 func(); 167 167 } 168 168 169 - void lkdtm_EXEC_DATA(void) 169 + static void lkdtm_EXEC_DATA(void) 170 170 { 171 171 execute_location(data_area, CODE_WRITE); 172 172 } 173 173 174 - void lkdtm_EXEC_STACK(void) 174 + static void lkdtm_EXEC_STACK(void) 175 175 { 176 176 u8 stack_area[EXEC_SIZE]; 177 177 execute_location(stack_area, CODE_WRITE); 178 178 } 179 179 180 - void lkdtm_EXEC_KMALLOC(void) 180 + static void lkdtm_EXEC_KMALLOC(void) 181 181 { 182 182 u32 *kmalloc_area = kmalloc(EXEC_SIZE, GFP_KERNEL); 183 183 execute_location(kmalloc_area, CODE_WRITE); 184 184 kfree(kmalloc_area); 185 185 } 186 186 187 - void lkdtm_EXEC_VMALLOC(void) 187 + static void lkdtm_EXEC_VMALLOC(void) 188 188 { 189 189 u32 *vmalloc_area = vmalloc(EXEC_SIZE); 190 190 execute_location(vmalloc_area, CODE_WRITE); 191 191 vfree(vmalloc_area); 192 192 } 193 193 194 - void lkdtm_EXEC_RODATA(void) 194 + static void lkdtm_EXEC_RODATA(void) 195 195 { 196 196 execute_location(dereference_function_descriptor(lkdtm_rodata_do_nothing), 197 197 CODE_AS_IS); 198 198 } 199 199 200 - void lkdtm_EXEC_USERSPACE(void) 200 + static void lkdtm_EXEC_USERSPACE(void) 201 201 { 202 202 unsigned long user_addr; 203 203 ··· 212 212 vm_munmap(user_addr, PAGE_SIZE); 213 213 } 214 214 215 - void lkdtm_EXEC_NULL(void) 215 + static void lkdtm_EXEC_NULL(void) 216 216 { 217 217 execute_location(NULL, CODE_AS_IS); 218 218 } 219 219 220 - void lkdtm_ACCESS_USERSPACE(void) 220 + static void lkdtm_ACCESS_USERSPACE(void) 221 221 { 222 222 unsigned long user_addr, tmp = 0; 223 223 unsigned long *ptr; ··· 250 250 vm_munmap(user_addr, PAGE_SIZE); 251 251 } 252 252 253 - void lkdtm_ACCESS_NULL(void) 253 + static void lkdtm_ACCESS_NULL(void) 254 254 { 255 255 unsigned long tmp; 256 256 volatile unsigned long *ptr = (unsigned long *)NULL; ··· 270 270 /* Make sure we can write to __ro_after_init values during __init */ 271 271 ro_after_init |= 0xAA; 272 272 } 273 + 274 + static struct crashtype crashtypes[] = { 275 + CRASHTYPE(WRITE_RO), 276 + CRASHTYPE(WRITE_RO_AFTER_INIT), 277 + CRASHTYPE(WRITE_KERN), 278 + CRASHTYPE(WRITE_OPD), 279 + CRASHTYPE(EXEC_DATA), 280 + CRASHTYPE(EXEC_STACK), 281 + CRASHTYPE(EXEC_KMALLOC), 282 + CRASHTYPE(EXEC_VMALLOC), 283 + CRASHTYPE(EXEC_RODATA), 284 + CRASHTYPE(EXEC_USERSPACE), 285 + CRASHTYPE(EXEC_NULL), 286 + CRASHTYPE(ACCESS_USERSPACE), 287 + CRASHTYPE(ACCESS_NULL), 288 + }; 289 + 290 + struct crashtype_category perms_crashtypes = { 291 + .crashtypes = crashtypes, 292 + .len = ARRAY_SIZE(crashtypes), 293 + };
+10 -1
drivers/misc/lkdtm/powerpc.c
··· 100 100 preempt_enable(); 101 101 } 102 102 103 - void lkdtm_PPC_SLB_MULTIHIT(void) 103 + static void lkdtm_PPC_SLB_MULTIHIT(void) 104 104 { 105 105 if (!radix_enabled()) { 106 106 pr_info("Injecting SLB multihit errors\n"); ··· 118 118 pr_err("XFAIL: This test is for ppc64 and with hash mode MMU only\n"); 119 119 } 120 120 } 121 + 122 + static struct crashtype crashtypes[] = { 123 + CRASHTYPE(PPC_SLB_MULTIHIT), 124 + }; 125 + 126 + struct crashtype_category powerpc_crashtypes = { 127 + .crashtypes = crashtypes, 128 + .len = ARRAY_SIZE(crashtypes), 129 + };
+46 -19
drivers/misc/lkdtm/refcount.c
··· 24 24 * A refcount_inc() above the maximum value of the refcount implementation, 25 25 * should at least saturate, and at most also WARN. 26 26 */ 27 - void lkdtm_REFCOUNT_INC_OVERFLOW(void) 27 + static void lkdtm_REFCOUNT_INC_OVERFLOW(void) 28 28 { 29 29 refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX - 1); 30 30 ··· 40 40 } 41 41 42 42 /* refcount_add() should behave just like refcount_inc() above. */ 43 - void lkdtm_REFCOUNT_ADD_OVERFLOW(void) 43 + static void lkdtm_REFCOUNT_ADD_OVERFLOW(void) 44 44 { 45 45 refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX - 1); 46 46 ··· 58 58 } 59 59 60 60 /* refcount_inc_not_zero() should behave just like refcount_inc() above. */ 61 - void lkdtm_REFCOUNT_INC_NOT_ZERO_OVERFLOW(void) 61 + static void lkdtm_REFCOUNT_INC_NOT_ZERO_OVERFLOW(void) 62 62 { 63 63 refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX); 64 64 ··· 70 70 } 71 71 72 72 /* refcount_add_not_zero() should behave just like refcount_inc() above. */ 73 - void lkdtm_REFCOUNT_ADD_NOT_ZERO_OVERFLOW(void) 73 + static void lkdtm_REFCOUNT_ADD_NOT_ZERO_OVERFLOW(void) 74 74 { 75 75 refcount_t over = REFCOUNT_INIT(REFCOUNT_MAX); 76 76 ··· 103 103 * zero it should either saturate (when inc-from-zero isn't protected) 104 104 * or stay at zero (when inc-from-zero is protected) and should WARN for both. 105 105 */ 106 - void lkdtm_REFCOUNT_DEC_ZERO(void) 106 + static void lkdtm_REFCOUNT_DEC_ZERO(void) 107 107 { 108 108 refcount_t zero = REFCOUNT_INIT(2); 109 109 ··· 142 142 } 143 143 144 144 /* A refcount_dec() going negative should saturate and may WARN. */ 145 - void lkdtm_REFCOUNT_DEC_NEGATIVE(void) 145 + static void lkdtm_REFCOUNT_DEC_NEGATIVE(void) 146 146 { 147 147 refcount_t neg = REFCOUNT_INIT(0); 148 148 ··· 156 156 * A refcount_dec_and_test() should act like refcount_dec() above when 157 157 * going negative. 158 158 */ 159 - void lkdtm_REFCOUNT_DEC_AND_TEST_NEGATIVE(void) 159 + static void lkdtm_REFCOUNT_DEC_AND_TEST_NEGATIVE(void) 160 160 { 161 161 refcount_t neg = REFCOUNT_INIT(0); 162 162 ··· 171 171 * A refcount_sub_and_test() should act like refcount_dec_and_test() 172 172 * above when going negative. 173 173 */ 174 - void lkdtm_REFCOUNT_SUB_AND_TEST_NEGATIVE(void) 174 + static void lkdtm_REFCOUNT_SUB_AND_TEST_NEGATIVE(void) 175 175 { 176 176 refcount_t neg = REFCOUNT_INIT(3); 177 177 ··· 203 203 /* 204 204 * A refcount_inc() from zero should pin to zero or saturate and may WARN. 205 205 */ 206 - void lkdtm_REFCOUNT_INC_ZERO(void) 206 + static void lkdtm_REFCOUNT_INC_ZERO(void) 207 207 { 208 208 refcount_t zero = REFCOUNT_INIT(0); 209 209 ··· 228 228 * A refcount_add() should act like refcount_inc() above when starting 229 229 * at zero. 230 230 */ 231 - void lkdtm_REFCOUNT_ADD_ZERO(void) 231 + static void lkdtm_REFCOUNT_ADD_ZERO(void) 232 232 { 233 233 refcount_t zero = REFCOUNT_INIT(0); 234 234 ··· 267 267 * A refcount_inc() from a saturated value should at most warn about 268 268 * being saturated already. 269 269 */ 270 - void lkdtm_REFCOUNT_INC_SATURATED(void) 270 + static void lkdtm_REFCOUNT_INC_SATURATED(void) 271 271 { 272 272 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 273 273 ··· 278 278 } 279 279 280 280 /* Should act like refcount_inc() above from saturated. */ 281 - void lkdtm_REFCOUNT_DEC_SATURATED(void) 281 + static void lkdtm_REFCOUNT_DEC_SATURATED(void) 282 282 { 283 283 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 284 284 ··· 289 289 } 290 290 291 291 /* Should act like refcount_inc() above from saturated. */ 292 - void lkdtm_REFCOUNT_ADD_SATURATED(void) 292 + static void lkdtm_REFCOUNT_ADD_SATURATED(void) 293 293 { 294 294 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 295 295 ··· 300 300 } 301 301 302 302 /* Should act like refcount_inc() above from saturated. */ 303 - void lkdtm_REFCOUNT_INC_NOT_ZERO_SATURATED(void) 303 + static void lkdtm_REFCOUNT_INC_NOT_ZERO_SATURATED(void) 304 304 { 305 305 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 306 306 ··· 312 312 } 313 313 314 314 /* Should act like refcount_inc() above from saturated. */ 315 - void lkdtm_REFCOUNT_ADD_NOT_ZERO_SATURATED(void) 315 + static void lkdtm_REFCOUNT_ADD_NOT_ZERO_SATURATED(void) 316 316 { 317 317 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 318 318 ··· 324 324 } 325 325 326 326 /* Should act like refcount_inc() above from saturated. */ 327 - void lkdtm_REFCOUNT_DEC_AND_TEST_SATURATED(void) 327 + static void lkdtm_REFCOUNT_DEC_AND_TEST_SATURATED(void) 328 328 { 329 329 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 330 330 ··· 336 336 } 337 337 338 338 /* Should act like refcount_inc() above from saturated. */ 339 - void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void) 339 + static void lkdtm_REFCOUNT_SUB_AND_TEST_SATURATED(void) 340 340 { 341 341 refcount_t sat = REFCOUNT_INIT(REFCOUNT_SATURATED); 342 342 ··· 348 348 } 349 349 350 350 /* Used to time the existing atomic_t when used for reference counting */ 351 - void lkdtm_ATOMIC_TIMING(void) 351 + static void lkdtm_ATOMIC_TIMING(void) 352 352 { 353 353 unsigned int i; 354 354 atomic_t count = ATOMIC_INIT(1); ··· 373 373 * cd /sys/kernel/debug/provoke-crash 374 374 * perf stat -B -- cat <(echo REFCOUNT_TIMING) > DIRECT 375 375 */ 376 - void lkdtm_REFCOUNT_TIMING(void) 376 + static void lkdtm_REFCOUNT_TIMING(void) 377 377 { 378 378 unsigned int i; 379 379 refcount_t count = REFCOUNT_INIT(1); ··· 390 390 else 391 391 pr_info("refcount timing: done\n"); 392 392 } 393 + 394 + static struct crashtype crashtypes[] = { 395 + CRASHTYPE(REFCOUNT_INC_OVERFLOW), 396 + CRASHTYPE(REFCOUNT_ADD_OVERFLOW), 397 + CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW), 398 + CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_OVERFLOW), 399 + CRASHTYPE(REFCOUNT_DEC_ZERO), 400 + CRASHTYPE(REFCOUNT_DEC_NEGATIVE), 401 + CRASHTYPE(REFCOUNT_DEC_AND_TEST_NEGATIVE), 402 + CRASHTYPE(REFCOUNT_SUB_AND_TEST_NEGATIVE), 403 + CRASHTYPE(REFCOUNT_INC_ZERO), 404 + CRASHTYPE(REFCOUNT_ADD_ZERO), 405 + CRASHTYPE(REFCOUNT_INC_SATURATED), 406 + CRASHTYPE(REFCOUNT_DEC_SATURATED), 407 + CRASHTYPE(REFCOUNT_ADD_SATURATED), 408 + CRASHTYPE(REFCOUNT_INC_NOT_ZERO_SATURATED), 409 + CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_SATURATED), 410 + CRASHTYPE(REFCOUNT_DEC_AND_TEST_SATURATED), 411 + CRASHTYPE(REFCOUNT_SUB_AND_TEST_SATURATED), 412 + CRASHTYPE(ATOMIC_TIMING), 413 + CRASHTYPE(REFCOUNT_TIMING), 414 + }; 415 + 416 + struct crashtype_category refcount_crashtypes = { 417 + .crashtypes = crashtypes, 418 + .len = ARRAY_SIZE(crashtypes), 419 + };
+10 -1
drivers/misc/lkdtm/stackleak.c
··· 11 11 #include "lkdtm.h" 12 12 #include <linux/stackleak.h> 13 13 14 - void lkdtm_STACKLEAK_ERASING(void) 14 + static void lkdtm_STACKLEAK_ERASING(void) 15 15 { 16 16 unsigned long *sp, left, found, i; 17 17 const unsigned long check_depth = ··· 80 80 pr_info("OK: the rest of the thread stack is properly erased\n"); 81 81 } 82 82 } 83 + 84 + static struct crashtype crashtypes[] = { 85 + CRASHTYPE(STACKLEAK_ERASING), 86 + }; 87 + 88 + struct crashtype_category stackleak_crashtypes = { 89 + .crashtypes = crashtypes, 90 + .len = ARRAY_SIZE(crashtypes), 91 + };
+24 -8
drivers/misc/lkdtm/usercopy.c
··· 272 272 } 273 273 274 274 /* Callable tests. */ 275 - void lkdtm_USERCOPY_HEAP_SIZE_TO(void) 275 + static void lkdtm_USERCOPY_HEAP_SIZE_TO(void) 276 276 { 277 277 do_usercopy_heap_size(true); 278 278 } 279 279 280 - void lkdtm_USERCOPY_HEAP_SIZE_FROM(void) 280 + static void lkdtm_USERCOPY_HEAP_SIZE_FROM(void) 281 281 { 282 282 do_usercopy_heap_size(false); 283 283 } 284 284 285 - void lkdtm_USERCOPY_HEAP_WHITELIST_TO(void) 285 + static void lkdtm_USERCOPY_HEAP_WHITELIST_TO(void) 286 286 { 287 287 do_usercopy_heap_whitelist(true); 288 288 } 289 289 290 - void lkdtm_USERCOPY_HEAP_WHITELIST_FROM(void) 290 + static void lkdtm_USERCOPY_HEAP_WHITELIST_FROM(void) 291 291 { 292 292 do_usercopy_heap_whitelist(false); 293 293 } 294 294 295 - void lkdtm_USERCOPY_STACK_FRAME_TO(void) 295 + static void lkdtm_USERCOPY_STACK_FRAME_TO(void) 296 296 { 297 297 do_usercopy_stack(true, true); 298 298 } 299 299 300 - void lkdtm_USERCOPY_STACK_FRAME_FROM(void) 300 + static void lkdtm_USERCOPY_STACK_FRAME_FROM(void) 301 301 { 302 302 do_usercopy_stack(false, true); 303 303 } 304 304 305 - void lkdtm_USERCOPY_STACK_BEYOND(void) 305 + static void lkdtm_USERCOPY_STACK_BEYOND(void) 306 306 { 307 307 do_usercopy_stack(true, false); 308 308 } 309 309 310 - void lkdtm_USERCOPY_KERNEL(void) 310 + static void lkdtm_USERCOPY_KERNEL(void) 311 311 { 312 312 unsigned long user_addr; 313 313 ··· 356 356 { 357 357 kmem_cache_destroy(whitelist_cache); 358 358 } 359 + 360 + static struct crashtype crashtypes[] = { 361 + CRASHTYPE(USERCOPY_HEAP_SIZE_TO), 362 + CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), 363 + CRASHTYPE(USERCOPY_HEAP_WHITELIST_TO), 364 + CRASHTYPE(USERCOPY_HEAP_WHITELIST_FROM), 365 + CRASHTYPE(USERCOPY_STACK_FRAME_TO), 366 + CRASHTYPE(USERCOPY_STACK_FRAME_FROM), 367 + CRASHTYPE(USERCOPY_STACK_BEYOND), 368 + CRASHTYPE(USERCOPY_KERNEL), 369 + }; 370 + 371 + struct crashtype_category usercopy_crashtypes = { 372 + .crashtypes = crashtypes, 373 + .len = ARRAY_SIZE(crashtypes), 374 + };