arm64: kernel: check mode for get_user in undefinstr
authorPeng Du <pdu@nvidia.com>
Wed, 23 Jul 2014 18:40:33 +0000 (11:40 -0700)
committerGreg Hackmann <ghackmann@google.com>
Sat, 13 Sep 2014 00:29:43 +0000 (17:29 -0700)
get_user() should be called only for user_mode undef instruction.

Change-Id: Ia654783de0cf72abac6847ac9630236f9f0d6ebb
Signed-off-by: Peng Du <pdu@nvidia.com>
Reviewed-on: http://git-master/r/441348
Reviewed-by: Thomas Cherry <tcherry@nvidia.com>
Reviewed-by: Bo Yan <byan@nvidia.com>
arch/arm64/kernel/traps.c

index 4f8bf320ec99840f86d10d4e8cc6565f76de4d96..0da47699510b685f5d56d9d4cde2a0dfb9ca9242 100644 (file)
@@ -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)