• David Howells's avatar
    security: Fix setting of PF_SUPERPRIV by __capable() · 5cd9c58f
    David Howells authored
    Fix the setting of PF_SUPERPRIV by __capable() as it could corrupt the flags
    the target process if that is not the current process and it is trying to
    change its own flags in a different way at the same time.
    
    __capable() is using neither atomic ops nor locking to protect t->flags.  This
    patch removes __capable() and introduces has_capability() that doesn't set
    PF_SUPERPRIV on the process being queried.
    
    This patch further splits security_ptrace() in two:
    
     (1) security_ptrace_may_access().  This passes judgement on whether one
         process may access another only (PTRACE_MODE_ATTACH for ptrace() and
         PTRACE_MODE_READ for /proc), and takes a pointer to the child process.
         current is the parent.
    
     (2) security_ptrace_traceme().  This passes judgement on PTRACE_TRACEME only,
         and takes only a pointer to the parent process.  current is the child.
    
         In Smack and commoncap, this uses has_capability() to determine whether
         the parent will be permitted to use PTRACE_ATTACH if normal checks fail.
         This does not set PF_SUPERPRIV.
    
    Two of the instances of __capable() actually only act on current, and so have
    been changed to calls to capable().
    
    Of the places that were using __capable():
    
     (1) The OOM killer calls __capable() thrice when weighing the killability of a
         process.  All of these now use has_capability().
    
     (2) cap_ptrace() and smack_ptrace() were using __capable() to check to see
         whether the parent was allowed to trace any process.  As mentioned above,
         these have been split.  For PTRACE_ATTACH and /proc, capable() is now
         used, and for PTRACE_TRACEME, has_capability() is used.
    
     (3) cap_safe_nice() only ever saw current, so now uses capable().
    
     (4) smack_setprocattr() rejected accesses to tasks other than current just
         after calling __capable(), so the order of these two tests have been
         switched and capable() is used instead.
    
     (5) In smack_file_send_sigiotask(), we need to allow privileged processes to
         receive SIGIO on files they're manipulating.
    
     (6) In smack_task_wait(), we let a process wait for a privileged process,
         whether or not the process doing the waiting is privileged.
    
    I've tested this with the LTP SELinux and syscalls testscripts.
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    Acked-by: default avatarSerge Hallyn <serue@us.ibm.com>
    Acked-by: default avatarCasey Schaufler <casey@schaufler-ca.com>
    Acked-by: default avatarAndrew G. Morgan <morgan@kernel.org>
    Acked-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: default avatarJames Morris <jmorris@namei.org>
    5cd9c58f
capability.c 21.9 KB