04 Apr, 2014

1 commit

  • 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

    Bobby Bingham
     

23 Oct, 2012

1 commit


18 Aug, 2010

1 commit

  • Make do_execve() take a const filename pointer so that kernel_execve() compiles
    correctly on ARM:

    arch/arm/kernel/sys_arm.c:88: warning: passing argument 1 of 'do_execve' discards qualifiers from pointer target type

    This also requires the argv and envp arguments to be consted twice, once for
    the pointer array and once for the strings the array points to. This is
    because do_execve() passes a pointer to the filename (now const) to
    copy_strings_kernel(). A simpler alternative would be to cast the filename
    pointer in do_execve() when it's passed to copy_strings_kernel().

    do_execve() may not change any of the strings it is passed as part of the argv
    or envp lists as they are some of them in .rodata, so marking these strings as
    const should be fine.

    Further kernel_execve() and sys_execve() need to be changed to match.

    This has been test built on x86_64, frv, arm and mips.

    Signed-off-by: David Howells
    Tested-by: Ralf Baechle
    Acked-by: Russell King
    Signed-off-by: Linus Torvalds

    David Howells
     

24 Sep, 2009

1 commit

  • * remove asm/atomic.h inclusion from linux/utsname.h --
    not needed after kref conversion
    * remove linux/utsname.h inclusion from files which do not need it

    NOTE: it looks like fs/binfmt_elf.c do not need utsname.h, however
    due to some personality stuff it _is_ needed -- cowardly leave ELF-related
    headers and files alone.

    Signed-off-by: Alexey Dobriyan
    Signed-off-by: Linus Torvalds

    Alexey Dobriyan
     

14 Jan, 2009

1 commit


08 Sep, 2008

1 commit


25 Jul, 2008

1 commit

  • This patch introduces the new syscall pipe2 which is like pipe but it also
    takes an additional parameter which takes a flag value. This patch implements
    the handling of O_CLOEXEC for the flag. I did not add support for the new
    syscall for the architectures which have a special sys_pipe implementation. I
    think the maintainers of those archs have the chance to go with the unified
    implementation but that's up to them.

    The implementation introduces do_pipe_flags. I did that instead of changing
    all callers of do_pipe because some of the callers are written in assembler.
    I would probably screw up changing the assembly code. To avoid breaking code
    do_pipe is now a small wrapper around do_pipe_flags. Once all callers are
    changed over to do_pipe_flags the old do_pipe function can be removed.

    The following test must be adjusted for architectures other than x86 and
    x86-64 and in case the syscall numbers changed.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #include
    #include
    #include
    #include

    #ifndef __NR_pipe2
    # ifdef __x86_64__
    # define __NR_pipe2 293
    # elif defined __i386__
    # define __NR_pipe2 331
    # else
    # error "need __NR_pipe2"
    # endif
    #endif

    int
    main (void)
    {
    int fd[2];
    if (syscall (__NR_pipe2, fd, 0) != 0)
    {
    puts ("pipe2(0) failed");
    return 1;
    }
    for (int i = 0; i < 2; ++i)
    {
    int coe = fcntl (fd[i], F_GETFD);
    if (coe == -1)
    {
    puts ("fcntl failed");
    return 1;
    }
    if (coe & FD_CLOEXEC)
    {
    printf ("pipe2(0) set close-on-exit for fd[%d]\n", i);
    return 1;
    }
    }
    close (fd[0]);
    close (fd[1]);

    if (syscall (__NR_pipe2, fd, O_CLOEXEC) != 0)
    {
    puts ("pipe2(O_CLOEXEC) failed");
    return 1;
    }
    for (int i = 0; i < 2; ++i)
    {
    int coe = fcntl (fd[i], F_GETFD);
    if (coe == -1)
    {
    puts ("fcntl failed");
    return 1;
    }
    if ((coe & FD_CLOEXEC) == 0)
    {
    printf ("pipe2(O_CLOEXEC) does not set close-on-exit for fd[%d]\n", i);
    return 1;
    }
    }
    close (fd[0]);
    close (fd[1]);

    puts ("OK");

    return 0;
    }
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Signed-off-by: Ulrich Drepper
    Acked-by: Davide Libenzi
    Cc: Michael Kerrisk
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ulrich Drepper
     

28 Jan, 2008

1 commit