]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
security,selinux,smack: kill security_task_wait hook
authorStephen Smalley <sds@tycho.nsa.gov>
Tue, 10 Jan 2017 17:28:32 +0000 (12:28 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 29 Jul 2022 15:05:44 +0000 (17:05 +0200)
commit 3a2f5a59a695a73e0cde9a61e0feae5fa730e936 upstream.

As reported by yangshukui, a permission denial from security_task_wait()
can lead to a soft lockup in zap_pid_ns_processes() since it only expects
sys_wait4() to return 0 or -ECHILD. Further, security_task_wait() can
in general lead to zombies; in the absence of some way to automatically
reparent a child process upon a denial, the hook is not useful.  Remove
the security hook and its implementations in SELinux and Smack.  Smack
already removed its check from its hook.

Reported-by: yangshukui <yangshukui@huawei.com>
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Alexander Grund <theflamefire89@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
include/linux/lsm_hooks.h
include/linux/security.h
kernel/exit.c
security/security.c
security/selinux/hooks.c
security/smack/smack_lsm.c

index 53ac461f342bb684a599cf472a659d426782bc64..491385a8a69d94756065f4f3b688d75044ba2d0f 100644 (file)
  *     @sig contains the signal value.
  *     @secid contains the sid of the process where the signal originated
  *     Return 0 if permission is granted.
- * @task_wait:
- *     Check permission before allowing a process to reap a child process @p
- *     and collect its status information.
- *     @p contains the task_struct for process.
- *     Return 0 if permission is granted.
  * @task_prctl:
  *     Check permission before performing a process control operation on the
  *     current process.
@@ -1507,7 +1502,6 @@ union security_list_options {
        int (*task_movememory)(struct task_struct *p);
        int (*task_kill)(struct task_struct *p, struct siginfo *info,
                                int sig, u32 secid);
-       int (*task_wait)(struct task_struct *p);
        int (*task_prctl)(int option, unsigned long arg2, unsigned long arg3,
                                unsigned long arg4, unsigned long arg5);
        void (*task_to_inode)(struct task_struct *p, struct inode *inode);
@@ -1768,7 +1762,6 @@ struct security_hook_heads {
        struct list_head task_getscheduler;
        struct list_head task_movememory;
        struct list_head task_kill;
-       struct list_head task_wait;
        struct list_head task_prctl;
        struct list_head task_to_inode;
        struct list_head ipc_permission;
index 2f5d282bd3ecaf6be99a3fecd86f2902403e8acf..472822a1e02bf7674e7d4d6e1b566bf50aaa9e4d 100644 (file)
@@ -332,7 +332,6 @@ int security_task_getscheduler(struct task_struct *p);
 int security_task_movememory(struct task_struct *p);
 int security_task_kill(struct task_struct *p, struct siginfo *info,
                        int sig, u32 secid);
-int security_task_wait(struct task_struct *p);
 int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                        unsigned long arg4, unsigned long arg5);
 void security_task_to_inode(struct task_struct *p, struct inode *inode);
@@ -980,11 +979,6 @@ static inline int security_task_kill(struct task_struct *p,
        return 0;
 }
 
-static inline int security_task_wait(struct task_struct *p)
-{
-       return 0;
-}
-
 static inline int security_task_prctl(int option, unsigned long arg2,
                                      unsigned long arg3,
                                      unsigned long arg4,
index 8716f0780fe3da40c1f5229ae102ede73dde7a8d..e0db254a405bb79427ca12874a0eb0290ee84c3d 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/tty.h>
 #include <linux/iocontext.h>
 #include <linux/key.h>
-#include <linux/security.h>
 #include <linux/cpu.h>
 #include <linux/acct.h>
 #include <linux/tsacct_kern.h>
@@ -1342,7 +1341,7 @@ static int wait_task_continued(struct wait_opts *wo, struct task_struct *p)
  * Returns nonzero for a final return, when we have unlocked tasklist_lock.
  * Returns zero if the search for a child should continue;
  * then ->notask_error is 0 if @p is an eligible child,
- * or another error from security_task_wait(), or still -ECHILD.
+ * or still -ECHILD.
  */
 static int wait_consider_task(struct wait_opts *wo, int ptrace,
                                struct task_struct *p)
@@ -1362,20 +1361,6 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
        if (!ret)
                return ret;
 
-       ret = security_task_wait(p);
-       if (unlikely(ret < 0)) {
-               /*
-                * If we have not yet seen any eligible child,
-                * then let this error code replace -ECHILD.
-                * A permission error will give the user a clue
-                * to look for security policy problems, rather
-                * than for mysterious wait bugs.
-                */
-               if (wo->notask_error)
-                       wo->notask_error = ret;
-               return 0;
-       }
-
        if (unlikely(exit_state == EXIT_TRACE)) {
                /*
                 * ptrace == 0 means we are the natural parent. In this case
@@ -1468,7 +1453,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
  * Returns nonzero for a final return, when we have unlocked tasklist_lock.
  * Returns zero if the search for a child should continue; then
  * ->notask_error is 0 if there were any eligible children,
- * or another error from security_task_wait(), or still -ECHILD.
+ * or still -ECHILD.
  */
 static int do_wait_thread(struct wait_opts *wo, struct task_struct *tsk)
 {
index 9a13d72a64465777dded12d15d8113d6b4cb7c24..5171c3cd1d304094d6fc1b029a1c5c93afa97ddc 100644 (file)
@@ -1032,11 +1032,6 @@ int security_task_kill(struct task_struct *p, struct siginfo *info,
        return call_int_hook(task_kill, 0, p, info, sig, secid);
 }
 
-int security_task_wait(struct task_struct *p)
-{
-       return call_int_hook(task_wait, 0, p);
-}
-
 int security_task_prctl(int option, unsigned long arg2, unsigned long arg3,
                         unsigned long arg4, unsigned long arg5)
 {
@@ -1776,7 +1771,6 @@ struct security_hook_heads security_hook_heads = {
        .task_movememory =
                LIST_HEAD_INIT(security_hook_heads.task_movememory),
        .task_kill =    LIST_HEAD_INIT(security_hook_heads.task_kill),
-       .task_wait =    LIST_HEAD_INIT(security_hook_heads.task_wait),
        .task_prctl =   LIST_HEAD_INIT(security_hook_heads.task_prctl),
        .task_to_inode =
                LIST_HEAD_INIT(security_hook_heads.task_to_inode),
index eb9e2b4e81d92848dcf485221e41ffbd14b646e9..eb503eccbacc8e367cfa024878291b7c1edbf2fb 100644 (file)
@@ -3951,11 +3951,6 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info,
        return rc;
 }
 
-static int selinux_task_wait(struct task_struct *p)
-{
-       return task_has_perm(p, current, PROCESS__SIGCHLD);
-}
-
 static void selinux_task_to_inode(struct task_struct *p,
                                  struct inode *inode)
 {
@@ -6220,7 +6215,6 @@ static struct security_hook_list selinux_hooks[] = {
        LSM_HOOK_INIT(task_getscheduler, selinux_task_getscheduler),
        LSM_HOOK_INIT(task_movememory, selinux_task_movememory),
        LSM_HOOK_INIT(task_kill, selinux_task_kill),
-       LSM_HOOK_INIT(task_wait, selinux_task_wait),
        LSM_HOOK_INIT(task_to_inode, selinux_task_to_inode),
 
        LSM_HOOK_INIT(ipc_permission, selinux_ipc_permission),
index 84ed47195cdd2cecfd2086885bac303960164ca0..f01b69ead47ec4c70ec6843ae853997372f78b93 100644 (file)
@@ -2276,25 +2276,6 @@ static int smack_task_kill(struct task_struct *p, struct siginfo *info,
        return rc;
 }
 
-/**
- * smack_task_wait - Smack access check for waiting
- * @p: task to wait for
- *
- * Returns 0
- */
-static int smack_task_wait(struct task_struct *p)
-{
-       /*
-        * Allow the operation to succeed.
-        * Zombies are bad.
-        * In userless environments (e.g. phones) programs
-        * get marked with SMACK64EXEC and even if the parent
-        * and child shouldn't be talking the parent still
-        * may expect to know when the child exits.
-        */
-       return 0;
-}
-
 /**
  * smack_task_to_inode - copy task smack into the inode blob
  * @p: task to copy from
@@ -4686,7 +4667,6 @@ static struct security_hook_list smack_hooks[] = {
        LSM_HOOK_INIT(task_getscheduler, smack_task_getscheduler),
        LSM_HOOK_INIT(task_movememory, smack_task_movememory),
        LSM_HOOK_INIT(task_kill, smack_task_kill),
-       LSM_HOOK_INIT(task_wait, smack_task_wait),
        LSM_HOOK_INIT(task_to_inode, smack_task_to_inode),
 
        LSM_HOOK_INIT(ipc_permission, smack_ipc_permission),