diff options
author | Jon Medhurst <tixy@yxit.co.uk> | 2011-04-19 05:52:16 -0400 |
---|---|---|
committer | Nicolas Pitre <nicolas.pitre@linaro.org> | 2011-04-28 23:40:59 -0400 |
commit | f704a6e25bd07e1381af81f19fb1d123975807b1 (patch) | |
tree | dc571d149ae5a78c9adf667cf512438615470ebe /arch | |
parent | 72c2bab2be734d63dee4342e67b1754c54fded70 (diff) |
ARM: kprobes: Reject probing of undefined data processing instructions
The instruction decoding in space_cccc_000x needs to reject probing of
instructions with undefined patterns as they may in future become
defined and then emulated faultily - as has already happened with the
SMC instruction.
This fix is achieved by testing for the instruction patterns we want to
probe and making the the default fall-through paths reject probes. This
also allows us to remove some explicit tests for instructions that we
wish to reject, as that is now the default action.
Signed-off-by: Jon Medhurst <tixy@yxit.co.uk>
Signed-off-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/kernel/kprobes-decode.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c index dc315c12d5f3..4715537b490c 100644 --- a/arch/arm/kernel/kprobes-decode.c +++ b/arch/arm/kernel/kprobes-decode.c | |||
@@ -966,14 +966,6 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
966 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ | 966 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx xxx0 xxxx */ |
967 | if ((insn & 0x0f900010) == 0x01000000) { | 967 | if ((insn & 0x0f900010) == 0x01000000) { |
968 | 968 | ||
969 | /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | ||
970 | /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | ||
971 | /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ | ||
972 | if ((insn & 0x0ff000f0) == 0x01200020 || | ||
973 | (insn & 0x0fb000f0) == 0x01200000 || | ||
974 | (insn & 0x0ff000f0) == 0x01400000) | ||
975 | return INSN_REJECTED; | ||
976 | |||
977 | /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ | 969 | /* MRS cpsr : cccc 0001 0000 xxxx xxxx xxxx 0000 xxxx */ |
978 | if ((insn & 0x0ff000f0) == 0x01000000) { | 970 | if ((insn & 0x0ff000f0) == 0x01000000) { |
979 | if (is_r15(insn, 12)) | 971 | if (is_r15(insn, 12)) |
@@ -994,17 +986,21 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
994 | 986 | ||
995 | /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ | 987 | /* SMLAxy : cccc 0001 0000 xxxx xxxx xxxx 1xx0 xxxx : Q */ |
996 | /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */ | 988 | /* SMLAWy : cccc 0001 0010 xxxx xxxx xxxx 1x00 xxxx : Q */ |
997 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | 989 | if ((insn & 0x0ff00090) == 0x01000080 || |
990 | (insn & 0x0ff000b0) == 0x01200080) | ||
991 | return prep_emulate_rd16rn12rs8rm0_wflags(insn, asi); | ||
992 | |||
993 | /* BXJ : cccc 0001 0010 xxxx xxxx xxxx 0010 xxxx */ | ||
994 | /* MSR : cccc 0001 0x10 xxxx xxxx xxxx 0000 xxxx */ | ||
995 | /* MRS spsr : cccc 0001 0100 xxxx xxxx xxxx 0000 xxxx */ | ||
998 | 996 | ||
997 | /* Other instruction encodings aren't yet defined */ | ||
998 | return INSN_REJECTED; | ||
999 | } | 999 | } |
1000 | 1000 | ||
1001 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ | 1001 | /* cccc 0001 0xx0 xxxx xxxx xxxx xxxx 0xx1 xxxx */ |
1002 | else if ((insn & 0x0f900090) == 0x01000010) { | 1002 | else if ((insn & 0x0f900090) == 0x01000010) { |
1003 | 1003 | ||
1004 | /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
1005 | if ((insn & 0xfff000f0) == 0xe1200070) | ||
1006 | return INSN_REJECTED; | ||
1007 | |||
1008 | /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ | 1004 | /* BLX(2) : cccc 0001 0010 xxxx xxxx xxxx 0011 xxxx */ |
1009 | /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ | 1005 | /* BX : cccc 0001 0010 xxxx xxxx xxxx 0001 xxxx */ |
1010 | if ((insn & 0x0ff000d0) == 0x01200010) { | 1006 | if ((insn & 0x0ff000d0) == 0x01200010) { |
@@ -1022,7 +1018,14 @@ space_cccc_000x(kprobe_opcode_t insn, struct arch_specific_insn *asi) | |||
1022 | /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ | 1018 | /* QSUB : cccc 0001 0010 xxxx xxxx xxxx 0101 xxxx :Q */ |
1023 | /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ | 1019 | /* QDADD : cccc 0001 0100 xxxx xxxx xxxx 0101 xxxx :Q */ |
1024 | /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ | 1020 | /* QDSUB : cccc 0001 0110 xxxx xxxx xxxx 0101 xxxx :Q */ |
1025 | return prep_emulate_rd12rn16rm0_wflags(insn, asi); | 1021 | if ((insn & 0x0f9000f0) == 0x01000050) |
1022 | return prep_emulate_rd12rn16rm0_wflags(insn, asi); | ||
1023 | |||
1024 | /* BKPT : 1110 0001 0010 xxxx xxxx xxxx 0111 xxxx */ | ||
1025 | /* SMC : cccc 0001 0110 xxxx xxxx xxxx 0111 xxxx */ | ||
1026 | |||
1027 | /* Other instruction encodings aren't yet defined */ | ||
1028 | return INSN_REJECTED; | ||
1026 | } | 1029 | } |
1027 | 1030 | ||
1028 | /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ | 1031 | /* cccc 0000 xxxx xxxx xxxx xxxx xxxx 1001 xxxx */ |