Skip to content

Commit 1a657f7

Browse files
Oleg NesterovLinus Torvalds
authored andcommitted
[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@tv-sign.ru> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
1 parent 1c0d04c commit 1a657f7

File tree

3 files changed

+13
-2
lines changed

3 files changed

+13
-2
lines changed

fs/proc/base.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ static struct inode *proc_pid_make_inode(struct super_block * sb, struct task_st
958958
/*
959959
* grab the reference to task.
960960
*/
961-
ei->pid = get_pid(task_pid(task));
961+
ei->pid = get_task_pid(task, PIDTYPE_PID);
962962
if (!ei->pid)
963963
goto out_unlock;
964964

@@ -1677,7 +1677,7 @@ static struct dentry *proc_base_instantiate(struct inode *dir,
16771677
/*
16781678
* grab the reference to the task.
16791679
*/
1680-
ei->pid = get_pid(task_pid(task));
1680+
ei->pid = get_task_pid(task, PIDTYPE_PID);
16811681
if (!ei->pid)
16821682
goto out_iput;
16831683

include/linux/pid.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ extern struct task_struct *FASTCALL(pid_task(struct pid *pid, enum pid_type));
6868
extern struct task_struct *FASTCALL(get_pid_task(struct pid *pid,
6969
enum pid_type));
7070

71+
extern struct pid *get_task_pid(struct task_struct *task, enum pid_type type);
72+
7173
/*
7274
* attach_pid() and detach_pid() must be called with the tasklist_lock
7375
* write-held.

kernel/pid.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,15 @@ struct task_struct *find_task_by_pid_type(int type, int nr)
304304

305305
EXPORT_SYMBOL(find_task_by_pid_type);
306306

307+
struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
308+
{
309+
struct pid *pid;
310+
rcu_read_lock();
311+
pid = get_pid(task->pids[type].pid);
312+
rcu_read_unlock();
313+
return pid;
314+
}
315+
307316
struct task_struct *fastcall get_pid_task(struct pid *pid, enum pid_type type)
308317
{
309318
struct task_struct *result;

0 commit comments

Comments
 (0)