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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.9-rc6 544 lines 14 kB view raw
1/* 2 * Linux Kernel Dump Test Module for testing kernel crashes conditions: 3 * induces system failures at predefined crashpoints and under predefined 4 * operational conditions in order to evaluate the reliability of kernel 5 * sanity checking and crash dumps obtained using different dumping 6 * solutions. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 * 22 * Copyright (C) IBM Corporation, 2006 23 * 24 * Author: Ankita Garg <ankita@in.ibm.com> 25 * 26 * It is adapted from the Linux Kernel Dump Test Tool by 27 * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net> 28 * 29 * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net> 30 * 31 * See Documentation/fault-injection/provoke-crashes.txt for instructions 32 */ 33#include "lkdtm.h" 34#include <linux/fs.h> 35#include <linux/module.h> 36#include <linux/buffer_head.h> 37#include <linux/kprobes.h> 38#include <linux/list.h> 39#include <linux/init.h> 40#include <linux/interrupt.h> 41#include <linux/hrtimer.h> 42#include <linux/slab.h> 43#include <scsi/scsi_cmnd.h> 44#include <linux/debugfs.h> 45 46#ifdef CONFIG_IDE 47#include <linux/ide.h> 48#endif 49 50#define DEFAULT_COUNT 10 51 52static int lkdtm_debugfs_open(struct inode *inode, struct file *file); 53static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf, 54 size_t count, loff_t *off); 55static ssize_t direct_entry(struct file *f, const char __user *user_buf, 56 size_t count, loff_t *off); 57 58#ifdef CONFIG_KPROBES 59static void lkdtm_handler(void); 60static ssize_t lkdtm_debugfs_entry(struct file *f, 61 const char __user *user_buf, 62 size_t count, loff_t *off); 63 64 65/* jprobe entry point handlers. */ 66static unsigned int jp_do_irq(unsigned int irq) 67{ 68 lkdtm_handler(); 69 jprobe_return(); 70 return 0; 71} 72 73static irqreturn_t jp_handle_irq_event(unsigned int irq, 74 struct irqaction *action) 75{ 76 lkdtm_handler(); 77 jprobe_return(); 78 return 0; 79} 80 81static void jp_tasklet_action(struct softirq_action *a) 82{ 83 lkdtm_handler(); 84 jprobe_return(); 85} 86 87static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) 88{ 89 lkdtm_handler(); 90 jprobe_return(); 91} 92 93struct scan_control; 94 95static unsigned long jp_shrink_inactive_list(unsigned long max_scan, 96 struct zone *zone, 97 struct scan_control *sc) 98{ 99 lkdtm_handler(); 100 jprobe_return(); 101 return 0; 102} 103 104static int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim, 105 const enum hrtimer_mode mode) 106{ 107 lkdtm_handler(); 108 jprobe_return(); 109 return 0; 110} 111 112static int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd) 113{ 114 lkdtm_handler(); 115 jprobe_return(); 116 return 0; 117} 118 119# ifdef CONFIG_IDE 120static int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file, 121 struct block_device *bdev, unsigned int cmd, 122 unsigned long arg) 123{ 124 lkdtm_handler(); 125 jprobe_return(); 126 return 0; 127} 128# endif 129#endif 130 131/* Crash points */ 132struct crashpoint { 133 const char *name; 134 const struct file_operations fops; 135 struct jprobe jprobe; 136}; 137 138#define CRASHPOINT(_name, _write, _symbol, _entry) \ 139 { \ 140 .name = _name, \ 141 .fops = { \ 142 .read = lkdtm_debugfs_read, \ 143 .llseek = generic_file_llseek, \ 144 .open = lkdtm_debugfs_open, \ 145 .write = _write, \ 146 }, \ 147 .jprobe = { \ 148 .kp.symbol_name = _symbol, \ 149 .entry = (kprobe_opcode_t *)_entry, \ 150 }, \ 151 } 152 153/* Define the possible places where we can trigger a crash point. */ 154struct crashpoint crashpoints[] = { 155 CRASHPOINT("DIRECT", direct_entry, 156 NULL, NULL), 157#ifdef CONFIG_KPROBES 158 CRASHPOINT("INT_HARDWARE_ENTRY", lkdtm_debugfs_entry, 159 "do_IRQ", jp_do_irq), 160 CRASHPOINT("INT_HW_IRQ_EN", lkdtm_debugfs_entry, 161 "handle_IRQ_event", jp_handle_irq_event), 162 CRASHPOINT("INT_TASKLET_ENTRY", lkdtm_debugfs_entry, 163 "tasklet_action", jp_tasklet_action), 164 CRASHPOINT("FS_DEVRW", lkdtm_debugfs_entry, 165 "ll_rw_block", jp_ll_rw_block), 166 CRASHPOINT("MEM_SWAPOUT", lkdtm_debugfs_entry, 167 "shrink_inactive_list", jp_shrink_inactive_list), 168 CRASHPOINT("TIMERADD", lkdtm_debugfs_entry, 169 "hrtimer_start", jp_hrtimer_start), 170 CRASHPOINT("SCSI_DISPATCH_CMD", lkdtm_debugfs_entry, 171 "scsi_dispatch_cmd", jp_scsi_dispatch_cmd), 172# ifdef CONFIG_IDE 173 CRASHPOINT("IDE_CORE_CP", lkdtm_debugfs_entry, 174 "generic_ide_ioctl", jp_generic_ide_ioctl), 175# endif 176#endif 177}; 178 179 180/* Crash types. */ 181struct crashtype { 182 const char *name; 183 void (*func)(void); 184}; 185 186#define CRASHTYPE(_name) \ 187 { \ 188 .name = __stringify(_name), \ 189 .func = lkdtm_ ## _name, \ 190 } 191 192/* Define the possible types of crashes that can be triggered. */ 193struct crashtype crashtypes[] = { 194 CRASHTYPE(PANIC), 195 CRASHTYPE(BUG), 196 CRASHTYPE(WARNING), 197 CRASHTYPE(EXCEPTION), 198 CRASHTYPE(LOOP), 199 CRASHTYPE(OVERFLOW), 200 CRASHTYPE(CORRUPT_STACK), 201 CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), 202 CRASHTYPE(OVERWRITE_ALLOCATION), 203 CRASHTYPE(WRITE_AFTER_FREE), 204 CRASHTYPE(READ_AFTER_FREE), 205 CRASHTYPE(WRITE_BUDDY_AFTER_FREE), 206 CRASHTYPE(READ_BUDDY_AFTER_FREE), 207 CRASHTYPE(SOFTLOCKUP), 208 CRASHTYPE(HARDLOCKUP), 209 CRASHTYPE(SPINLOCKUP), 210 CRASHTYPE(HUNG_TASK), 211 CRASHTYPE(EXEC_DATA), 212 CRASHTYPE(EXEC_STACK), 213 CRASHTYPE(EXEC_KMALLOC), 214 CRASHTYPE(EXEC_VMALLOC), 215 CRASHTYPE(EXEC_RODATA), 216 CRASHTYPE(EXEC_USERSPACE), 217 CRASHTYPE(ACCESS_USERSPACE), 218 CRASHTYPE(WRITE_RO), 219 CRASHTYPE(WRITE_RO_AFTER_INIT), 220 CRASHTYPE(WRITE_KERN), 221 CRASHTYPE(ATOMIC_UNDERFLOW), 222 CRASHTYPE(ATOMIC_OVERFLOW), 223 CRASHTYPE(USERCOPY_HEAP_SIZE_TO), 224 CRASHTYPE(USERCOPY_HEAP_SIZE_FROM), 225 CRASHTYPE(USERCOPY_HEAP_FLAG_TO), 226 CRASHTYPE(USERCOPY_HEAP_FLAG_FROM), 227 CRASHTYPE(USERCOPY_STACK_FRAME_TO), 228 CRASHTYPE(USERCOPY_STACK_FRAME_FROM), 229 CRASHTYPE(USERCOPY_STACK_BEYOND), 230 CRASHTYPE(USERCOPY_KERNEL), 231}; 232 233 234/* Global jprobe entry and crashtype. */ 235static struct jprobe *lkdtm_jprobe; 236struct crashpoint *lkdtm_crashpoint; 237struct crashtype *lkdtm_crashtype; 238 239/* Module parameters */ 240static int recur_count = -1; 241module_param(recur_count, int, 0644); 242MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test"); 243 244static char* cpoint_name; 245module_param(cpoint_name, charp, 0444); 246MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed"); 247 248static char* cpoint_type; 249module_param(cpoint_type, charp, 0444); 250MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\ 251 "hitting the crash point"); 252 253static int cpoint_count = DEFAULT_COUNT; 254module_param(cpoint_count, int, 0644); 255MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ 256 "crash point is to be hit to trigger action"); 257 258 259/* Return the crashtype number or NULL if the name is invalid */ 260static struct crashtype *find_crashtype(const char *name) 261{ 262 int i; 263 264 for (i = 0; i < ARRAY_SIZE(crashtypes); i++) { 265 if (!strcmp(name, crashtypes[i].name)) 266 return &crashtypes[i]; 267 } 268 269 return NULL; 270} 271 272/* 273 * This is forced noinline just so it distinctly shows up in the stackdump 274 * which makes validation of expected lkdtm crashes easier. 275 */ 276static noinline void lkdtm_do_action(struct crashtype *crashtype) 277{ 278 BUG_ON(!crashtype || !crashtype->func); 279 crashtype->func(); 280} 281 282static int lkdtm_register_cpoint(struct crashpoint *crashpoint, 283 struct crashtype *crashtype) 284{ 285 int ret; 286 287 /* If this doesn't have a symbol, just call immediately. */ 288 if (!crashpoint->jprobe.kp.symbol_name) { 289 lkdtm_do_action(crashtype); 290 return 0; 291 } 292 293 if (lkdtm_jprobe != NULL) 294 unregister_jprobe(lkdtm_jprobe); 295 296 lkdtm_crashpoint = crashpoint; 297 lkdtm_crashtype = crashtype; 298 lkdtm_jprobe = &crashpoint->jprobe; 299 ret = register_jprobe(lkdtm_jprobe); 300 if (ret < 0) { 301 pr_info("Couldn't register jprobe %s\n", 302 crashpoint->jprobe.kp.symbol_name); 303 lkdtm_jprobe = NULL; 304 lkdtm_crashpoint = NULL; 305 lkdtm_crashtype = NULL; 306 } 307 308 return ret; 309} 310 311#ifdef CONFIG_KPROBES 312/* Global crash counter and spinlock. */ 313static int crash_count = DEFAULT_COUNT; 314static DEFINE_SPINLOCK(crash_count_lock); 315 316/* Called by jprobe entry points. */ 317static void lkdtm_handler(void) 318{ 319 unsigned long flags; 320 bool do_it = false; 321 322 BUG_ON(!lkdtm_crashpoint || !lkdtm_crashtype); 323 324 spin_lock_irqsave(&crash_count_lock, flags); 325 crash_count--; 326 pr_info("Crash point %s of type %s hit, trigger in %d rounds\n", 327 lkdtm_crashpoint->name, lkdtm_crashtype->name, crash_count); 328 329 if (crash_count == 0) { 330 do_it = true; 331 crash_count = cpoint_count; 332 } 333 spin_unlock_irqrestore(&crash_count_lock, flags); 334 335 if (do_it) 336 lkdtm_do_action(lkdtm_crashtype); 337} 338 339static ssize_t lkdtm_debugfs_entry(struct file *f, 340 const char __user *user_buf, 341 size_t count, loff_t *off) 342{ 343 struct crashpoint *crashpoint = file_inode(f)->i_private; 344 struct crashtype *crashtype = NULL; 345 char *buf; 346 int err; 347 348 if (count >= PAGE_SIZE) 349 return -EINVAL; 350 351 buf = (char *)__get_free_page(GFP_KERNEL); 352 if (!buf) 353 return -ENOMEM; 354 if (copy_from_user(buf, user_buf, count)) { 355 free_page((unsigned long) buf); 356 return -EFAULT; 357 } 358 /* NULL-terminate and remove enter */ 359 buf[count] = '\0'; 360 strim(buf); 361 362 crashtype = find_crashtype(buf); 363 free_page((unsigned long)buf); 364 365 if (!crashtype) 366 return -EINVAL; 367 368 err = lkdtm_register_cpoint(crashpoint, crashtype); 369 if (err < 0) 370 return err; 371 372 *off += count; 373 374 return count; 375} 376#endif 377 378/* Generic read callback that just prints out the available crash types */ 379static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf, 380 size_t count, loff_t *off) 381{ 382 char *buf; 383 int i, n, out; 384 385 buf = (char *)__get_free_page(GFP_KERNEL); 386 if (buf == NULL) 387 return -ENOMEM; 388 389 n = snprintf(buf, PAGE_SIZE, "Available crash types:\n"); 390 for (i = 0; i < ARRAY_SIZE(crashtypes); i++) { 391 n += snprintf(buf + n, PAGE_SIZE - n, "%s\n", 392 crashtypes[i].name); 393 } 394 buf[n] = '\0'; 395 396 out = simple_read_from_buffer(user_buf, count, off, 397 buf, n); 398 free_page((unsigned long) buf); 399 400 return out; 401} 402 403static int lkdtm_debugfs_open(struct inode *inode, struct file *file) 404{ 405 return 0; 406} 407 408/* Special entry to just crash directly. Available without KPROBEs */ 409static ssize_t direct_entry(struct file *f, const char __user *user_buf, 410 size_t count, loff_t *off) 411{ 412 struct crashtype *crashtype; 413 char *buf; 414 415 if (count >= PAGE_SIZE) 416 return -EINVAL; 417 if (count < 1) 418 return -EINVAL; 419 420 buf = (char *)__get_free_page(GFP_KERNEL); 421 if (!buf) 422 return -ENOMEM; 423 if (copy_from_user(buf, user_buf, count)) { 424 free_page((unsigned long) buf); 425 return -EFAULT; 426 } 427 /* NULL-terminate and remove enter */ 428 buf[count] = '\0'; 429 strim(buf); 430 431 crashtype = find_crashtype(buf); 432 free_page((unsigned long) buf); 433 if (!crashtype) 434 return -EINVAL; 435 436 pr_info("Performing direct entry %s\n", crashtype->name); 437 lkdtm_do_action(crashtype); 438 *off += count; 439 440 return count; 441} 442 443static struct dentry *lkdtm_debugfs_root; 444 445static int __init lkdtm_module_init(void) 446{ 447 struct crashpoint *crashpoint = NULL; 448 struct crashtype *crashtype = NULL; 449 int ret = -EINVAL; 450 int i; 451 452 /* Neither or both of these need to be set */ 453 if ((cpoint_type || cpoint_name) && !(cpoint_type && cpoint_name)) { 454 pr_err("Need both cpoint_type and cpoint_name or neither\n"); 455 return -EINVAL; 456 } 457 458 if (cpoint_type) { 459 crashtype = find_crashtype(cpoint_type); 460 if (!crashtype) { 461 pr_err("Unknown crashtype '%s'\n", cpoint_type); 462 return -EINVAL; 463 } 464 } 465 466 if (cpoint_name) { 467 for (i = 0; i < ARRAY_SIZE(crashpoints); i++) { 468 if (!strcmp(cpoint_name, crashpoints[i].name)) 469 crashpoint = &crashpoints[i]; 470 } 471 472 /* Refuse unknown crashpoints. */ 473 if (!crashpoint) { 474 pr_err("Invalid crashpoint %s\n", cpoint_name); 475 return -EINVAL; 476 } 477 } 478 479#ifdef CONFIG_KPROBES 480 /* Set crash count. */ 481 crash_count = cpoint_count; 482#endif 483 484 /* Handle test-specific initialization. */ 485 lkdtm_bugs_init(&recur_count); 486 lkdtm_perms_init(); 487 lkdtm_usercopy_init(); 488 489 /* Register debugfs interface */ 490 lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL); 491 if (!lkdtm_debugfs_root) { 492 pr_err("creating root dir failed\n"); 493 return -ENODEV; 494 } 495 496 /* Install debugfs trigger files. */ 497 for (i = 0; i < ARRAY_SIZE(crashpoints); i++) { 498 struct crashpoint *cur = &crashpoints[i]; 499 struct dentry *de; 500 501 de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, 502 cur, &cur->fops); 503 if (de == NULL) { 504 pr_err("could not create crashpoint %s\n", cur->name); 505 goto out_err; 506 } 507 } 508 509 /* Install crashpoint if one was selected. */ 510 if (crashpoint) { 511 ret = lkdtm_register_cpoint(crashpoint, crashtype); 512 if (ret < 0) { 513 pr_info("Invalid crashpoint %s\n", crashpoint->name); 514 goto out_err; 515 } 516 pr_info("Crash point %s of type %s registered\n", 517 crashpoint->name, cpoint_type); 518 } else { 519 pr_info("No crash points registered, enable through debugfs\n"); 520 } 521 522 return 0; 523 524out_err: 525 debugfs_remove_recursive(lkdtm_debugfs_root); 526 return ret; 527} 528 529static void __exit lkdtm_module_exit(void) 530{ 531 debugfs_remove_recursive(lkdtm_debugfs_root); 532 533 /* Handle test-specific clean-up. */ 534 lkdtm_usercopy_exit(); 535 536 unregister_jprobe(lkdtm_jprobe); 537 pr_info("Crash point unregistered\n"); 538} 539 540module_init(lkdtm_module_init); 541module_exit(lkdtm_module_exit); 542 543MODULE_LICENSE("GPL"); 544MODULE_DESCRIPTION("Kernel crash testing module");