Currently, readlink() and follow_link() for the symbolic links in /proc/<pid>/fd/* will return -EACCES in the case where looking up the task finds that it does not exist.
This patch inlines the logic from proc_fd_access_allowed() into these two functions such that they will return -ESRCH if the lookup in /proc races with the task exiting. Since those were the only two callers of that helper function, it also removes it. Signed-off-by: Calvin Owens <calvinow...@fb.com> --- fs/proc/base.c | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 3f3d7ae..308fcbd 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -485,23 +485,6 @@ static int proc_pid_syscall(struct seq_file *m, struct pid_namespace *ns, /* Here the fs part begins */ /************************************************************************/ -/* permission checks */ -static int proc_fd_access_allowed(struct inode *inode) -{ - struct task_struct *task; - int allowed = 0; - /* Allow access to a task's file descriptors if it is us or we - * may use ptrace attach to the process and find out that - * information. - */ - task = get_proc_task(inode); - if (task) { - allowed = ptrace_may_access(task, PTRACE_MODE_READ); - put_task_struct(task); - } - return allowed; -} - int proc_setattr(struct dentry *dentry, struct iattr *attr) { int error; @@ -1375,10 +1358,21 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) { struct inode *inode = dentry->d_inode; struct path path; - int error = -EACCES; + int error = -ESRCH; + int allowed = 0; + struct task_struct *task; /* Are we allowed to snoop on the tasks file descriptors? */ - if (!proc_fd_access_allowed(inode)) + task = get_proc_task(inode); + if (task) { + allowed = ptrace_may_access(task, PTRACE_MODE_READ); + put_task_struct(task); + } else { + goto out; + } + + error = -EACCES; + if (!allowed) goto out; error = PROC_I(inode)->op.proc_get_link(dentry, &path); @@ -1417,12 +1411,23 @@ static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int buflen) { - int error = -EACCES; + int error = -ESRCH; + int allowed = 0; + struct task_struct *task; struct inode *inode = dentry->d_inode; struct path path; /* Are we allowed to snoop on the tasks file descriptors? */ - if (!proc_fd_access_allowed(inode)) + task = get_proc_task(inode); + if (task) { + allowed = ptrace_may_access(task, PTRACE_MODE_READ); + put_task_struct(task); + } else { + goto out; + } + + error = -EACCES; + if (!allowed) goto out; error = PROC_I(inode)->op.proc_get_link(dentry, &path); -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/