• Bobby Bingham's avatar
    sh: push extra copy of r0-r2 for syscall parameters · abafe5d9
    Bobby Bingham authored
    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:
    
        <SyS_clone>:
            mov.l   8c020714 <SyS_clone+0xc>,r1  ! 8c020540 <do_fork>
            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: default avatarBobby Bingham <koorogi@koorogi.info>
    Cc: Paul Mundt <paul.mundt@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    abafe5d9
signal_32.c 13.9 KB