There is a use-after-free case with below call stack. pid_nr_ns+0x10/0x38 cgroup_pidlist_start+0x144/0x400 cgroup_seqfile_start+0x1c/0x24 kernfs_seq_start+0x54/0x90 seq_read+0x15c/0x3a8 kernfs_fop_read+0x38/0x160 __vfs_read+0x28/0xc8 vfs_read+0x84/0xfc A task in the cg_list was dying and the group_leader's task struct was already freed. To avoid this task_tgid_vnr needs to take the rcu_read_lock and check for pid_alive. Signed-off-by: Eun Taik Lee --- include/linux/sched.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index e9c009d..ed567bc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -2118,14 +2118,21 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk) } pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns); +static inline int pid_alive(const struct task_struct *p); static inline pid_t task_tgid_vnr(struct task_struct *tsk) { - return pid_vnr(task_tgid(tsk)); + pid_t pid = 0; + + rcu_read_lock(); + if (pid_alive(tsk)) + pid = pid_vnr(task_tgid(tsk)); + rcu_read_unlock(); + + return pid; } -static inline int pid_alive(const struct task_struct *p); static inline pid_t task_ppid_nr_ns(const struct task_struct *tsk, struct pid_namespace *ns) { pid_t pid = 0; -- 1.9.1