Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sh: don't pass saved userspace state to exception handlers

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>

authored by

Bobby Bingham and committed by
Linus Torvalds
a3c19514 7caf62de

+11 -28
+4 -12
arch/sh/include/asm/traps_32.h
··· 42 42 asmlinkage void do_address_error(struct pt_regs *regs, 43 43 unsigned long writeaccess, 44 44 unsigned long address); 45 - asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, 46 - unsigned long r6, unsigned long r7, 47 - struct pt_regs __regs); 48 - asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, 49 - unsigned long r6, unsigned long r7, 50 - struct pt_regs __regs); 51 - asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, 52 - unsigned long r6, unsigned long r7, 53 - struct pt_regs __regs); 54 - asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, 55 - unsigned long r6, unsigned long r7, 56 - struct pt_regs __regs); 45 + asmlinkage void do_divide_error(unsigned long r4); 46 + asmlinkage void do_reserved_inst(void); 47 + asmlinkage void do_illegal_slot_inst(void); 48 + asmlinkage void do_exception_error(void); 57 49 58 50 #define BUILD_TRAP_HANDLER(name) \ 59 51 asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \
+7 -16
arch/sh/kernel/traps_32.c
··· 594 594 #endif /* CONFIG_SH_DSP */ 595 595 596 596 #ifdef CONFIG_CPU_SH2A 597 - asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, 598 - unsigned long r6, unsigned long r7, 599 - struct pt_regs __regs) 597 + asmlinkage void do_divide_error(unsigned long r4) 600 598 { 601 599 siginfo_t info; 602 600 ··· 611 613 } 612 614 #endif 613 615 614 - asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, 615 - unsigned long r6, unsigned long r7, 616 - struct pt_regs __regs) 616 + asmlinkage void do_reserved_inst(void) 617 617 { 618 - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 618 + struct pt_regs *regs = current_pt_regs(); 619 619 unsigned long error_code; 620 620 struct task_struct *tsk = current; 621 621 ··· 697 701 } 698 702 #endif 699 703 700 - asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, 701 - unsigned long r6, unsigned long r7, 702 - struct pt_regs __regs) 704 + asmlinkage void do_illegal_slot_inst(void) 703 705 { 704 - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 706 + struct pt_regs *regs = current_pt_regs(); 705 707 unsigned long inst; 706 708 struct task_struct *tsk = current; 707 709 ··· 724 730 die_if_no_fixup("illegal slot instruction", regs, inst); 725 731 } 726 732 727 - asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, 728 - unsigned long r6, unsigned long r7, 729 - struct pt_regs __regs) 733 + asmlinkage void do_exception_error(void) 730 734 { 731 - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); 732 735 long ex; 733 736 734 737 ex = lookup_exception_vector(); 735 - die_if_kernel("exception", regs, ex); 738 + die_if_kernel("exception", current_pt_regs(), ex); 736 739 } 737 740 738 741 void per_cpu_trap_init(void)