diff options
| -rw-r--r-- | fs/proc/base.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 7f2ab96dfd95..23550fef0c47 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1582,14 +1582,13 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct read_unlock(&tasklist_lock); if (!task) goto out; + if (!thread_group_leader(task)) + goto out_drop_task; inode = proc_pid_make_inode(dir->i_sb, task, PROC_TGID_INO); - - if (!inode) { - put_task_struct(task); - goto out; - } + if (!inode) + goto out_drop_task; inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; inode->i_op = &proc_tgid_base_inode_operations; inode->i_fop = &proc_tgid_base_operations; @@ -1614,6 +1613,8 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct goto out; } return NULL; +out_drop_task: + put_task_struct(task); out: return ERR_PTR(-ENOENT); } @@ -1622,6 +1623,7 @@ out: static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) { struct task_struct *task; + struct task_struct *leader = proc_task(dir); struct inode *inode; unsigned tid; @@ -1636,14 +1638,14 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry read_unlock(&tasklist_lock); if (!task) goto out; + if (leader->tgid != task->tgid) + goto out_drop_task; inode = proc_pid_make_inode(dir->i_sb, task, PROC_TID_INO); - if (!inode) { - put_task_struct(task); - goto out; - } + if (!inode) + goto out_drop_task; inode->i_mode = S_IFDIR|S_IRUGO|S_IXUGO; inode->i_op = &proc_tid_base_inode_operations; inode->i_fop = &proc_tid_base_operations; @@ -1656,6 +1658,8 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry put_task_struct(task); return NULL; +out_drop_task: + put_task_struct(task); out: return ERR_PTR(-ENOENT); } |
