Commit a0266c21 authored by Wang Nan's avatar Wang Nan Committed by Jon Medhurst

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: default avatarWang Nan <wangnan0@huawei.com>
Reviewed-by: default avatarJon Medhurst <tixy@linaro.org>
Signed-off-by: default avatarJon Medhurst <tixy@linaro.org>
parent 6624cf65
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#define __ARCH_WANT_KPROBES_INSN_SLOT #define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE 2 #define MAX_INSN_SIZE 2
#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
#define flush_insn_slot(p) do { } while (0) #define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0 #define kretprobe_blacklist_size 0
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
#ifndef _ASM_PROBES_H #ifndef _ASM_PROBES_H
#define _ASM_PROBES_H #define _ASM_PROBES_H
#ifndef __ASSEMBLY__
typedef u32 probes_opcode_t; typedef u32 probes_opcode_t;
struct arch_probes_insn; struct arch_probes_insn;
...@@ -41,4 +43,14 @@ struct arch_probes_insn { ...@@ -41,4 +43,14 @@ struct arch_probes_insn {
int stack_space; int stack_space;
}; };
#endif /* __ASSEMBLY__ */
/*
* We assume one instruction can consume at most 64 bytes stack, which is
* 'push {r0-r15}'. Instructions consume more or unknown stack space like
* 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe.
* Both kprobe and jprobe use this macro.
*/
#define MAX_STACK_SIZE 64
#endif #endif
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "entry-header.S" #include "entry-header.S"
#include <asm/entry-macro-multi.S> #include <asm/entry-macro-multi.S>
#include <asm/probes.h>
/* /*
* Interrupt handling. * Interrupt handling.
...@@ -249,7 +250,7 @@ __und_svc: ...@@ -249,7 +250,7 @@ __und_svc:
@ If a kprobe is about to simulate a "stmdb sp..." instruction, @ If a kprobe is about to simulate a "stmdb sp..." instruction,
@ it obviously needs free stack space which then will belong to @ it obviously needs free stack space which then will belong to
@ the saved context. @ the saved context.
svc_entry 64 svc_entry MAX_STACK_SIZE
#else #else
svc_entry svc_entry
#endif #endif
......
...@@ -115,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) ...@@ -115,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
break; break;
} }
/*
* Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes
* 'str r0, [sp, #-68]' should also be prohibited.
* See __und_svc.
*/
if ((p->ainsn.stack_space < 0) ||
(p->ainsn.stack_space > MAX_STACK_SIZE))
return -EINVAL;
return 0; return 0;
} }
......
...@@ -476,7 +476,8 @@ void kprobe_arm_test_cases(void) ...@@ -476,7 +476,8 @@ void kprobe_arm_test_cases(void)
TEST_GROUP("Extra load/store instructions") TEST_GROUP("Extra load/store instructions")
TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")
TEST_RPR( "streqh r",14,VAL2,", [r",13,0, ", r",12, 48,"]") TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]")
TEST_UNSUPPORTED( "streqh r14, [r13, r12]")
TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!")
TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!") TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"") TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"")
...@@ -565,7 +566,8 @@ void kprobe_arm_test_cases(void) ...@@ -565,7 +566,8 @@ void kprobe_arm_test_cases(void)
#if __LINUX_ARM_ARCH__ >= 5 #if __LINUX_ARM_ARCH__ >= 5
TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]") TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]")
TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]") TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]")
TEST_UNSUPPORTED( "strccd r8, [r13, r12]")
TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!") TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!") TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"") TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"")
...@@ -638,13 +640,15 @@ void kprobe_arm_test_cases(void) ...@@ -638,13 +640,15 @@ void kprobe_arm_test_cases(void)
TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \ TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \
TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \ TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \
TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \
TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 48,"]") \ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \
TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \
TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \
TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \ TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \
TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \ TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \
TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \ TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \
TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\ TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\
TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\
TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]")\
TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\ TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\
TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\ TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\
TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \ TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \
...@@ -668,12 +672,12 @@ void kprobe_arm_test_cases(void) ...@@ -668,12 +672,12 @@ void kprobe_arm_test_cases(void)
LOAD_STORE("") LOAD_STORE("")
TEST_P( "str pc, [r",0,0,", #15*4]") TEST_P( "str pc, [r",0,0,", #15*4]")
TEST_R( "str pc, [sp, r",2,15*4,"]") TEST_UNSUPPORTED( "str pc, [sp, r2]")
TEST_BF( "ldr pc, [sp, #15*4]") TEST_BF( "ldr pc, [sp, #15*4]")
TEST_BF_R("ldr pc, [sp, r",2,15*4,"]") TEST_BF_R("ldr pc, [sp, r",2,15*4,"]")
TEST_P( "str sp, [r",0,0,", #13*4]") TEST_P( "str sp, [r",0,0,", #13*4]")
TEST_R( "str sp, [sp, r",2,13*4,"]") TEST_UNSUPPORTED( "str sp, [sp, r2]")
TEST_BF( "ldr sp, [sp, #13*4]") TEST_BF( "ldr sp, [sp, #13*4]")
TEST_BF_R("ldr sp, [sp, r",2,13*4,"]") TEST_BF_R("ldr sp, [sp, r",2,13*4,"]")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment