aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWang Nan <wangnan0@huawei.com>2015-01-05 06:29:25 -0500
committerJon Medhurst <tixy@linaro.org>2015-01-13 11:10:15 -0500
commita0266c214fab21371a499e6ab1c9385cc6589189 (patch)
tree69accee3d0fdc9ae9a0c3c683a7ed87497e61a81
parent6624cf651f1a14363d0385f36dc255d304ac7ebb (diff)
ARM: kprobes: disallow probing stack consuming instructions
This patch prohibits probing instructions for which the stack requirements are unable to be determined statically. Some test cases are found not work again after the modification, this patch also removes them. Signed-off-by: Wang Nan <wangnan0@huawei.com> Reviewed-by: Jon Medhurst <tixy@linaro.org> Signed-off-by: Jon Medhurst <tixy@linaro.org>
-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