aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/lkdtm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/lkdtm.c')
-rw-r--r--drivers/misc/lkdtm.c74
1 files changed, 57 insertions, 17 deletions
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c
index 49c7a23f02fc..d66a2f24f6b3 100644
--- a/drivers/misc/lkdtm.c
+++ b/drivers/misc/lkdtm.c
@@ -30,6 +30,7 @@
30 * 30 *
31 * See Documentation/fault-injection/provoke-crashes.txt for instructions 31 * See Documentation/fault-injection/provoke-crashes.txt for instructions
32 */ 32 */
33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
33 34
34#include <linux/kernel.h> 35#include <linux/kernel.h>
35#include <linux/fs.h> 36#include <linux/fs.h>
@@ -45,6 +46,7 @@
45#include <linux/debugfs.h> 46#include <linux/debugfs.h>
46#include <linux/vmalloc.h> 47#include <linux/vmalloc.h>
47#include <linux/mman.h> 48#include <linux/mman.h>
49#include <asm/cacheflush.h>
48 50
49#ifdef CONFIG_IDE 51#ifdef CONFIG_IDE
50#include <linux/ide.h> 52#include <linux/ide.h>
@@ -101,6 +103,7 @@ enum ctype {
101 CT_EXEC_USERSPACE, 103 CT_EXEC_USERSPACE,
102 CT_ACCESS_USERSPACE, 104 CT_ACCESS_USERSPACE,
103 CT_WRITE_RO, 105 CT_WRITE_RO,
106 CT_WRITE_KERN,
104}; 107};
105 108
106static char* cp_name[] = { 109static char* cp_name[] = {
@@ -137,6 +140,7 @@ static char* cp_type[] = {
137 "EXEC_USERSPACE", 140 "EXEC_USERSPACE",
138 "ACCESS_USERSPACE", 141 "ACCESS_USERSPACE",
139 "WRITE_RO", 142 "WRITE_RO",
143 "WRITE_KERN",
140}; 144};
141 145
142static struct jprobe lkdtm; 146static struct jprobe lkdtm;
@@ -316,6 +320,13 @@ static void do_nothing(void)
316 return; 320 return;
317} 321}
318 322
323/* Must immediately follow do_nothing for size calculuations to work out. */
324static void do_overwritten(void)
325{
326 pr_info("do_overwritten wasn't overwritten!\n");
327 return;
328}
329
319static noinline void corrupt_stack(void) 330static noinline void corrupt_stack(void)
320{ 331{
321 /* Use default char array length that triggers stack protection. */ 332 /* Use default char array length that triggers stack protection. */
@@ -328,7 +339,12 @@ static void execute_location(void *dst)
328{ 339{
329 void (*func)(void) = dst; 340 void (*func)(void) = dst;
330 341
342 pr_info("attempting ok execution at %p\n", do_nothing);
343 do_nothing();
344
331 memcpy(dst, do_nothing, EXEC_SIZE); 345 memcpy(dst, do_nothing, EXEC_SIZE);
346 flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
347 pr_info("attempting bad execution at %p\n", func);
332 func(); 348 func();
333} 349}
334 350
@@ -337,8 +353,13 @@ static void execute_user_location(void *dst)
337 /* Intentionally crossing kernel/user memory boundary. */ 353 /* Intentionally crossing kernel/user memory boundary. */
338 void (*func)(void) = dst; 354 void (*func)(void) = dst;
339 355
356 pr_info("attempting ok execution at %p\n", do_nothing);
357 do_nothing();
358
340 if (copy_to_user((void __user *)dst, do_nothing, EXEC_SIZE)) 359 if (copy_to_user((void __user *)dst, do_nothing, EXEC_SIZE))
341 return; 360 return;
361 flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE);
362 pr_info("attempting bad execution at %p\n", func);
342 func(); 363 func();
343} 364}
344 365
@@ -463,8 +484,12 @@ static void lkdtm_do_action(enum ctype which)
463 } 484 }
464 485
465 ptr = (unsigned long *)user_addr; 486 ptr = (unsigned long *)user_addr;
487
488 pr_info("attempting bad read at %p\n", ptr);
466 tmp = *ptr; 489 tmp = *ptr;
467 tmp += 0xc0dec0de; 490 tmp += 0xc0dec0de;
491
492 pr_info("attempting bad write at %p\n", ptr);
468 *ptr = tmp; 493 *ptr = tmp;
469 494
470 vm_munmap(user_addr, PAGE_SIZE); 495 vm_munmap(user_addr, PAGE_SIZE);
@@ -475,10 +500,28 @@ static void lkdtm_do_action(enum ctype which)
475 unsigned long *ptr; 500 unsigned long *ptr;
476 501
477 ptr = (unsigned long *)&rodata; 502 ptr = (unsigned long *)&rodata;
503
504 pr_info("attempting bad write at %p\n", ptr);
478 *ptr ^= 0xabcd1234; 505 *ptr ^= 0xabcd1234;
479 506
480 break; 507 break;
481 } 508 }
509 case CT_WRITE_KERN: {
510 size_t size;
511 unsigned char *ptr;
512
513 size = (unsigned long)do_overwritten -
514 (unsigned long)do_nothing;
515 ptr = (unsigned char *)do_overwritten;
516
517 pr_info("attempting bad %zu byte write at %p\n", size, ptr);
518 memcpy(ptr, (unsigned char *)do_nothing, size);
519 flush_icache_range((unsigned long)ptr,
520 (unsigned long)(ptr + size));
521
522 do_overwritten();
523 break;
524 }
482 case CT_NONE: 525 case CT_NONE:
483 default: 526 default:
484 break; 527 break;
@@ -493,8 +536,8 @@ static void lkdtm_handler(void)
493 536
494 spin_lock_irqsave(&count_lock, flags); 537 spin_lock_irqsave(&count_lock, flags);
495 count--; 538 count--;
496 printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", 539 pr_info("Crash point %s of type %s hit, trigger in %d rounds\n",
497 cp_name_to_str(cpoint), cp_type_to_str(cptype), count); 540 cp_name_to_str(cpoint), cp_type_to_str(cptype), count);
498 541
499 if (count == 0) { 542 if (count == 0) {
500 do_it = true; 543 do_it = true;
@@ -551,18 +594,18 @@ static int lkdtm_register_cpoint(enum cname which)
551 lkdtm.kp.symbol_name = "generic_ide_ioctl"; 594 lkdtm.kp.symbol_name = "generic_ide_ioctl";
552 lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl; 595 lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl;
553#else 596#else
554 printk(KERN_INFO "lkdtm: Crash point not available\n"); 597 pr_info("Crash point not available\n");
555 return -EINVAL; 598 return -EINVAL;
556#endif 599#endif
557 break; 600 break;
558 default: 601 default:
559 printk(KERN_INFO "lkdtm: Invalid Crash Point\n"); 602 pr_info("Invalid Crash Point\n");
560 return -EINVAL; 603 return -EINVAL;
561 } 604 }
562 605
563 cpoint = which; 606 cpoint = which;
564 if ((ret = register_jprobe(&lkdtm)) < 0) { 607 if ((ret = register_jprobe(&lkdtm)) < 0) {
565 printk(KERN_INFO "lkdtm: Couldn't register jprobe\n"); 608 pr_info("Couldn't register jprobe\n");
566 cpoint = CN_INVALID; 609 cpoint = CN_INVALID;
567 } 610 }
568 611
@@ -709,8 +752,7 @@ static ssize_t direct_entry(struct file *f, const char __user *user_buf,
709 if (type == CT_NONE) 752 if (type == CT_NONE)
710 return -EINVAL; 753 return -EINVAL;
711 754
712 printk(KERN_INFO "lkdtm: Performing direct entry %s\n", 755 pr_info("Performing direct entry %s\n", cp_type_to_str(type));
713 cp_type_to_str(type));
714 lkdtm_do_action(type); 756 lkdtm_do_action(type);
715 *off += count; 757 *off += count;
716 758
@@ -772,7 +814,7 @@ static int __init lkdtm_module_init(void)
772 /* Register debugfs interface */ 814 /* Register debugfs interface */
773 lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL); 815 lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
774 if (!lkdtm_debugfs_root) { 816 if (!lkdtm_debugfs_root) {
775 printk(KERN_ERR "lkdtm: creating root dir failed\n"); 817 pr_err("creating root dir failed\n");
776 return -ENODEV; 818 return -ENODEV;
777 } 819 }
778 820
@@ -787,28 +829,26 @@ static int __init lkdtm_module_init(void)
787 de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, 829 de = debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root,
788 NULL, &cur->fops); 830 NULL, &cur->fops);
789 if (de == NULL) { 831 if (de == NULL) {
790 printk(KERN_ERR "lkdtm: could not create %s\n", 832 pr_err("could not create %s\n", cur->name);
791 cur->name);
792 goto out_err; 833 goto out_err;
793 } 834 }
794 } 835 }
795 836
796 if (lkdtm_parse_commandline() == -EINVAL) { 837 if (lkdtm_parse_commandline() == -EINVAL) {
797 printk(KERN_INFO "lkdtm: Invalid command\n"); 838 pr_info("Invalid command\n");
798 goto out_err; 839 goto out_err;
799 } 840 }
800 841
801 if (cpoint != CN_INVALID && cptype != CT_NONE) { 842 if (cpoint != CN_INVALID && cptype != CT_NONE) {
802 ret = lkdtm_register_cpoint(cpoint); 843 ret = lkdtm_register_cpoint(cpoint);
803 if (ret < 0) { 844 if (ret < 0) {
804 printk(KERN_INFO "lkdtm: Invalid crash point %d\n", 845 pr_info("Invalid crash point %d\n", cpoint);
805 cpoint);
806 goto out_err; 846 goto out_err;
807 } 847 }
808 printk(KERN_INFO "lkdtm: Crash point %s of type %s registered\n", 848 pr_info("Crash point %s of type %s registered\n",
809 cpoint_name, cpoint_type); 849 cpoint_name, cpoint_type);
810 } else { 850 } else {
811 printk(KERN_INFO "lkdtm: No crash points registered, enable through debugfs\n"); 851 pr_info("No crash points registered, enable through debugfs\n");
812 } 852 }
813 853
814 return 0; 854 return 0;
@@ -823,7 +863,7 @@ static void __exit lkdtm_module_exit(void)
823 debugfs_remove_recursive(lkdtm_debugfs_root); 863 debugfs_remove_recursive(lkdtm_debugfs_root);
824 864
825 unregister_jprobe(&lkdtm); 865 unregister_jprobe(&lkdtm);
826 printk(KERN_INFO "lkdtm: Crash point unregistered\n"); 866 pr_info("Crash point unregistered\n");
827} 867}
828 868
829module_init(lkdtm_module_init); 869module_init(lkdtm_module_init);