16 Nov, 2011

1 commit

  • As per the comments added by this commit, %g2 turns out to not be a
    usable place to save away orig_i0 for syscall restart handling.

    In fact all of %g2, %g3, %g4, and %g5 are assumed to be saved across
    a system call by various bits of code in glibc.

    %g1 can't be used because that holds the syscall number, which would
    need to be saved and restored for syscall restart handling too, and
    that would only compound our problems :-)

    This leaves us with %g6 and %g7 which are for "system use". %g7 is
    used as the "thread register" by glibc, but %g6 is used as a compiler
    and assembler temporary scratch register. And in no instance is %g6
    used to hold a value across a system call.

    Therefore %g6 is safe for storing away orig_i0, at least for now.

    Signed-off-by: David S. Miller

    David S. Miller
     

15 Nov, 2011

1 commit

  • Although we provide a proper way for a debugger to control whether
    syscall restart occurs, we run into problems because orig_i0 is not
    saved and restored properly.

    Luckily we can solve this problem without having to make debuggers
    aware of the issue. Across system calls, several registers are
    considered volatile and can be safely clobbered.

    Therefore we use the pt_regs save area of one of those registers, %g2,
    as a place to save and restore orig_i0.

    Debuggers transparently will do the right thing because they save and
    restore this register already.

    Signed-off-by: David S. Miller

    David S. Miller
     

13 Oct, 2011

2 commits


21 Aug, 2011

1 commit

  • If we can't push the pending register windows onto the user's stack,
    we disallow signal delivery even if the signal would be delivered on a
    valid seperate signal stack.

    Add a register window save area in the signal frame, and store any
    unsavable windows there.

    On sigreturn, if any windows are still queued up in the signal frame,
    try to push them back onto the stack and if that fails we kill the
    process immediately.

    This allows the debug/tst-longjmp_chk2 glibc test case to pass.

    Signed-off-by: David S. Miller

    David S. Miller
     

22 Sep, 2010

2 commits


10 Feb, 2010

1 commit


02 Sep, 2009

1 commit

  • Add a keyctl to install a process's session keyring onto its parent. This
    replaces the parent's session keyring. Because the COW credential code does
    not permit one process to change another process's credentials directly, the
    change is deferred until userspace next starts executing again. Normally this
    will be after a wait*() syscall.

    To support this, three new security hooks have been provided:
    cred_alloc_blank() to allocate unset security creds, cred_transfer() to fill in
    the blank security creds and key_session_to_parent() - which asks the LSM if
    the process may replace its parent's session keyring.

    The replacement may only happen if the process has the same ownership details
    as its parent, and the process has LINK permission on the session keyring, and
    the session keyring is owned by the process, and the LSM permits it.

    Note that this requires alteration to each architecture's notify_resume path.
    This has been done for all arches barring blackfin, m68k* and xtensa, all of
    which need assembly alteration to support TIF_NOTIFY_RESUME. This allows the
    replacement to be performed at the point the parent process resumes userspace
    execution.

    This allows the userspace AFS pioctl emulation to fully emulate newpag() and
    the VIOCSETTOK and VIOCSETTOK2 pioctls, all of which require the ability to
    alter the parent process's PAG membership. However, since kAFS doesn't use
    PAGs per se, but rather dumps the keys into the session keyring, the session
    keyring of the parent must be replaced if, for example, VIOCSETTOK is passed
    the newpag flag.

    This can be tested with the following program:

    #include
    #include
    #include

    #define KEYCTL_SESSION_TO_PARENT 18

    #define OSERROR(X, S) do { if ((long)(X) == -1) { perror(S); exit(1); } } while(0)

    int main(int argc, char **argv)
    {
    key_serial_t keyring, key;
    long ret;

    keyring = keyctl_join_session_keyring(argv[1]);
    OSERROR(keyring, "keyctl_join_session_keyring");

    key = add_key("user", "a", "b", 1, keyring);
    OSERROR(key, "add_key");

    ret = keyctl(KEYCTL_SESSION_TO_PARENT);
    OSERROR(ret, "KEYCTL_SESSION_TO_PARENT");

    return 0;
    }

    Compiled and linked with -lkeyutils, you should see something like:

    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: _ses
    355907932 --alswrv 4043 -1 \_ keyring: _uid.4043
    [dhowells@andromeda ~]$ /tmp/newpag
    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: _ses
    1055658746 --alswrv 4043 4043 \_ user: a
    [dhowells@andromeda ~]$ /tmp/newpag hello
    [dhowells@andromeda ~]$ keyctl show
    Session Keyring
    -3 --alswrv 4043 4043 keyring: hello
    340417692 --alswrv 4043 4043 \_ user: a

    Where the test program creates a new session keyring, sticks a user key named
    'a' into it and then installs it on its parent.

    Signed-off-by: David Howells
    Signed-off-by: James Morris

    David Howells
     

05 Dec, 2008

1 commit

  • o Move all files from sparc64/kernel/ to sparc/kernel
    - rename as appropriate
    o Update sparc/Makefile to the changes
    o Update sparc/kernel/Makefile to include the sparc64 files

    NOTE: This commit changes link order on sparc64!

    Link order had to change for either of sparc32 and sparc64.
    And assuming sparc64 see more testing than sparc32 change link
    order on sparc64 where issues will be caught faster.

    Signed-off-by: Sam Ravnborg
    Signed-off-by: David S. Miller

    Sam Ravnborg