summaryrefslogtreecommitdiff
path: root/arch/arm64
diff options
context:
space:
mode:
authorPeng Du <pdu@nvidia.com>2014-07-23 11:40:33 -0700
committerMatthew Pedro <mapedro@nvidia.com>2014-07-28 12:19:36 -0700
commitf5091b9678a8a00cf8bb0181e08e1ccdb81fce9b (patch)
treed1c95c1b7826a04480d6107aeb648161ecd6509b /arch/arm64
parent18aa7b3f4a96ea569d9d9797fd2ad152a403f5a2 (diff)
arm64: kernel: check mode for get_user in undefinstr
get_user() should be called only for user_mode undef instruction. Bug 1536343 Change-Id: Ia654783de0cf72abac6847ac9630236f9f0d6ebb Signed-off-by: Peng Du <pdu@nvidia.com> Reviewed-on: http://git-master/r/441348 (cherry picked from commit 518317f3e09c794e14de49f1afe47a93f92787ab) Reviewed-on: http://git-master/r/448179 Reviewed-by: Matthew Pedro <mapedro@nvidia.com> Tested-by: Matthew Pedro <mapedro@nvidia.com>
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/kernel/traps.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index ab9f1ec73933..d23f9341c58e 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -287,19 +287,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
/* check for AArch32 breakpoint instructions */
if (!aarch32_break_handler(regs))
return;
- if (compat_thumb_mode(regs)) {
- if (get_user(instr, (u16 __user *)pc))
- goto die_sig;
- if (is_wide_instruction(instr)) {
- u32 instr2;
- if (get_user(instr2, (u16 __user *)pc+1))
+ if (user_mode(regs)) {
+ if (compat_thumb_mode(regs)) {
+ if (get_user(instr, (u16 __user *)pc))
goto die_sig;
- instr <<= 16;
- instr |= instr2;
+ if (is_wide_instruction(instr)) {
+ u32 instr2;
+ if (get_user(instr2, (u16 __user *)pc+1))
+ goto die_sig;
+ instr <<= 16;
+ instr |= instr2;
+ }
+ } else if (get_user(instr, (u32 __user *)pc)) {
+ goto die_sig;
}
-
- } else if ((get_user(instr, (u32 __user *)pc))) {
- goto die_sig;
+ } else {
+ /* kernel mode */
+ instr = *((u32 *)pc);
}
if (call_undef_hook(regs, instr) == 0)