sh: don't pass saved userspace state to exception handlers
authorBobby Bingham <koorogi@koorogi.info>
Thu, 3 Apr 2014 21:46:41 +0000 (14:46 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 3 Apr 2014 23:20:52 +0000 (16:20 -0700)
The compiler is permitted to generate code which overwrites the
parameters to a function.  If those parameters include the only saved
copy we have of userspace's registers, we're in trouble.

Signed-off-by: Bobby Bingham <koorogi@koorogi.info>
Cc: Paul Mundt <paul.mundt@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/sh/include/asm/traps_32.h
arch/sh/kernel/traps_32.c

index cfd55ff9dff24197ae8e9c2f728c78ca2e9f1616..17e129fe459c61bd30b417df5864fe88bb5972c8 100644 (file)
@@ -42,18 +42,10 @@ static inline void trigger_address_error(void)
 asmlinkage void do_address_error(struct pt_regs *regs,
                                 unsigned long writeaccess,
                                 unsigned long address);
-asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
-                               unsigned long r6, unsigned long r7,
-                               struct pt_regs __regs);
-asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
-                               unsigned long r6, unsigned long r7,
-                               struct pt_regs __regs);
-asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
-                               unsigned long r6, unsigned long r7,
-                               struct pt_regs __regs);
-asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
-                                  unsigned long r6, unsigned long r7,
-                                  struct pt_regs __regs);
+asmlinkage void do_divide_error(unsigned long r4);
+asmlinkage void do_reserved_inst(void);
+asmlinkage void do_illegal_slot_inst(void);
+asmlinkage void do_exception_error(void);
 
 #define BUILD_TRAP_HANDLER(name)                                       \
 asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5,        \
index 68e99f09171dd668248489499e9e10073b23d579..ff639342a8bef97fa81b89120deae05740974b28 100644 (file)
@@ -594,9 +594,7 @@ int is_dsp_inst(struct pt_regs *regs)
 #endif /* CONFIG_SH_DSP */
 
 #ifdef CONFIG_CPU_SH2A
-asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
-                               unsigned long r6, unsigned long r7,
-                               struct pt_regs __regs)
+asmlinkage void do_divide_error(unsigned long r4)
 {
        siginfo_t info;
 
@@ -613,11 +611,9 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5,
 }
 #endif
 
-asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5,
-                               unsigned long r6, unsigned long r7,
-                               struct pt_regs __regs)
+asmlinkage void do_reserved_inst(void)
 {
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       struct pt_regs *regs = current_pt_regs();
        unsigned long error_code;
        struct task_struct *tsk = current;
 
@@ -701,11 +697,9 @@ static int emulate_branch(unsigned short inst, struct pt_regs *regs)
 }
 #endif
 
-asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
-                               unsigned long r6, unsigned long r7,
-                               struct pt_regs __regs)
+asmlinkage void do_illegal_slot_inst(void)
 {
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
+       struct pt_regs *regs = current_pt_regs();
        unsigned long inst;
        struct task_struct *tsk = current;
 
@@ -730,15 +724,12 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
        die_if_no_fixup("illegal slot instruction", regs, inst);
 }
 
-asmlinkage void do_exception_error(unsigned long r4, unsigned long r5,
-                                  unsigned long r6, unsigned long r7,
-                                  struct pt_regs __regs)
+asmlinkage void do_exception_error(void)
 {
-       struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
        long ex;
 
        ex = lookup_exception_vector();
-       die_if_kernel("exception", regs, ex);
+       die_if_kernel("exception", current_pt_regs(), ex);
 }
 
 void per_cpu_trap_init(void)