Commit 1a657f78 authored by Oleg Nesterov's avatar Oleg Nesterov Committed by Linus Torvalds

[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: default avatarOleg Nesterov <oleg@tv-sign.ru>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1c0d04c9
...@@ -958,7 +958,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st ...@@ -958,7 +958,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
/* /*
* grab the reference to task. * grab the reference to task.
*/ */
ei->pid = get_pid(task_pid(task)); ei->pid = get_task_pid(task, PIDTYPE_PID);
if (!ei->pid) if (!ei->pid)
goto out_unlock; goto out_unlock;
...@@ -1677,7 +1677,7 @@ static struct dentry *proc_base_instantiate(struct inode *dir, ...@@ -1677,7 +1677,7 @@ static struct dentry *proc_base_instantiate(struct inode *dir,
/* /*
* grab the reference to the task. * grab the reference to the task.
*/ */
ei->pid = get_pid(task_pid(task)); ei->pid = get_task_pid(task, PIDTYPE_PID);
if (!ei->pid) if (!ei->pid)
goto out_iput; goto out_iput;
......
...@@ -68,6 +68,8 @@ extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type)); ...@@ -68,6 +68,8 @@ extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type));
extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid, extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
enum pid_type)); 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 * attach_pid() and detach_pid() must be called with the tasklist_lock
* write-held. * write-held.
......
...@@ -304,6 +304,15 @@ struct task_struct *find_task_by_pid_type(int type, int nr) ...@@ -304,6 +304,15 @@ struct task_struct *find_task_by_pid_type(int type, int nr)
EXPORT_SYMBOL(find_task_by_pid_type); 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 *fastcall get_pid_task(struct pid *pid, enum pid_type type)
{ {
struct task_struct *result; struct task_struct *result;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment