From a0c32761e73c9999cbf592b702f284221fea8040 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Thu, 3 Apr 2014 14:46:20 -0700 Subject: sh: fix format string bug in stack tracer Kees reported the following error: arch/sh/kernel/dumpstack.c: In function 'print_trace_address': arch/sh/kernel/dumpstack.c:118:2: error: format not a string literal and no format arguments [-Werror=format-security] Use the "%s" format so that it's impossible to interpret 'data' as a format string. Signed-off-by: Matt Fleming Reported-by: Kees Cook Acked-by: Kees Cook Cc: Paul Mundt Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/kernel/dumpstack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/dumpstack.c b/arch/sh/kernel/dumpstack.c index b959f5592604..8dfe645bcc4b 100644 --- a/arch/sh/kernel/dumpstack.c +++ b/arch/sh/kernel/dumpstack.c @@ -115,7 +115,7 @@ static int print_trace_stack(void *data, char *name) */ static void print_trace_address(void *data, unsigned long addr, int reliable) { - printk(data); + printk("%s", (char *)data); printk_address(addr, reliable); } -- cgit v1.2.3 From abafe5d9b04648a2f699202e9ae2d15ffe44c3a3 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Thu, 3 Apr 2014 14:46:39 -0700 Subject: sh: push extra copy of r0-r2 for syscall parameters When invoking syscall handlers on sh32, the saved userspace registers are at the top of the stack. This seems to have been intentional, as it is an easy way to pass r0, r1, ... to the handler as parameters 5, 6, ... It causes problems, however, because the compiler is allowed to generate code for a function which clobbers that function's own parameters. For example, gcc generates the following code for clone: : mov.l 8c020714 ,r1 ! 8c020540 mov.l r7,@r15 mov r6,r7 jmp @r1 mov #0,r6 nop .word 0x0540 .word 0x8c02 The `mov.l r7,@r15` clobbers the saved value of r0 passed from userspace. For most system calls, this might not be a problem, because we'll be overwriting r0 with the return value anyway. But in the case of clone, copy_thread will need the original value of r0 if the CLONE_SETTLS flag was specified. The first patch in this series fixes this issue for system calls by pushing to the stack and extra copy of r0-r2 before invoking the handler. We discard this copy before restoring the userspace registers, so it is not a problem if they are clobbered. Exception handlers also receive the userspace register values in a similar manner, and may hit the same problem. The second patch removes the do_fpu_error handler, which looks susceptible to this problem and which, as far as I can tell, has not been used in some time. The third patch addresses other exception handlers. This patch (of 3): The userspace registers are stored at the top of the stack when the syscall handler is invoked, which allows r0-r2 to act as parameters 5-7. Parameters passed on the stack may be clobbered by the syscall handler. The solution is to push an extra copy of the registers which might be used as syscall parameters to the stack, so that the authoritative set of saved register values does not get clobbered. A few system call handlers are also updated to get the userspace registers using current_pt_regs() instead of from the stack. Signed-off-by: Bobby Bingham Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/include/asm/syscalls_32.h | 12 +++--------- arch/sh/kernel/entry-common.S | 15 +++++++++++---- arch/sh/kernel/signal_32.c | 12 ++++-------- arch/sh/kernel/sys_sh32.c | 7 ++----- 4 files changed, 20 insertions(+), 26 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/include/asm/syscalls_32.h b/arch/sh/include/asm/syscalls_32.h index 4f97df87d7d5..4f643aa718e3 100644 --- a/arch/sh/include/asm/syscalls_32.h +++ b/arch/sh/include/asm/syscalls_32.h @@ -9,15 +9,9 @@ struct pt_regs; -asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); -asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs); +asmlinkage int sys_sigreturn(void); +asmlinkage int sys_rt_sigreturn(void); +asmlinkage int sys_sh_pipe(void); asmlinkage ssize_t sys_pread_wrapper(unsigned int fd, char __user *buf, size_t count, long dummy, loff_t pos); asmlinkage ssize_t sys_pwrite_wrapper(unsigned int fd, const char __user *buf, diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index ca46834294b7..13047a4facd2 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -193,10 +193,10 @@ syscall_trace_entry: ! Reload R0-R4 from kernel stack, where the ! parent may have modified them using ! ptrace(POKEUSR). (Note that R0-R2 are - ! used by the system call handler directly - ! from the kernel stack anyway, so don't need - ! to be reloaded here.) This allows the parent - ! to rewrite system calls and args on the fly. + ! reloaded from the kernel stack by syscall_call + ! below, so don't need to be reloaded here.) + ! This allows the parent to rewrite system calls + ! and args on the fly. mov.l @(OFF_R4,r15), r4 ! arg0 mov.l @(OFF_R5,r15), r5 mov.l @(OFF_R6,r15), r6 @@ -357,8 +357,15 @@ syscall_call: mov.l 3f, r8 ! Load the address of sys_call_table add r8, r3 mov.l @r3, r8 + mov.l @(OFF_R2,r15), r2 + mov.l @(OFF_R1,r15), r1 + mov.l @(OFF_R0,r15), r0 + mov.l r2, @-r15 + mov.l r1, @-r15 + mov.l r0, @-r15 jsr @r8 ! jump to specific syscall handler nop + add #12, r15 mov.l @(OFF_R0,r15), r12 ! save r0 mov.l r0, @(OFF_R0,r15) ! save the return value ! diff --git a/arch/sh/kernel/signal_32.c b/arch/sh/kernel/signal_32.c index 6af6e7c5cac8..594cd371aa28 100644 --- a/arch/sh/kernel/signal_32.c +++ b/arch/sh/kernel/signal_32.c @@ -148,11 +148,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *r0_p return err; } -asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage int sys_sigreturn(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *regs = current_pt_regs(); struct sigframe __user *frame = (struct sigframe __user *)regs->regs[15]; sigset_t set; int r0; @@ -180,11 +178,9 @@ badframe: return 0; } -asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage int sys_rt_sigreturn(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); + struct pt_regs *regs = current_pt_regs(); struct rt_sigframe __user *frame = (struct rt_sigframe __user *)regs->regs[15]; sigset_t set; int r0; diff --git a/arch/sh/kernel/sys_sh32.c b/arch/sh/kernel/sys_sh32.c index 497bab3a0401..b66d1c62eb19 100644 --- a/arch/sh/kernel/sys_sh32.c +++ b/arch/sh/kernel/sys_sh32.c @@ -21,17 +21,14 @@ * sys_pipe() is the normal C calling standard for creating * a pipe. It's not the way Unix traditionally does this, though. */ -asmlinkage int sys_sh_pipe(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage int sys_sh_pipe(void) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); int fd[2]; int error; error = do_pipe_flags(fd, 0); if (!error) { - regs->regs[1] = fd[1]; + current_pt_regs()->regs[1] = fd[1]; return fd[0]; } return error; -- cgit v1.2.3 From 7caf62de25554da3af00c92c11afa95dcc3592c4 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Thu, 3 Apr 2014 14:46:40 -0700 Subject: sh: remove unused do_fpu_error This does not appear to have been used since commit 74d99a5e2622 ("sh: SH-2A FPU support") in 2007. Signed-off-by: Bobby Bingham Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/math-emu/math.c | 18 ------------------ 1 file changed, 18 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/math-emu/math.c b/arch/sh/math-emu/math.c index b876780c1e1c..04aa55fa8c75 100644 --- a/arch/sh/math-emu/math.c +++ b/arch/sh/math-emu/math.c @@ -574,24 +574,6 @@ static int ieee_fpe_handler(struct pt_regs *regs) return 0; } -asmlinkage void do_fpu_error(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs regs) -{ - struct task_struct *tsk = current; - siginfo_t info; - - if (ieee_fpe_handler (®s)) - return; - - regs.pc += 2; - info.si_signo = SIGFPE; - info.si_errno = 0; - info.si_code = FPE_FLTINV; - info.si_addr = (void __user *)regs.pc; - force_sig_info(SIGFPE, &info, tsk); -} - /** * fpu_init - Initialize FPU registers * @fpu: Pointer to software emulated FPU registers. -- cgit v1.2.3 From a3c195144e162097c42e4284323ed6d386de105d Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Thu, 3 Apr 2014 14:46:41 -0700 Subject: 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 Cc: Paul Mundt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/include/asm/traps_32.h | 16 ++++------------ arch/sh/kernel/traps_32.c | 23 +++++++---------------- 2 files changed, 11 insertions(+), 28 deletions(-) (limited to 'arch/sh') 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) 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, \ 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) #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) -- cgit v1.2.3 From f0767e897816c82cdb27058bd3be76442b7b5b10 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Thu, 3 Apr 2014 14:46:42 -0700 Subject: arch/sh/boards/board-sh7757lcr.c: fixup SDHI register size sh7757lcr SDHI register size is 0x100 Signed-off-by: Kuninori Morimoto Cc: Simon Horman Cc: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/boards/board-sh7757lcr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index 25c5a932f9fe..669df51a82e3 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c @@ -252,7 +252,7 @@ static struct sh_mobile_sdhi_info sdhi_info = { static struct resource sdhi_resources[] = { [0] = { .start = 0xffe50000, - .end = 0xffe501ff, + .end = 0xffe500ff, .flags = IORESOURCE_MEM, }, [1] = { -- cgit v1.2.3 From ba6e8b8f02e0431550e9e3c12cbc7dd2d1e14534 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 3 Apr 2014 14:46:43 -0700 Subject: sh: sh7757: switch RSPI clock to dev ID match Switch the RSPI MSTP clock on SH7757 from a con ID match to a dev ID match, so we can start looking it up using clk_get() with a NULL ID. Signed-off-by: Geert Uytterhoeven Tested-by: Yoshihiro Shimoda Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/kernel/cpu/sh4a/clock-sh7757.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/sh') diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c index e84a43229b9c..5c0e3c335161 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7757.c @@ -132,7 +132,7 @@ static struct clk_lookup lookups[] = { CLKDEV_CON_ID("usb_fck", &mstp_clks[MSTP103]), CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP102]), CLKDEV_CON_ID("mmc0", &mstp_clks[MSTP220]), - CLKDEV_CON_ID("rspi2", &mstp_clks[MSTP127]), + CLKDEV_DEV_ID("rspi.2", &mstp_clks[MSTP127]), }; int __init arch_clk_init(void) -- cgit v1.2.3 From 0c3d1d62f99b3c83b0c0a0f306b78e65d49fda30 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Thu, 3 Apr 2014 14:46:44 -0700 Subject: arch/sh/drivers/pci/pcie-sh7786.h: remove duplicate SH4A_PCIEPHYCTLR Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sh/drivers/pci/pcie-sh7786.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'arch/sh') diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index 1ee054e47eae..4a6ff55f759b 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h @@ -145,9 +145,6 @@ /* PCIERMSGIER */ #define SH4A_PCIERMSGIER (0x004040) /* R/W - 0x0000 0000 32 */ -/* PCIEPHYCTLR */ -#define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */ - /* PCIEPHYADRR */ #define SH4A_PCIEPHYADRR (0x010004) /* R/W - 0x0000 0000 32 */ #define BITS_ACK (24) // Rev1.171 -- cgit v1.2.3