From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754506AbbBNUpS (ORCPT ); Sat, 14 Feb 2015 15:45:18 -0500 Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:25191 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754225AbbBNUpQ (ORCPT ); Sat, 14 Feb 2015 15:45:16 -0500 Date: Sat, 14 Feb 2015 12:44:52 -0800 From: Calvin Owens To: Cyrill Gorcunov , "Kirill A. Shutemov" , Andrew Morton CC: Alexey Dobriyan , Oleg Nesterov , "Eric W. Biederman" , Al Viro , "Kirill A. Shutemov" , Peter Feiner , Grant Likely , Siddhesh Poyarekar , , , Pavel Emelyanov Subject: [PATCH] procfs: Return -ESRCH on /proc/N/fd/* when PID N doesn't exist Message-ID: <20150214204452.GA1777871@mail.thefacebook.com> References: <1421194829-28696-1-git-send-email-calvinowens@fb.com> <20150114152501.GB9820@node.dhcp.inet.fi> <20150114153323.GF2253@moon> <20150114204653.GA26698@mail.thefacebook.com> <20150114211613.GH2253@moon> <20150122024554.GB23762@mail.thefacebook.com> <20150124031544.GA1992748@mail.thefacebook.com> <20150212022910.GA3247638@mail.thefacebook.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Disposition: inline In-Reply-To: <20150212022910.GA3247638@mail.thefacebook.com> User-Agent: Mutt/1.5.20 (2009-12-10) X-Originating-IP: [192.168.16.4] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.13.68,1.0.33,0.0.0000 definitions=2015-02-14_02:2015-02-13,2015-02-14,1970-01-01 signatures=0 X-Proofpoint-Spam-Details: rule=fb_default_notspam policy=fb_default score=0 kscore.is_bulkscore=0 kscore.compositescore=0 circleOfTrustscore=0 compositescore=0.925924926977281 suspectscore=0 recipient_domain_to_sender_totalscore=0 phishscore=0 bulkscore=0 kscore.is_spamscore=0 rbsscore=0.925924926977281 recipient_to_sender_totalscore=0 recipient_domain_to_sender_domain_totalscore=0 spamscore=0 recipient_to_sender_domain_totalscore=0 urlsuspectscore=0.925924926977281 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=7.0.1-1402240000 definitions=main-1502140214 X-FB-Internal: deliver Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Currently, readlink() and follow_link() for the symbolic links in /proc//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 --- 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