24 Sep, 2009

4 commits

  • __fatal_signal_pending inlines to one instruction on x86, probably two
    instructions on other machines. It takes two longer x86 instructions just
    to call it and test its return value, not to mention the function itself.

    On my random x86_64 config, this saved 70 bytes of text (59 of those being
    __fatal_signal_pending itself).

    Signed-off-by: Roland McGrath
    Cc: Oleg Nesterov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Roland McGrath
     
  • Introduce do_send_sig_info() and convert group_send_sig_info(),
    send_sig_info(), do_send_specific() to use this helper.

    Hopefully it will have more users soon, it allows to specify
    specific/group behaviour via "bool group" argument.

    Shaves 80 bytes from .text.

    Signed-off-by: Oleg Nesterov
    Cc: Peter Zijlstra
    Cc: stephane eranian
    Cc: Ingo Molnar
    Cc: Roland McGrath
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     
  • This changes tracehook_notify_jctl() so it's called with the siglock held,
    and changes its argument and return value definition. These clean-ups
    make it a better fit for what new tracing hooks need to check.

    Tracing needs the siglock here, held from the time TASK_STOPPED was set,
    to avoid potential SIGCONT races if it wants to allow any blocking in its
    tracing hooks.

    This also folds the finish_stop() function into its caller
    do_signal_stop(). The function is short, called only once and only
    unconditionally. It aids readability to fold it in.

    [oleg@redhat.com: do not call tracehook_notify_jctl() in TASK_STOPPED state]
    [oleg@redhat.com: introduce tracehook_finish_jctl() helper]
    Signed-off-by: Roland McGrath
    Signed-off-by: Oleg Nesterov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Roland McGrath
     
  • The bug is old, it wasn't cause by recent changes.

    Test case:

    static void *tfunc(void *arg)
    {
    int pid = (long)arg;

    assert(ptrace(PTRACE_ATTACH, pid, NULL, NULL) == 0);
    kill(pid, SIGKILL);

    sleep(1);
    return NULL;
    }

    int main(void)
    {
    pthread_t th;
    long pid = fork();

    if (!pid)
    pause();

    signal(SIGCHLD, SIG_IGN);
    assert(pthread_create(&th, NULL, tfunc, (void*)pid) == 0);

    int r = waitpid(-1, NULL, __WNOTHREAD);
    printf("waitpid: %d %m\n", r);

    return 0;
    }

    Before the patch this program hangs, after this patch waitpid() correctly
    fails with errno == -ECHILD.

    The problem is, __ptrace_detach() reaps the EXIT_ZOMBIE tracee if its
    ->real_parent is our sub-thread and we ignore SIGCHLD. But in this case
    we should wake up other threads which can sleep in do_wait().

    Signed-off-by: Oleg Nesterov
    Cc: Roland McGrath
    Cc: Vitaly Mayatskikh
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     

02 Aug, 2009

