diff options
author | Bobby Bingham <koorogi@koorogi.info> | 2014-04-03 17:46:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-03 19:20:52 -0400 |
commit | a3c195144e162097c42e4284323ed6d386de105d (patch) | |
tree | beae07ac4a12e2bee76f3160a8f4b5725f8a00ad /arch | |
parent | 7caf62de25554da3af00c92c11afa95dcc3592c4 (diff) |
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>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/sh/include/asm/traps_32.h | 16 | ||||
-rw-r--r-- | arch/sh/kernel/traps_32.c | 23 |
2 files changed, 11 insertions, 28 deletions
diff --git a/arch/sh/include/asm/traps_32.h b/arch/sh/include/asm/traps_32.h index cfd55ff9dff2..17e129fe459c 100644 --- a/arch/sh/include/asm/traps_32.h +++ b/arch/sh/include/asm/traps_32.h | |||
@@ -42,18 +42,10 @@ static inline void trigger_address_error(void) | |||
42 | asmlinkage void do_address_error(struct pt_regs *regs, | 42 | asmlinkage void do_address_error(struct pt_regs *regs, |
43 | unsigned long writeaccess, | 43 | unsigned long writeaccess, |
44 | unsigned long address); | 44 | unsigned long address); |
45 | asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, | 45 | asmlinkage void do_divide_error(unsigned long r4); |
46 | unsigned long r6, unsigned long r7, | 46 | asmlinkage void do_reserved_inst(void); |
47 | struct pt_regs __regs); | 47 | asmlinkage void do_illegal_slot_inst(void); |
48 | asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | 48 | asmlinkage void do_exception_error(void); |
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); | ||
57 | 49 | ||
58 | #define BUILD_TRAP_HANDLER(name) \ | 50 | #define BUILD_TRAP_HANDLER(name) \ |
59 | asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ | 51 | asmlinkage void name##_trap_handler(unsigned long r4, unsigned long r5, \ |
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c index 68e99f09171d..ff639342a8be 100644 --- a/arch/sh/kernel/traps_32.c +++ b/arch/sh/kernel/traps_32.c | |||
@@ -594,9 +594,7 @@ int is_dsp_inst(struct pt_regs *regs) | |||
594 | #endif /* CONFIG_SH_DSP */ | 594 | #endif /* CONFIG_SH_DSP */ |
595 | 595 | ||
596 | #ifdef CONFIG_CPU_SH2A | 596 | #ifdef CONFIG_CPU_SH2A |
597 | asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, | 597 | asmlinkage void do_divide_error(unsigned long r4) |
598 | unsigned long r6, unsigned long r7, | ||
599 | struct pt_regs __regs) | ||
600 | { | 598 | { |
601 | siginfo_t info; | 599 | siginfo_t info; |
602 | 600 | ||
@@ -613,11 +611,9 @@ asmlinkage void do_divide_error(unsigned long r4, unsigned long r5, | |||
613 | } | 611 | } |
614 | #endif | 612 | #endif |
615 | 613 | ||
616 | asmlinkage void do_reserved_inst(unsigned long r4, unsigned long r5, | 614 | asmlinkage void do_reserved_inst(void) |
617 | unsigned long r6, unsigned long r7, | ||
618 | struct pt_regs __regs) | ||
619 | { | 615 | { |
620 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 616 | struct pt_regs *regs = current_pt_regs(); |
621 | unsigned long error_code; | 617 | unsigned long error_code; |
622 | struct task_struct *tsk = current; | 618 | struct task_struct *tsk = current; |
623 | 619 | ||
@@ -701,11 +697,9 @@ static int emulate_branch(unsigned short inst, struct pt_regs *regs) | |||
701 | } | 697 | } |
702 | #endif | 698 | #endif |
703 | 699 | ||
704 | asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, | 700 | asmlinkage void do_illegal_slot_inst(void) |
705 | unsigned long r6, unsigned long r7, | ||
706 | struct pt_regs __regs) | ||
707 | { | 701 | { |
708 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | 702 | struct pt_regs *regs = current_pt_regs(); |
709 | unsigned long inst; | 703 | unsigned long inst; |
710 | struct task_struct *tsk = current; | 704 | struct task_struct *tsk = current; |
711 | 705 | ||
@@ -730,15 +724,12 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, | |||
730 | die_if_no_fixup("illegal slot instruction", regs, inst); | 724 | die_if_no_fixup("illegal slot instruction", regs, inst); |
731 | } | 725 | } |
732 | 726 | ||
733 | asmlinkage void do_exception_error(unsigned long r4, unsigned long r5, | 727 | asmlinkage void do_exception_error(void) |
734 | unsigned long r6, unsigned long r7, | ||
735 | struct pt_regs __regs) | ||
736 | { | 728 | { |
737 | struct pt_regs *regs = RELOC_HIDE(&__regs, 0); | ||
738 | long ex; | 729 | long ex; |
739 | 730 | ||
740 | ex = lookup_exception_vector(); | 731 | ex = lookup_exception_vector(); |
741 | die_if_kernel("exception", regs, ex); | 732 | die_if_kernel("exception", current_pt_regs(), ex); |
742 | } | 733 | } |
743 | 734 | ||
744 | void per_cpu_trap_init(void) | 735 | void per_cpu_trap_init(void) |