aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/kprobes.h1
-rw-r--r--arch/arm/include/asm/probes.h12
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/probes/kprobes/core.c9
-rw-r--r--arch/arm/probes/kprobes/test-arm.c16
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
22typedef u32 probes_opcode_t; 24typedef u32 probes_opcode_t;
23 25
24struct arch_probes_insn; 26struct 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