]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
cred: remove task_is_dead() from __task_cred() validation
authorOleg Nesterov <oleg@redhat.com>
Wed, 25 Apr 2012 01:04:42 +0000 (11:04 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Mon, 30 Apr 2012 05:17:38 +0000 (15:17 +1000)
commit 8f92054e ("CRED: Fix __task_cred()'s lockdep check and banner
comment"):

    add the following validation condition:

        task->exit_state >= 0

    to permit the access if the target task is dead and therefore
    unable to change its own credentials.

OK, but afaics currently this can only help wait_task_zombie() which calls
__task_cred() without rcu lock.

Remove this validation and change wait_task_zombie() to use task_uid()
instead.  This means we do rcu_read_lock() only to shut up the lockdep,
but we already do the same in, say, wait_task_stopped().

task_is_dead() should die, task->exit_state != 0 means that this task has
passed exit_notify(), only do_wait-like code paths should use this.

Unfortunately, we can't kill task_is_dead() right now, it has already
acquired buggy users in drivers/staging.  The fix already exists.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: David Howells <dhowells@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Cc: James Morris <jmorris@namei.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/cred.h
kernel/exit.c

index adadf71a73271347a5c170df3b1c5490da073910..1b64c7222f82b4c86f580cad8d9b2dd077465027 100644 (file)
@@ -276,17 +276,13 @@ static inline void put_cred(const struct cred *_cred)
  * @task: The task to query
  *
  * Access the objective credentials of a task.  The caller must hold the RCU
- * readlock or the task must be dead and unable to change its own credentials.
+ * readlock.
  *
  * The result of this function should not be passed directly to get_cred();
  * rather get_task_cred() should be used instead.
  */
-#define __task_cred(task)                                              \
-       ({                                                              \
-               const struct task_struct *__t = (task);                 \
-               rcu_dereference_check(__t->real_cred,                   \
-                                     task_is_dead(__t));               \
-       })
+#define __task_cred(task)      \
+       rcu_dereference((task)->real_cred)
 
 /**
  * get_current_cred - Get the current task's subjective credentials
index 70875a6de8467273e84edfdd47a2cfe9be9890cd..78ea40be33fb05e289611d92cf72859574f84b72 100644 (file)
@@ -1217,7 +1217,7 @@ static int wait_task_zombie(struct wait_opts *wo, struct task_struct *p)
        unsigned long state;
        int retval, status, traced;
        pid_t pid = task_pid_vnr(p);
-       uid_t uid = __task_cred(p)->uid;
+       uid_t uid = task_uid(p);
        struct siginfo __user *infop;
 
        if (!likely(wo->wo_flags & WEXITED))