2 commits

  • The previous commit ("do_sigaltstack: avoid copying 'stack_t' as a
    structure to user space") fixed a real bug. This one just cleans up the
    copy from user space to that gcc can generate better code for it (and so
    that it looks the same as the later copy back to user space).

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     
  • Ulrich Drepper correctly points out that there is generally padding in
    the structure on 64-bit hosts, and that copying the structure from
    kernel to user space can leak information from the kernel stack in those
    padding bytes.

    Avoid the whole issue by just copying the three members one by one
    instead, which also means that the function also can avoid the need for
    a stack frame. This also happens to match how we copy the new structure
    from user space, so it all even makes sense.

    [ The obvious solution of adding a memset() generates horrid code, gcc
    does really stupid things. ]

    Reported-by: Ulrich Drepper
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

19 Jun, 2009

2 commits

  • If the non-traced sub-thread calls do_notify_parent_cldstop(), we send the
    notification to group_leader->real_parent and we report group_leader's
    pid.

    But, if group_leader is traced we use the wrong ->parent->nsproxy->pid_ns,
    the tracer and parent can live in different namespaces. Change the code
    to use "parent" instead of tsk->parent.

    Signed-off-by: Oleg Nesterov
    Acked-by: Roland McGrath
    Acked-by: Sukadev Bhattiprolu
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     
  • No functional changes.

    - Nobody except ptrace.c & co should use ptrace flags directly, we have
    task_ptrace() for that.

    - No need to specially check PT_PTRACED, we must not have other PT_ bits
    set without PT_PTRACED. And no need to know this flag exists.

    Signed-off-by: Oleg Nesterov
    Cc: Roland McGrath
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     

15 Jun, 2009

1 commit

  • This false positive is due to field padding in struct sigqueue. When
    this dynamically allocated structure is copied to the stack (in arch-
    specific delivery code), kmemcheck sees a read from the padding, which
    is, naturally, uninitialized.

    Hide the false positive using the __GFP_NOTRACK_FALSE_POSITIVE flag.
    Also made the rlimit override code a bit clearer by introducing a new
    variable.

    Cc: Oleg Nesterov
    Signed-off-by: Vegard Nossum

    Vegard Nossum
     

12 Jun, 2009

1 commit

  • …s/security-testing-2.6

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (44 commits)
    nommu: Provide mmap_min_addr definition.
    TOMOYO: Add description of lists and structures.
    TOMOYO: Remove unused field.
    integrity: ima audit dentry_open failure
    TOMOYO: Remove unused parameter.
    security: use mmap_min_addr indepedently of security models
    TOMOYO: Simplify policy reader.
    TOMOYO: Remove redundant markers.
    SELinux: define audit permissions for audit tree netlink messages
    TOMOYO: Remove unused mutex.
    tomoyo: avoid get+put of task_struct
    smack: Remove redundant initialization.
    integrity: nfsd imbalance bug fix
    rootplug: Remove redundant initialization.
    smack: do not beyond ARRAY_SIZE of data
    integrity: move ima_counts_get
    integrity: path_check update
    IMA: Add __init notation to ima functions
    IMA: Minimal IMA policy and boot param for TCB IMA policy
    selinux: remove obsolete read buffer limit from sel_read_bool
    ...

    Linus Torvalds
     

11 Jun, 2009

1 commit

  • * 'tracing-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (244 commits)
    Revert "x86, bts: reenable ptrace branch trace support"
    tracing: do not translate event helper macros in print format
    ftrace/documentation: fix typo in function grapher name
    tracing/events: convert block trace points to TRACE_EVENT(), fix !CONFIG_BLOCK
    tracing: add protection around module events unload
    tracing: add trace_seq_vprint interface
    tracing: fix the block trace points print size
    tracing/events: convert block trace points to TRACE_EVENT()
    ring-buffer: fix ret in rb_add_time_stamp
    ring-buffer: pass in lockdep class key for reader_lock
    tracing: add annotation to what type of stack trace is recorded
    tracing: fix multiple use of __print_flags and __print_symbolic
    tracing/events: fix output format of user stack
    tracing/events: fix output format of kernel stack
    tracing/trace_stack: fix the number of entries in the header
    ring-buffer: discard timestamps that are at the start of the buffer
    ring-buffer: try to discard unneeded timestamps
    ring-buffer: fix bug in ring_buffer_discard_commit
    ftrace: do not profile functions when disabled
    tracing: make trace pipe recognize latency format flag
    ...

    Linus Torvalds
     

08 May, 2009

1 commit


01 May, 2009

2 commits

  • sys_kill has the per thread counterpart sys_tgkill. sigqueueinfo is
    missing a thread directed counterpart. Such an interface is important
    for migrating applications from other OSes which have the per thread
    delivery implemented.

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Oleg Nesterov
    Acked-by: Roland McGrath
    Acked-by: Ulrich Drepper

    Thomas Gleixner
     
  • Split out the code from do_tkill to make it reusable by the follow up
    patch which implements sys_rt_tgsigqueueinfo

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Oleg Nesterov

    Thomas Gleixner
     

30 Apr, 2009

1 commit

  • Don't flush inherited SIGKILL during execve() in SELinux's post cred commit
    hook. This isn't really a security problem: if the SIGKILL came before the
    credentials were changed, then we were right to receive it at the time, and
    should honour it; if it came after the creds were changed, then we definitely
    should honour it; and in any case, all that will happen is that the process
    will be scrapped before it ever returns to userspace.

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

    David Howells
     

15 Apr, 2009

2 commits

  • Impact: clean up

    Create a sub directory in include/trace called events to keep the
    trace point headers in their own separate directory. Only headers that
    declare trace points should be defined in this directory.

    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Neil Horman
    Cc: Zhao Lei
    Cc: Eduard - Gabriel Munteanu
    Cc: Pekka Enberg
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     
  • This patch lowers the number of places a developer must modify to add
    new tracepoints. The current method to add a new tracepoint
    into an existing system is to write the trace point macro in the
    trace header with one of the macros TRACE_EVENT, TRACE_FORMAT or
    DECLARE_TRACE, then they must add the same named item into the C file
    with the macro DEFINE_TRACE(name) and then add the trace point.

    This change cuts out the needing to add the DEFINE_TRACE(name).
    Every file that uses the tracepoint must still include the trace/.h
    file, but the one C file must also add a define before the including
    of that file.

    #define CREATE_TRACE_POINTS
    #include

    This will cause the trace/mytrace.h file to also produce the C code
    necessary to implement the trace point.

    Note, if more than one trace/.h is used to create the C code
    it is best to list them all together.

    #define CREATE_TRACE_POINTS
    #include
    #include
    #include

    Thanks to Mathieu Desnoyers and Christoph Hellwig for coming up with
    the cleaner solution of the define above the includes over my first
    design to have the C code include a "special" header.

    This patch converts sched, irq and lockdep and skb to use this new
    method.

    Cc: Peter Zijlstra
    Cc: Thomas Gleixner
    Cc: Neil Horman
    Cc: Zhao Lei
    Cc: Eduard - Gabriel Munteanu
    Cc: Pekka Enberg
    Signed-off-by: Steven Rostedt

    Steven Rostedt
     

03 Apr, 2009

6 commits

  • When sending a signal to a descendant namespace, set ->si_pid to 0 since
    the sender does not have a pid in the receiver's namespace.

    Note:
    - If rt_sigqueueinfo() sets si_code to SI_USER when sending a
    signal across a pid namespace boundary, the value in ->si_pid
    will be cleared to 0.

    Signed-off-by: Sukadev Bhattiprolu
    Cc: Oleg Nesterov
    Cc: Roland McGrath
    Cc: "Eric W. Biederman"
    Cc: Daniel Lezcano
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sukadev Bhattiprolu
     
  • Normally SIG_DFL signals to global and container-init are dropped early.
    But if a signal is blocked when it is posted, we cannot drop the signal
    since the receiver may install a handler before unblocking the signal.
    Once this signal is queued however, the receiver container-init has no way
    of knowing if the signal was sent from an ancestor or descendant
    namespace. This patch ensures that contianer-init drops all SIG_DFL
    signals in get_signal_to_deliver() except SIGKILL/SIGSTOP.

    If SIGSTOP/SIGKILL originate from a descendant of container-init they are
    never queued (i.e dropped in sig_ignored() in an earler patch).

    If SIGSTOP/SIGKILL originate from parent namespace, the signal is queued
    and container-init processes the signal.

    IOW, if get_signal_to_deliver() sees a sig_kernel_only() signal for global
    or container-init, the signal must have been generated internally or must
    have come from an ancestor ns and we process the signal.

    Further, the signal_group_exit() check was needed to cover the case of a
    multi-threaded init sending SIGKILL to other threads when doing an exit()
    or exec(). But since the new sig_kernel_only() check covers the SIGKILL,
    the signal_group_exit() check is no longer needed and can be removed.

    Finally, now that we have all pieces in place, set SIGNAL_UNKILLABLE for
    container-inits.

    Signed-off-by: Sukadev Bhattiprolu
    Cc: Oleg Nesterov
    Cc: Roland McGrath
    Cc: "Eric W. Biederman"
    Cc: Daniel Lezcano
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sukadev Bhattiprolu
     
  • Drop early any SIG_DFL or SIG_IGN signals to container-init from within
    the same container. But queue SIGSTOP and SIGKILL to the container-init
    if they are from an ancestor container.

    Blocked, fatal signals (i.e when SIG_DFL is to terminate) from within the
    container can still terminate the container-init. That will be addressed
    in the next patch.

    Note: To be bisect-safe, SIGNAL_UNKILLABLE will be set for container-inits
    in a follow-on patch. Until then, this patch is just a preparatory
    step.

    Signed-off-by: Sukadev Bhattiprolu
    Cc: Oleg Nesterov
    Cc: Roland McGrath
    Cc: "Eric W. Biederman"
    Cc: Daniel Lezcano
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sukadev Bhattiprolu
     
  • send_signal() (or its helper) needs to determine the pid namespace of the
    sender. But a signal sent via kill_pid_info_as_uid() comes from within
    the kernel and send_signal() does not need to determine the pid namespace
    of the sender. So define a helper for send_signal() which takes an
    additional parameter, 'from_ancestor_ns' and have kill_pid_info_as_uid()
    use that helper directly.

    The 'from_ancestor_ns' parameter will be used in a follow-on patch.

    Signed-off-by: Sukadev Bhattiprolu
    Cc: Oleg Nesterov
    Cc: Roland McGrath
    Cc: "Eric W. Biederman"
    Cc: Daniel Lezcano
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sukadev Bhattiprolu
     
  • (This is a modified version of the patch submitted by Oleg Nesterov
    http://lkml.org/lkml/2008/11/18/249 and tries to address comments that
    came up in that discussion)

    init ignores the SIG_DFL signals but we queue them anyway, including
    SIGKILL. This is mostly OK, the signal will be dropped silently when
    dequeued, but the pending SIGKILL has 2 bad implications:

    - it implies fatal_signal_pending(), so we confuse things
    like wait_for_completion_killable/lock_page_killable.

    - for the sub-namespace inits, the pending SIGKILL can
    mask (legacy_queue) the subsequent SIGKILL from the
    parent namespace which must kill cinit reliably.
    (preparation, cinits don't have SIGNAL_UNKILLABLE yet)

    The patch can't help when init is ptraced, but ptracing of init is not
    "safe" anyway.

    Signed-off-by: Sukadev Bhattiprolu
    Acked-by: Roland McGrath
    Signed-off-by: Oleg Nesterov
    Cc: "Eric W. Biederman"
    Cc: Daniel Lezcano
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     
  • Container-init must behave like global-init to processes within the
    container and hence it must be immune to unhandled fatal signals from
    within the container (i.e SIG_DFL signals that terminate the process).

    But the same container-init must behave like a normal process to processes
    in ancestor namespaces and so if it receives the same fatal signal from a
    process in ancestor namespace, the signal must be processed.

    Implementing these semantics requires that send_signal() determine pid
    namespace of the sender but since signals can originate from workqueues/
    interrupt-handlers, determining pid namespace of sender may not always be
    possible or safe.

    This patchset implements the design/simplified semantics suggested by
    Oleg Nesterov. The simplified semantics for container-init are:

    - container-init must never be terminated by a signal from a
    descendant process.

    - container-init must never be immune to SIGKILL from an ancestor
    namespace (so a process in parent namespace must always be able
    to terminate a descendant container).

    - container-init may be immune to unhandled fatal signals (like
    SIGUSR1) even if they are from ancestor namespace. SIGKILL/SIGSTOP
    are the only reliable signals to a container-init from ancestor
    namespace.

    This patch:

    Based on an earlier patch submitted by Oleg Nesterov and comments from
    Roland McGrath (http://lkml.org/lkml/2008/11/19/258).

    The handler parameter is currently unused in the tracehook functions.
    Besides, the tracehook functions are called with siglock held, so the
    functions can check the handler if they later need to.

    Removing the parameter simiplifies changes to sig_ignored() in a follow-on
    patch.

    Signed-off-by: Sukadev Bhattiprolu
    Acked-by: Roland McGrath
    Signed-off-by: Oleg Nesterov
    Cc: "Eric W. Biederman"
    Cc: Daniel Lezcano
    Cc: Ingo Molnar
    Cc: Thomas Gleixner
    Cc: "H. Peter Anvin"
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     

24 Mar, 2009

1 commit

  • This patch fixes bug #12208:

    Bug-Entry : http://bugzilla.kernel.org/show_bug.cgi?id=12208
    Subject : uml is very slow on 2.6.28 host

    This turned out to be not a scheduler regression, but an already
    existing problem in ptrace being triggered by subtle scheduler
    changes.

    The problem is this:

    - task A is ptracing task B
    - task B stops on a trace event
    - task A is woken up and preempts task B
    - task A calls ptrace on task B, which does ptrace_check_attach()
    - this calls wait_task_inactive(), which sees that task B is still on the runq
    - task A goes to sleep for a jiffy
    - ...

    Since UML does lots of the above sequences, those jiffies quickly add
    up to make it slow as hell.

    This patch solves this by not rescheduling in read_unlock() after
    ptrace_stop() has woken up the tracer.

    Thanks to Oleg Nesterov and Ingo Molnar for the feedback.

    Signed-off-by: Miklos Szeredi
    CC: stable@kernel.org
    Signed-off-by: Linus Torvalds

    Miklos Szeredi
     

05 Feb, 2009

1 commit

  • We're going to split the process wide cpu accounting into two parts:

    - clocks; which can take all the time they want since they run
    from user context.

    - timers; which need constant time tracing but can affort the overhead
    because they're default off -- and rare.

    The clock readout will go back to a full sum of the thread group, for this
    we need to re-add the exit stats that were removed in the initial itimer
    rework (f06febc9: timers: fix itimer/many thread hang).

    Furthermore, since that full sum can be rather slow for large thread groups
    and we have the complete dead task stats, revert the do_notify_parent time
    computation.

    Signed-off-by: Peter Zijlstra
    Reviewed-by: Ingo Molnar
    Signed-off-by: Ingo Molnar

    Peter Zijlstra
     

27 Jan, 2009

1 commit

  • With print-fatal-signals=1 on a kernel with CONFIG_PREEMPT=y, sending an
    unexpected signal to a process causes a BUG: using smp_processor_id() in
    preemptible code.

    get_signal_to_deliver() releases the siglock before calling
    print_fatal_signal(), which calls show_regs(), which calls
    smp_processor_id(), which is not supposed to be called from a
    preemptible thread.

    Make sure show_regs() runs with preemption disabled.

    Signed-off-by: Ed Swierk
    Signed-off-by: Ingo Molnar

    Ed Swierk
     

14 Jan, 2009

6 commits


07 Jan, 2009

2 commits

  • POSIX requires the si_pid to be the process id of the sender, so ->si_pid
    should really be set to 'tgid'. This change does have following changes
    in behavior:

    - When sending pdeath_signal on re-parent to a sub-thread, ->si_pid
    cannot be used to identify the thread that did the re-parent since
    it will now show the tgid instead of thread id.

    - A multi-threaded application that expects to find the specific
    thread that encountered a SIGPIPE using the ->si_pid will now
    break.

    Signed-off-by: Sukadev Bhattiprolu
    Acked-By: Roland McGrath
    Cc: "Eric W. Biederman"
    Cc: Oleg Nesterov
    Cc: Pavel Emelyanov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sukadev Bhattiprolu
     
  • For SEND_SIG_NOINFO, si_pid is currently set to the pid of sender
    in sender's active pid namespace. But if the receiver is in a
    Eg: when parent sends the 'pdeath_signal' to a child that is in
    a descendant pid namespace, we should set si_pid 0.

    Signed-off-by: Sukadev Bhattiprolu
    Acked-By: Roland McGrath
    Cc: "Eric W. Biederman"
    Cc: Oleg Nesterov
    Cc: Pavel Emelyanov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sukadev Bhattiprolu
     

29 Dec, 2008

1 commit

  • …el/git/tip/linux-2.6-tip

    * 'tracing-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (241 commits)
    sched, trace: update trace_sched_wakeup()
    tracing/ftrace: don't trace on early stage of a secondary cpu boot, v3
    Revert "x86: disable X86_PTRACE_BTS"
    ring-buffer: prevent false positive warning
    ring-buffer: fix dangling commit race
    ftrace: enable format arguments checking
    x86, bts: memory accounting
    x86, bts: add fork and exit handling
    ftrace: introduce tracing_reset_online_cpus() helper
    tracing: fix warnings in kernel/trace/trace_sched_switch.c
    tracing: fix warning in kernel/trace/trace.c
    tracing/ring-buffer: remove unused ring_buffer size
    trace: fix task state printout
    ftrace: add not to regex on filtering functions
    trace: better use of stack_trace_enabled for boot up code
    trace: add a way to enable or disable the stack tracer
    x86: entry_64 - introduce FTRACE_ frame macro v2
    tracing/ftrace: add the printk-msg-only option
    tracing/ftrace: use preempt_enable_no_resched_notrace in ring_buffer_time_stamp()
    x86, bts: correctly report invalid bts records
    ...

    Fixed up trivial conflict in scripts/recordmcount.pl due to SH bits
    being already partly merged by the SH merge.

    Linus Torvalds
     

16 Nov, 2008

1 commit

  • Impact: API *CHANGE*. Must update all tracepoint users.

    Add DEFINE_TRACE() to tracepoints to let them declare the tracepoint
    structure in a single spot for all the kernel. It helps reducing memory
    consumption, especially when declaring a lot of tracepoints, e.g. for
    kmalloc tracing.

    *API CHANGE WARNING*: now, DECLARE_TRACE() must be used in headers for
    tracepoint declarations rather than DEFINE_TRACE(). This is the sane way
    to do it. The name previously used was misleading.

    Updates scheduler instrumentation to follow this API change.

    Signed-off-by: Mathieu Desnoyers
    Signed-off-by: Ingo Molnar

    Mathieu Desnoyers
     

14 Nov, 2008

4 commits

  • Inaugurate copy-on-write credentials management. This uses RCU to manage the
    credentials pointer in the task_struct with respect to accesses by other tasks.
    A process may only modify its own credentials, and so does not need locking to
    access or modify its own credentials.

    A mutex (cred_replace_mutex) is added to the task_struct to control the effect
    of PTRACE_ATTACHED on credential calculations, particularly with respect to
    execve().

    With this patch, the contents of an active credentials struct may not be
    changed directly; rather a new set of credentials must be prepared, modified
    and committed using something like the following sequence of events:

    struct cred *new = prepare_creds();
    int ret = blah(new);
    if (ret < 0) {
    abort_creds(new);
    return ret;
    }
    return commit_creds(new);

    There are some exceptions to this rule: the keyrings pointed to by the active
    credentials may be instantiated - keyrings violate the COW rule as managing
    COW keyrings is tricky, given that it is possible for a task to directly alter
    the keys in a keyring in use by another task.

    To help enforce this, various pointers to sets of credentials, such as those in
    the task_struct, are declared const. The purpose of this is compile-time
    discouragement of altering credentials through those pointers. Once a set of
    credentials has been made public through one of these pointers, it may not be
    modified, except under special circumstances:

    (1) Its reference count may incremented and decremented.

    (2) The keyrings to which it points may be modified, but not replaced.

    The only safe way to modify anything else is to create a replacement and commit
    using the functions described in Documentation/credentials.txt (which will be
    added by a later patch).

    This patch and the preceding patches have been tested with the LTP SELinux
    testsuite.

    This patch makes several logical sets of alteration:

    (1) execve().

    This now prepares and commits credentials in various places in the
    security code rather than altering the current creds directly.

    (2) Temporary credential overrides.

    do_coredump() and sys_faccessat() now prepare their own credentials and
    temporarily override the ones currently on the acting thread, whilst
    preventing interference from other threads by holding cred_replace_mutex
    on the thread being dumped.

    This will be replaced in a future patch by something that hands down the
    credentials directly to the functions being called, rather than altering
    the task's objective credentials.

    (3) LSM interface.

    A number of functions have been changed, added or removed:

    (*) security_capset_check(), ->capset_check()
    (*) security_capset_set(), ->capset_set()

    Removed in favour of security_capset().

    (*) security_capset(), ->capset()

    New. This is passed a pointer to the new creds, a pointer to the old
    creds and the proposed capability sets. It should fill in the new
    creds or return an error. All pointers, barring the pointer to the
    new creds, are now const.

    (*) security_bprm_apply_creds(), ->bprm_apply_creds()

    Changed; now returns a value, which will cause the process to be
    killed if it's an error.

    (*) security_task_alloc(), ->task_alloc_security()

    Removed in favour of security_prepare_creds().

    (*) security_cred_free(), ->cred_free()

    New. Free security data attached to cred->security.

    (*) security_prepare_creds(), ->cred_prepare()

    New. Duplicate any security data attached to cred->security.

    (*) security_commit_creds(), ->cred_commit()

    New. Apply any security effects for the upcoming installation of new
    security by commit_creds().

    (*) security_task_post_setuid(), ->task_post_setuid()

    Removed in favour of security_task_fix_setuid().

    (*) security_task_fix_setuid(), ->task_fix_setuid()

    Fix up the proposed new credentials for setuid(). This is used by
    cap_set_fix_setuid() to implicitly adjust capabilities in line with
    setuid() changes. Changes are made to the new credentials, rather
    than the task itself as in security_task_post_setuid().

    (*) security_task_reparent_to_init(), ->task_reparent_to_init()

    Removed. Instead the task being reparented to init is referred
    directly to init's credentials.

    NOTE! This results in the loss of some state: SELinux's osid no
    longer records the sid of the thread that forked it.

    (*) security_key_alloc(), ->key_alloc()
    (*) security_key_permission(), ->key_permission()

    Changed. These now take cred pointers rather than task pointers to
    refer to the security context.

    (4) sys_capset().

    This has been simplified and uses less locking. The LSM functions it
    calls have been merged.

    (5) reparent_to_kthreadd().

    This gives the current thread the same credentials as init by simply using
    commit_thread() to point that way.

    (6) __sigqueue_alloc() and switch_uid()

    __sigqueue_alloc() can't stop the target task from changing its creds
    beneath it, so this function gets a reference to the currently applicable
    user_struct which it then passes into the sigqueue struct it returns if
    successful.

    switch_uid() is now called from commit_creds(), and possibly should be
    folded into that. commit_creds() should take care of protecting
    __sigqueue_alloc().

    (7) [sg]et[ug]id() and co and [sg]et_current_groups.

    The set functions now all use prepare_creds(), commit_creds() and
    abort_creds() to build and check a new set of credentials before applying
    it.

    security_task_set[ug]id() is called inside the prepared section. This
    guarantees that nothing else will affect the creds until we've finished.

    The calling of set_dumpable() has been moved into commit_creds().

    Much of the functionality of set_user() has been moved into
    commit_creds().

    The get functions all simply access the data directly.

    (8) security_task_prctl() and cap_task_prctl().

    security_task_prctl() has been modified to return -ENOSYS if it doesn't
    want to handle a function, or otherwise return the return value directly
    rather than through an argument.

    Additionally, cap_task_prctl() now prepares a new set of credentials, even
    if it doesn't end up using it.

    (9) Keyrings.

    A number of changes have been made to the keyrings code:

    (a) switch_uid_keyring(), copy_keys(), exit_keys() and suid_keys() have
    all been dropped and built in to the credentials functions directly.
    They may want separating out again later.

    (b) key_alloc() and search_process_keyrings() now take a cred pointer
    rather than a task pointer to specify the security context.

    (c) copy_creds() gives a new thread within the same thread group a new
    thread keyring if its parent had one, otherwise it discards the thread
    keyring.

    (d) The authorisation key now points directly to the credentials to extend
    the search into rather pointing to the task that carries them.

    (e) Installing thread, process or session keyrings causes a new set of
    credentials to be created, even though it's not strictly necessary for
    process or session keyrings (they're shared).

    (10) Usermode helper.

    The usermode helper code now carries a cred struct pointer in its
    subprocess_info struct instead of a new session keyring pointer. This set
    of credentials is derived from init_cred and installed on the new process
    after it has been cloned.

    call_usermodehelper_setup() allocates the new credentials and
    call_usermodehelper_freeinfo() discards them if they haven't been used. A
    special cred function (prepare_usermodeinfo_creds()) is provided
    specifically for call_usermodehelper_setup() to call.

    call_usermodehelper_setkeys() adjusts the credentials to sport the
    supplied keyring as the new session keyring.

    (11) SELinux.

    SELinux has a number of changes, in addition to those to support the LSM
    interface changes mentioned above:

    (a) selinux_setprocattr() no longer does its check for whether the
    current ptracer can access processes with the new SID inside the lock
    that covers getting the ptracer's SID. Whilst this lock ensures that
    the check is done with the ptracer pinned, the result is only valid
    until the lock is released, so there's no point doing it inside the
    lock.

    (12) is_single_threaded().

    This function has been extracted from selinux_setprocattr() and put into
    a file of its own in the lib/ directory as join_session_keyring() now
    wants to use it too.

    The code in SELinux just checked to see whether a task shared mm_structs
    with other tasks (CLONE_VM), but that isn't good enough. We really want
    to know if they're part of the same thread group (CLONE_THREAD).

    (13) nfsd.

    The NFS server daemon now has to use the COW credentials to set the
    credentials it is going to use. It really needs to pass the credentials
    down to the functions it calls, but it can't do that until other patches
    in this series have been applied.

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

    David Howells
     
  • Use RCU to access another task's creds and to release a task's own creds.
    This means that it will be possible for the credentials of a task to be
    replaced without another task (a) requiring a full lock to read them, and (b)
    seeing deallocated memory.

    Signed-off-by: David Howells
    Acked-by: James Morris
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David Howells
     
  • Separate the task security context from task_struct. At this point, the
    security data is temporarily embedded in the task_struct with two pointers
    pointing to it.

    Note that the Alpha arch is altered as it refers to (E)UID and (E)GID in
    entry.S via asm-offsets.

    With comment fixes Signed-off-by: Marc Dionne

    Signed-off-by: David Howells
    Acked-by: James Morris
    Acked-by: Serge Hallyn
    Signed-off-by: James Morris

    David Howells
     
  • Wrap access to task credentials so that they can be separated more easily from
    the task_struct during the introduction of COW creds.

    Change most current->(|e|s|fs)[ug]id to current_(|e|s|fs)[ug]id().

    Change some task->e?[ug]id to task_e?[ug]id(). In some places it makes more
    sense to use RCU directly rather than a convenient wrapper; these will be
    addressed by later patches.

    Signed-off-by: David Howells
    Reviewed-by: James Morris
    Acked-by: Serge Hallyn
    Cc: Al Viro
    Cc: linux-audit@redhat.com
    Cc: containers@lists.linux-foundation.org
    Cc: linux-mm@kvack.org
    Signed-off-by: James Morris

    David Howells