1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Linux Kernel Dump Test Module for testing kernel crashes conditions: 4 * induces system failures at predefined crashpoints and under predefined 5 * operational conditions in order to evaluate the reliability of kernel 6 * sanity checking and crash dumps obtained using different dumping 7 * solutions. 8 * 9 * Copyright (C) IBM Corporation, 2006 10 * 11 * Author: Ankita Garg <ankita@in.ibm.com> 12 * 13 * It is adapted from the Linux Kernel Dump Test Tool by 14 * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net> 15 * 16 * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net> 17 * 18 * See Documentation/fault-injection/provoke-crashes.rst for instructions 19 */ 20 #include "lkdtm.h" 21 #include <linux/fs.h> 22 #include <linux/module.h> 23 #include <linux/buffer_head.h> 24 #include <linux/kprobes.h> 25 #include <linux/list.h> 26 #include <linux/init.h> 27 #include <linux/slab.h> 28 #include <linux/debugfs.h> 29 #include <linux/utsname.h> 30 31 #define DEFAULT_COUNT 10 32 33 static int lkdtm_debugfs_open(struct inode *inode, struct file *file); 34 static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf, 35 size_t count, loff_t *off); 36 static ssize_t direct_entry(struct file *f, const char __user *user_buf, 37 size_t count, loff_t *off); 38 39 #ifdef CONFIG_KPROBES 40 static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs); 41 static ssize_t lkdtm_debugfs_entry(struct file *f, 42 const char __user *user_buf, 43 size_t count, loff_t *off); 44 # define CRASHPOINT_KPROBE(_symbol) \ 45 .kprobe = { \ 46 .symbol_name = (_symbol), \ 47 .pre_handler = lkdtm_kprobe_handler, \ 48 }, 49 # define CRASHPOINT_WRITE(_symbol) \ 50 (_symbol) ? lkdtm_debugfs_entry : direct_entry 51 #else 52 # define CRASHPOINT_KPROBE(_symbol) 53 # define CRASHPOINT_WRITE(_symbol) direct_entry 54 #endif 55 56 /* Crash points */ 57 struct crashpoint { 58 const char *name; 59 const struct file_operations fops; 60 struct kprobe kprobe; 61 }; 62 63 #define CRASHPOINT(_name, _symbol) \ 64 { \ 65 .name = _name, \ 66 .fops = { \ 67 .read = lkdtm_debugfs_read, \ 68 .llseek = generic_file_llseek, \ 69 .open = lkdtm_debugfs_open, \ 70 .write = CRASHPOINT_WRITE(_symbol) \ 71 }, \ 72 CRASHPOINT_KPROBE(_symbol) \ 73 } 74 75 /* Define the possible places where we can trigger a crash point. */ 76 static struct crashpoint crashpoints[] = { 77 CRASHPOINT("DIRECT", NULL), 78 #ifdef CONFIG_KPROBES 79 CRASHPOINT("INT_HARDWARE_ENTRY", "do_IRQ"), 80 CRASHPOINT("INT_HW_IRQ_EN", "handle_irq_event"), 81 CRASHPOINT("INT_TASKLET_ENTRY", "tasklet_action"), 82 CRASHPOINT("FS_SUBMIT_BH", "submit_bh"), 83 CRASHPOINT("MEM_SWAPOUT", "shrink_inactive_list"), 84 CRASHPOINT("TIMERADD", "hrtimer_start"), 85 CRASHPOINT("SCSI_QUEUE_RQ", "scsi_queue_rq"), 86 #endif 87 }; 88 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, 99 #ifdef CONFIG_PPC_64S_HASH_MMU 100 &powerpc_crashtypes, 101 #endif 102 }; 103 104 /* Global kprobe entry and crashtype. */ 105 static struct kprobe *lkdtm_kprobe; 106 static struct crashpoint *lkdtm_crashpoint; 107 static const struct crashtype *lkdtm_crashtype; 108 109 /* Module parameters */ 110 static int recur_count = -1; 111 module_param(recur_count, int, 0644); 112 MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test"); 113 114 static char* cpoint_name; 115 module_param(cpoint_name, charp, 0444); 116 MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); 117 118 static char* cpoint_type; 119 module_param(cpoint_type, charp, 0444); 120 MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ 121 "hitting the crash point"); 122 123 static int cpoint_count = DEFAULT_COUNT; 124 module_param(cpoint_count, int, 0644); 125 MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ 126 "crash point is to be hit to trigger action"); 127 128 /* 129 * For test debug reporting when CI systems provide terse summaries. 130 * TODO: Remove this once reasonable reporting exists in most CI systems: 131 * https://lore.kernel.org/lkml/CAHk-=wiFvfkoFixTapvvyPMN9pq5G-+Dys2eSyBa1vzDGAO5+A@mail.gmail.com 132 */ 133 char *lkdtm_kernel_info; 134 135 /* Return the crashtype number or NULL if the name is invalid */ 136 static const struct crashtype *find_crashtype(const char *name) 137 { 138 int cat, idx; 139 140 for (cat = 0; cat < ARRAY_SIZE(crashtype_categories); cat++) { 141 for (idx = 0; idx < crashtype_categories[cat]->len; idx++) { 142 struct crashtype *crashtype; 143 144 crashtype = &crashtype_categories[cat]->crashtypes[idx]; 145 if (!strcmp(name, crashtype->name)) 146 return crashtype; 147 } 148 } 149 150 return NULL; 151 } 152 153 /* 154 * This is forced noinline just so it distinctly shows up in the stackdump 155 * which makes validation of expected lkdtm crashes easier. 156 * 157 * NOTE: having a valid return value helps prevent the compiler from doing 158 * tail call optimizations and taking this out of the stack trace. 159 */ 160 static noinline int lkdtm_do_action(const struct crashtype *crashtype) 161 { 162 if (WARN_ON(!crashtype || !crashtype->func)) 163 return -EINVAL; 164 crashtype->func(); 165 166 return 0; 167 } 168 169 static int lkdtm_register_cpoint(struct crashpoint *crashpoint, 170 const struct crashtype *crashtype) 171 { 172 int ret; 173 174 /* If this doesn't have a symbol, just call immediately. */ 175 if (!crashpoint->kprobe.symbol_name) 176 return lkdtm_do_action(crashtype); 177 178 if (lkdtm_kprobe != NULL) 179 unregister_kprobe(lkdtm_kprobe); 180 181 lkdtm_crashpoint = crashpoint; 182 lkdtm_crashtype = crashtype; 183 lkdtm_kprobe = &crashpoint->kprobe; 184 ret = register_kprobe(lkdtm_kprobe); 185 if (ret < 0) { 186 pr_info("Couldn't register kprobe %s\n", 187 crashpoint->kprobe.symbol_name); 188 lkdtm_kprobe = NULL; 189 lkdtm_crashpoint = NULL; 190 lkdtm_crashtype = NULL; 191 } 192 193 return ret; 194 } 195 196 #ifdef CONFIG_KPROBES 197 /* Global crash counter and spinlock. */ 198 static int crash_count = DEFAULT_COUNT; 199 static DEFINE_SPINLOCK(crash_count_lock); 200 201 /* Called by kprobe entry points. */ 202 static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs) 203 { 204 unsigned long flags; 205 bool do_it = false; 206 207 if (WARN_ON(!lkdtm_crashpoint || !lkdtm_crashtype)) 208 return 0; 209 210 spin_lock_irqsave(&crash_count_lock, flags); 211 crash_count--; 212 pr_info("Crash point %s of type %s hit, trigger in %d rounds\n", 213 lkdtm_crashpoint->name, lkdtm_crashtype->name, crash_count); 214 215 if (crash_count == 0) { 216 do_it = true; 217 crash_count = cpoint_count; 218 } 219 spin_unlock_irqrestore(&crash_count_lock, flags); 220 221 if (do_it) 222 return lkdtm_do_action(lkdtm_crashtype); 223 224 return 0; 225 } 226 227 static ssize_t lkdtm_debugfs_entry(struct file *f, 228 const char __user *user_buf, 229 size_t count, loff_t *off) 230 { 231 struct crashpoint *crashpoint = file_inode(f)->i_private; 232 const struct crashtype *crashtype = NULL; 233 char *buf; 234 int err; 235 236 if (count >= PAGE_SIZE) 237 return -EINVAL; 238 239 buf = (char *)__get_free_page(GFP_KERNEL); 240 if (!buf) 241 return -ENOMEM; 242 if (copy_from_user(buf, user_buf, count)) { 243 free_page((unsigned long) buf); 244 return -EFAULT; 245 } 246 /* NULL-terminate and remove enter */ 247 buf[count] = '\0'; 248 strim(buf); 249 250 crashtype = find_crashtype(buf); 251 free_page((unsigned long)buf); 252 253 if (!crashtype) 254 return -EINVAL; 255 256 err = lkdtm_register_cpoint(crashpoint, crashtype); 257 if (err < 0) 258 return err; 259 260 *off += count; 261 262 return count; 263 } 264 #endif 265 266 /* Generic read callback that just prints out the available crash types */ 267 static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf, 268 size_t count, loff_t *off) 269 { 270 int n, cat, idx; 271 ssize_t out; 272 char *buf; 273 274 buf = (char *)__get_free_page(GFP_KERNEL); 275 if (buf == NULL) 276 return -ENOMEM; 277 278 n = scnprintf(buf, PAGE_SIZE, "Available crash types:\n"); 279 280 for (cat = 0; cat < ARRAY_SIZE(crashtype_categories); cat++) { 281 for (idx = 0; idx < crashtype_categories[cat]->len; idx++) { 282 struct crashtype *crashtype; 283 284 crashtype = &crashtype_categories[cat]->crashtypes[idx]; 285 n += scnprintf(buf + n, PAGE_SIZE - n, "%s\n", 286 crashtype->name); 287 } 288 } 289 buf[n] = '\0'; 290 291 out = simple_read_from_buffer(user_buf, count, off, 292 buf, n); 293 free_page((unsigned long) buf); 294 295 return out; 296 } 297 298 static int lkdtm_debugfs_open(struct inode *inode, struct file *file) 299 { 300 return 0; 301 } 302 303 /* Special entry to just crash directly. Available without KPROBEs */ 304 static ssize_t direct_entry(struct file *f, const char __user *user_buf, 305 size_t count, loff_t *off) 306 { 307 const struct crashtype *crashtype; 308 char *buf; 309 int err; 310 311 if (count >= PAGE_SIZE) 312 return -EINVAL; 313 if (count < 1) 314 return -EINVAL; 315 316 buf = (char *)__get_free_page(GFP_KERNEL); 317 if (!buf) 318 return -ENOMEM; 319 if (copy_from_user(buf, user_buf, count)) { 320 free_page((unsigned long) buf); 321 return -EFAULT; 322 } 323 /* NULL-terminate and remove enter */ 324 buf[count] = '\0'; 325 strim(buf); 326 327 crashtype = find_crashtype(buf); 328 free_page((unsigned long) buf); 329 if (!crashtype) 330 return -EINVAL; 331 332 pr_info("Performing direct entry %s\n", crashtype->name); 333 err = lkdtm_do_action(crashtype); 334 *off += count; 335 336 if (err) 337 return err; 338 return count; 339 } 340 341 #ifndef MODULE 342 /* 343 * To avoid needing to export parse_args(), just don't use this code 344 * when LKDTM is built as a module. 345 */ 346 struct check_cmdline_args { 347 const char *param; 348 int value; 349 }; 350 351 static int lkdtm_parse_one(char *param, char *val, 352 const char *unused, void *arg) 353 { 354 struct check_cmdline_args *args = arg; 355 356 /* short circuit if we already found a value. */ 357 if (args->value != -ESRCH) 358 return 0; 359 if (strncmp(param, args->param, strlen(args->param)) == 0) { 360 bool bool_result; 361 int ret; 362 363 ret = kstrtobool(val, &bool_result); 364 if (ret == 0) 365 args->value = bool_result; 366 } 367 return 0; 368 } 369 370 int lkdtm_check_bool_cmdline(const char *param) 371 { 372 char *command_line; 373 struct check_cmdline_args args = { 374 .param = param, 375 .value = -ESRCH, 376 }; 377 378 command_line = kstrdup(saved_command_line, GFP_KERNEL); 379 if (!command_line) 380 return -ENOMEM; 381 382 parse_args("Setting sysctl args", command_line, 383 NULL, 0, -1, -1, &args, lkdtm_parse_one); 384 385 kfree(command_line); 386 387 return args.value; 388 } 389 #endif 390 391 static struct dentry *lkdtm_debugfs_root; 392 393 static int __init lkdtm_module_init(void) 394 { 395 struct crashpoint *crashpoint = NULL; 396 const struct crashtype *crashtype = NULL; 397 int ret; 398 int i; 399 400 /* Neither or both of these need to be set */ 401 if ((cpoint_type || cpoint_name) && !(cpoint_type && cpoint_name)) { 402 pr_err("Need both cpoint_type and cpoint_name or neither\n"); 403 return -EINVAL; 404 } 405 406 if (cpoint_type) { 407 crashtype = find_crashtype(cpoint_type); 408 if (!crashtype) { 409 pr_err("Unknown crashtype '%s'\n", cpoint_type); 410 return -EINVAL; 411 } 412 } 413 414 if (cpoint_name) { 415 for (i = 0; i < ARRAY_SIZE(crashpoints); i++) { 416 if (!strcmp(cpoint_name, crashpoints[i].name)) 417 crashpoint = &crashpoints[i]; 418 } 419 420 /* Refuse unknown crashpoints. */ 421 if (!crashpoint) { 422 pr_err("Invalid crashpoint %s\n", cpoint_name); 423 return -EINVAL; 424 } 425 } 426 427 #ifdef CONFIG_KPROBES 428 /* Set crash count. */ 429 crash_count = cpoint_count; 430 #endif 431 432 /* Common initialization. */ 433 lkdtm_kernel_info = kasprintf(GFP_KERNEL, "kernel (%s %s)", 434 init_uts_ns.name.release, 435 init_uts_ns.name.machine); 436 437 /* Handle test-specific initialization. */ 438 lkdtm_bugs_init(&recur_count); 439 lkdtm_perms_init(); 440 lkdtm_usercopy_init(); 441 lkdtm_heap_init(); 442 443 /* Register debugfs interface */ 444 lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL); 445 446 /* Install debugfs trigger files. */ 447 for (i = 0; i < ARRAY_SIZE(crashpoints); i++) { 448 struct crashpoint *cur = &crashpoints[i]; 449 450 debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, cur, 451 &cur->fops); 452 } 453 454 /* Install crashpoint if one was selected. */ 455 if (crashpoint) { 456 ret = lkdtm_register_cpoint(crashpoint, crashtype); 457 if (ret < 0) { 458 pr_info("Invalid crashpoint %s\n", crashpoint->name); 459 goto out_err; 460 } 461 pr_info("Crash point %s of type %s registered\n", 462 crashpoint->name, cpoint_type); 463 } else { 464 pr_info("No crash points registered, enable through debugfs\n"); 465 } 466 467 return 0; 468 469 out_err: 470 debugfs_remove_recursive(lkdtm_debugfs_root); 471 return ret; 472 } 473 474 static void __exit lkdtm_module_exit(void) 475 { 476 debugfs_remove_recursive(lkdtm_debugfs_root); 477 478 /* Handle test-specific clean-up. */ 479 lkdtm_heap_exit(); 480 lkdtm_usercopy_exit(); 481 482 if (lkdtm_kprobe != NULL) 483 unregister_kprobe(lkdtm_kprobe); 484 485 kfree(lkdtm_kernel_info); 486 487 pr_info("Crash point unregistered\n"); 488 } 489 490 module_init(lkdtm_module_init); 491 module_exit(lkdtm_module_exit); 492 493 MODULE_LICENSE("GPL"); 494 MODULE_DESCRIPTION("Kernel crash testing module"); 495