diff options
-rw-r--r-- | arch/arm/include/asm/kprobes.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/probes.h | 12 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 3 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/core.c | 9 | ||||
-rw-r--r-- | arch/arm/probes/kprobes/test-arm.c | 16 |
5 files changed, 33 insertions, 8 deletions
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h index 49fa0dfaad33..56f9ac68fbd1 100644 --- a/arch/arm/include/asm/kprobes.h +++ b/arch/arm/include/asm/kprobes.h | |||
@@ -22,7 +22,6 @@ | |||
22 | 22 | ||
23 | #define __ARCH_WANT_KPROBES_INSN_SLOT | 23 | #define __ARCH_WANT_KPROBES_INSN_SLOT |
24 | #define MAX_INSN_SIZE 2 | 24 | #define MAX_INSN_SIZE 2 |
25 | #define MAX_STACK_SIZE 64 /* 32 would probably be OK */ | ||
26 | 25 | ||
27 | #define flush_insn_slot(p) do { } while (0) | 26 | #define flush_insn_slot(p) do { } while (0) |
28 | #define kretprobe_blacklist_size 0 | 27 | #define kretprobe_blacklist_size 0 |
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h index 6026deb28794..cd9e81588d83 100644 --- a/arch/arm/include/asm/probes.h +++ b/arch/arm/include/asm/probes.h | |||
@@ -19,6 +19,8 @@ | |||
19 | #ifndef _ASM_PROBES_H | 19 | #ifndef _ASM_PROBES_H |
20 | #define _ASM_PROBES_H | 20 | #define _ASM_PROBES_H |
21 | 21 | ||
22 | #ifndef __ASSEMBLY__ | ||
23 | |||
22 | typedef u32 probes_opcode_t; | 24 | typedef u32 probes_opcode_t; |
23 | 25 | ||
24 | struct arch_probes_insn; | 26 | struct arch_probes_insn; |
@@ -41,4 +43,14 @@ struct arch_probes_insn { | |||
41 | int stack_space; | 43 | int stack_space; |
42 | }; | 44 | }; |
43 | 45 | ||
46 | #endif /* __ASSEMBLY__ */ | ||
47 | |||
48 | /* | ||
49 | * We assume one instruction can consume at most 64 bytes stack, which is | ||
50 | * 'push {r0-r15}'. Instructions consume more or unknown stack space like | ||
51 | * 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe. | ||
52 | * Both kprobe and jprobe use this macro. | ||
53 | */ | ||
54 | #define MAX_STACK_SIZE 64 | ||
55 | |||
44 | #endif | 56 | #endif |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 2f5555d307b3..672b21942fff 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include "entry-header.S" | 32 | #include "entry-header.S" |
33 | #include <asm/entry-macro-multi.S> | 33 | #include <asm/entry-macro-multi.S> |
34 | #include <asm/probes.h> | ||
34 | 35 | ||
35 | /* | 36 | /* |
36 | * Interrupt handling. | 37 | * Interrupt handling. |
@@ -249,7 +250,7 @@ __und_svc: | |||
249 | @ If a kprobe is about to simulate a "stmdb sp..." instruction, | 250 | @ If a kprobe is about to simulate a "stmdb sp..." instruction, |
250 | @ it obviously needs free stack space which then will belong to | 251 | @ it obviously needs free stack space which then will belong to |
251 | @ the saved context. | 252 | @ the saved context. |
252 | svc_entry 64 | 253 | svc_entry MAX_STACK_SIZE |
253 | #else | 254 | #else |
254 | svc_entry | 255 | svc_entry |
255 | #endif | 256 | #endif |
diff --git a/arch/arm/probes/kprobes/core.c b/arch/arm/probes/kprobes/core.c index 74f3dc3ac212..3a58db4cc1c6 100644 --- a/arch/arm/probes/kprobes/core.c +++ b/arch/arm/probes/kprobes/core.c | |||
@@ -115,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
115 | break; | 115 | break; |
116 | } | 116 | } |
117 | 117 | ||
118 | /* | ||
119 | * Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes | ||
120 | * 'str r0, [sp, #-68]' should also be prohibited. | ||
121 | * See __und_svc. | ||
122 | */ | ||
123 | if ((p->ainsn.stack_space < 0) || | ||
124 | (p->ainsn.stack_space > MAX_STACK_SIZE)) | ||
125 | return -EINVAL; | ||
126 | |||
118 | return 0; | 127 | return 0; |
119 | } | 128 | } |
120 | 129 | ||
diff --git a/arch/arm/probes/kprobes/test-arm.c b/arch/arm/probes/kprobes/test-arm.c index d9a1255f3043..fdeb300b0fc8 100644 --- a/arch/arm/probes/kprobes/test-arm.c +++ b/arch/arm/probes/kprobes/test-arm.c | |||
@@ -476,7 +476,8 @@ void kprobe_arm_test_cases(void) | |||
476 | TEST_GROUP("Extra load/store instructions") | 476 | TEST_GROUP("Extra load/store instructions") |
477 | 477 | ||
478 | TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") | 478 | TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") |
479 | TEST_RPR( "streqh r",14,VAL2,", [r",13,0, ", r",12, 48,"]") | 479 | TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]") |
480 | TEST_UNSUPPORTED( "streqh r14, [r13, r12]") | ||
480 | TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") | 481 | TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") |
481 | TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!") | 482 | TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!") |
482 | TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"") | 483 | TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"") |
@@ -565,7 +566,8 @@ void kprobe_arm_test_cases(void) | |||
565 | 566 | ||
566 | #if __LINUX_ARM_ARCH__ >= 5 | 567 | #if __LINUX_ARM_ARCH__ >= 5 |
567 | TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") | 568 | TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") |
568 | TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]") | 569 | TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]") |
570 | TEST_UNSUPPORTED( "strccd r8, [r13, r12]") | ||
569 | TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") | 571 | TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") |
570 | TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!") | 572 | TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!") |
571 | TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"") | 573 | TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"") |
@@ -638,13 +640,15 @@ void kprobe_arm_test_cases(void) | |||
638 | TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ | 640 | TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ |
639 | TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ | 641 | TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ |
640 | TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ | 642 | TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ |
641 | TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 48,"]") \ | 643 | TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \ |
644 | TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \ | ||
642 | TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ | 645 | TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ |
643 | TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ | 646 | TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ |
644 | TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ | 647 | TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ |
645 | TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ | 648 | TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ |
646 | TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ | 649 | TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ |
647 | TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\ | 650 | TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\ |
651 | TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]")\ | ||
648 | TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ | 652 | TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ |
649 | TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\ | 653 | TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\ |
650 | TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \ | 654 | TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \ |
@@ -668,12 +672,12 @@ void kprobe_arm_test_cases(void) | |||
668 | 672 | ||
669 | LOAD_STORE("") | 673 | LOAD_STORE("") |
670 | TEST_P( "str pc, [r",0,0,", #15*4]") | 674 | TEST_P( "str pc, [r",0,0,", #15*4]") |
671 | TEST_R( "str pc, [sp, r",2,15*4,"]") | 675 | TEST_UNSUPPORTED( "str pc, [sp, r2]") |
672 | TEST_BF( "ldr pc, [sp, #15*4]") | 676 | TEST_BF( "ldr pc, [sp, #15*4]") |
673 | TEST_BF_R("ldr pc, [sp, r",2,15*4,"]") | 677 | TEST_BF_R("ldr pc, [sp, r",2,15*4,"]") |
674 | 678 | ||
675 | TEST_P( "str sp, [r",0,0,", #13*4]") | 679 | TEST_P( "str sp, [r",0,0,", #13*4]") |
676 | TEST_R( "str sp, [sp, r",2,13*4,"]") | 680 | TEST_UNSUPPORTED( "str sp, [sp, r2]") |
677 | TEST_BF( "ldr sp, [sp, #13*4]") | 681 | TEST_BF( "ldr sp, [sp, #13*4]") |
678 | TEST_BF_R("ldr sp, [sp, r",2,13*4,"]") | 682 | TEST_BF_R("ldr sp, [sp, r",2,13*4,"]") |
679 | 683 | ||