diff options
author | Kees Cook <keescook@chromium.org> | 2013-07-08 13:01:33 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-07-25 01:47:20 -0400 |
commit | cc33c537c12f36e9ce753c308999cc2e93195112 (patch) | |
tree | 035b7a29193a50a42efb2d02a7066a47cac7bcf5 /drivers/misc | |
parent | 274a5855c034800b8e9a6ca32bbf81298ae917d8 (diff) |
lkdtm: add "EXEC_*" triggers
Add new crash locations that attempt to execute non-executable memory
regions (data segment, stack, kmalloc, vmalloc).
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/lkdtm.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 8bc7f0bcd945..2fc0586ce3bb 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/slab.h> | 43 | #include <linux/slab.h> |
44 | #include <scsi/scsi_cmnd.h> | 44 | #include <scsi/scsi_cmnd.h> |
45 | #include <linux/debugfs.h> | 45 | #include <linux/debugfs.h> |
46 | #include <linux/vmalloc.h> | ||
46 | 47 | ||
47 | #ifdef CONFIG_IDE | 48 | #ifdef CONFIG_IDE |
48 | #include <linux/ide.h> | 49 | #include <linux/ide.h> |
@@ -50,6 +51,7 @@ | |||
50 | 51 | ||
51 | #define DEFAULT_COUNT 10 | 52 | #define DEFAULT_COUNT 10 |
52 | #define REC_NUM_DEFAULT 10 | 53 | #define REC_NUM_DEFAULT 10 |
54 | #define EXEC_SIZE 64 | ||
53 | 55 | ||
54 | enum cname { | 56 | enum cname { |
55 | CN_INVALID, | 57 | CN_INVALID, |
@@ -80,6 +82,10 @@ enum ctype { | |||
80 | CT_HARDLOCKUP, | 82 | CT_HARDLOCKUP, |
81 | CT_SPINLOCKUP, | 83 | CT_SPINLOCKUP, |
82 | CT_HUNG_TASK, | 84 | CT_HUNG_TASK, |
85 | CT_EXEC_DATA, | ||
86 | CT_EXEC_STACK, | ||
87 | CT_EXEC_KMALLOC, | ||
88 | CT_EXEC_VMALLOC, | ||
83 | }; | 89 | }; |
84 | 90 | ||
85 | static char* cp_name[] = { | 91 | static char* cp_name[] = { |
@@ -109,6 +115,10 @@ static char* cp_type[] = { | |||
109 | "HARDLOCKUP", | 115 | "HARDLOCKUP", |
110 | "SPINLOCKUP", | 116 | "SPINLOCKUP", |
111 | "HUNG_TASK", | 117 | "HUNG_TASK", |
118 | "EXEC_DATA", | ||
119 | "EXEC_STACK", | ||
120 | "EXEC_KMALLOC", | ||
121 | "EXEC_VMALLOC", | ||
112 | }; | 122 | }; |
113 | 123 | ||
114 | static struct jprobe lkdtm; | 124 | static struct jprobe lkdtm; |
@@ -127,6 +137,8 @@ static int count = DEFAULT_COUNT; | |||
127 | static DEFINE_SPINLOCK(count_lock); | 137 | static DEFINE_SPINLOCK(count_lock); |
128 | static DEFINE_SPINLOCK(lock_me_up); | 138 | static DEFINE_SPINLOCK(lock_me_up); |
129 | 139 | ||
140 | static u8 data_area[EXEC_SIZE]; | ||
141 | |||
130 | module_param(recur_count, int, 0644); | 142 | module_param(recur_count, int, 0644); |
131 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ | 143 | MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\ |
132 | "default is 10"); | 144 | "default is 10"); |
@@ -280,6 +292,19 @@ static int recursive_loop(int a) | |||
280 | return recursive_loop(a); | 292 | return recursive_loop(a); |
281 | } | 293 | } |
282 | 294 | ||
295 | static void do_nothing(void) | ||
296 | { | ||
297 | return; | ||
298 | } | ||
299 | |||
300 | static void execute_location(void *dst) | ||
301 | { | ||
302 | void (*func)(void) = dst; | ||
303 | |||
304 | memcpy(dst, do_nothing, EXEC_SIZE); | ||
305 | func(); | ||
306 | } | ||
307 | |||
283 | static void lkdtm_do_action(enum ctype which) | 308 | static void lkdtm_do_action(enum ctype which) |
284 | { | 309 | { |
285 | switch (which) { | 310 | switch (which) { |
@@ -356,6 +381,26 @@ static void lkdtm_do_action(enum ctype which) | |||
356 | set_current_state(TASK_UNINTERRUPTIBLE); | 381 | set_current_state(TASK_UNINTERRUPTIBLE); |
357 | schedule(); | 382 | schedule(); |
358 | break; | 383 | break; |
384 | case CT_EXEC_DATA: | ||
385 | execute_location(data_area); | ||
386 | break; | ||
387 | case CT_EXEC_STACK: { | ||
388 | u8 stack_area[EXEC_SIZE]; | ||
389 | execute_location(stack_area); | ||
390 | break; | ||
391 | } | ||
392 | case CT_EXEC_KMALLOC: { | ||
393 | u32 *kmalloc_area = kmalloc(EXEC_SIZE, GFP_KERNEL); | ||
394 | execute_location(kmalloc_area); | ||
395 | kfree(kmalloc_area); | ||
396 | break; | ||
397 | } | ||
398 | case CT_EXEC_VMALLOC: { | ||
399 | u32 *vmalloc_area = vmalloc(EXEC_SIZE); | ||
400 | execute_location(vmalloc_area); | ||
401 | vfree(vmalloc_area); | ||
402 | break; | ||
403 | } | ||
359 | case CT_NONE: | 404 | case CT_NONE: |
360 | default: | 405 | default: |
361 | break; | 406 | break; |