[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20060911043751.GA7320@oleg>
Date: Mon, 11 Sep 2006 08:37:51 +0400
From: Oleg Nesterov <oleg@...sign.ru>
To: "Eric W. Biederman" <ebiederm@...ssion.com>
Cc: Andrew Morton <akpm@...l.org>, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] introduce get_task_pid() to fix unsafe get_pid()
On 09/10, Eric W. Biederman wrote:
>
> As for the functions can we build them in all 4 varieties.
> struct pid *get_task_pid(struct task *);
> struct pid *get_task_tgid(struct task *);
> struct pid *get_task_pgrp(struct task *);
> struct pid *get_task_session(struct task *);
Something like the patch below?
> Either that or we can just drop in some rcu_read_lock() rcu_read_unlock()
> into the call sites.
Possible. I don't have a strong opinion, please feel free to send
a different patch.
[PATCH] introduce get_task_pid() to fix unsafe get_pid()
proc_pid_make_inode:
ei->pid = get_pid(task_pid(task));
I think this is not safe. get_pid() can be preempted after checking
"pid != NULL". Then the task exits, does detach_pid(), and RCU frees
the pid.
Signed-off-by: Oleg Nesterov <oleg@...sign.ru>
--- rc6-mm1/include/linux/pid.h~1_tgp 2006-09-09 22:34:50.000000000 +0400
+++ rc6-mm1/include/linux/pid.h 2006-09-11 08:24:15.000000000 +0400
@@ -68,6 +68,8 @@ extern struct task_struct *FASTCALL(pid_
extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
enum pid_type));
+extern struct pid *__get_task_pid(struct task_struct *task, enum pid_type type);
+
/*
* attach_pid() and detach_pid() must be called with the tasklist_lock
* write-held.
--- rc6-mm1/kernel/pid.c~1_tgp 2006-09-09 22:34:50.000000000 +0400
+++ rc6-mm1/kernel/pid.c 2006-09-11 08:24:21.000000000 +0400
@@ -305,6 +305,15 @@ struct task_struct *find_task_by_pid_typ
EXPORT_SYMBOL(find_task_by_pid_type);
+struct pid *__get_task_pid(struct task_struct *task, enum pid_type type)
+{
+ struct pid *pid;
+ rcu_read_lock();
+ pid = get_pid(task->pids[type].pid);
+ rcu_read_unlock();
+ return pid;
+}
+
struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
{
struct task_struct *result;
--- rc6-mm1/include/linux/sched.h~1_tgp 2006-09-09 22:34:50.000000000 +0400
+++ rc6-mm1/include/linux/sched.h 2006-09-11 08:26:29.000000000 +0400
@@ -1073,6 +1073,11 @@ static inline struct pid *task_session(s
return task->group_leader->pids[PIDTYPE_SID].pid;
}
+static inline struct pid *get_task_pid(struct task_struct *task)
+{
+ return __get_task_pid(task, PIDTYPE_PID);
+}
+
/**
* pid_alive - check that a task structure is not stale
* @p: Task structure to be checked.
--- rc6-mm1/fs/proc/base.c~1_tgp 2006-09-09 22:34:49.000000000 +0400
+++ rc6-mm1/fs/proc/base.c 2006-09-11 08:27:12.000000000 +0400
@@ -958,7 +958,7 @@ static struct inode *proc_pid_make_inode
/*
* grab the reference to task.
*/
- ei->pid = get_pid(task_pid(task));
+ ei->pid = get_task_pid(task);
if (!ei->pid)
goto out_unlock;
@@ -1665,7 +1665,7 @@ static struct dentry *proc_base_instanti
/*
* grab the reference to the task.
*/
- ei->pid = get_pid(task_pid(task));
+ ei->pid = get_task_pid(task);
if (!ei->pid)
goto out_iput;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists