Messages in this thread Patch in this message | | | Date | Mon, 11 Sep 2006 08:37:51 +0400 | From | Oleg Nesterov <> | 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@tv-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@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |