From patchwork Mon Sep 12 19:29:10 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 9327881 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id BE7C76077F for ; Mon, 12 Sep 2016 19:33:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B0E6328E59 for ; Mon, 12 Sep 2016 19:33:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A51D128E97; Mon, 12 Sep 2016 19:33:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 433A928E59 for ; Mon, 12 Sep 2016 19:33:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756409AbcILTdV (ORCPT ); Mon, 12 Sep 2016 15:33:21 -0400 Received: from mail-wm0-f49.google.com ([74.125.82.49]:37083 "EHLO mail-wm0-f49.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758161AbcILT3f (ORCPT ); Mon, 12 Sep 2016 15:29:35 -0400 Received: by mail-wm0-f49.google.com with SMTP id c131so75118682wmh.0 for ; Mon, 12 Sep 2016 12:29:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=wbueSSMr1aKrycjrS2JkvSV6tIegl6MbrbcAcKUsS+s=; b=TQcCEIn1dRkZsdQr99LPYbvuasSnSgP4leqOUT3QQPlQPOrjWzZahnVx/9AiVmDP7f gBY8Ms4uON1WrIhwGJxk2Q7ViZIuq6PqWsFQHM1YjWVURMrETjGo2mNaSPL9vB8nSOeT nPOReXuHAoK7QzgXwuYbGTsPvSntsMXnrBCHaHXpHJNUAUPbRjZ6Ptekx4Ei8+vPpzfY k5ZVBGeqvrqhjMmQeD1nhFw0hA6C6Fff28064/xMsWyNv/Oe8E+EaSh0wKLnOiYiuzlX D6FEMTl5HayNR1sk3WX6s59s1snmLXazfLEym0Lu0fd2ts3kqx+MNhN0OkhShZasv152 YRww== X-Gm-Message-State: AE9vXwOVGBUsVeEd1LIIdF220MC6i2ijyf+06gdgq42d6cof9cIMFolwr5pf9bvupK54pIZx X-Received: by 10.28.209.142 with SMTP id i136mr6640632wmg.0.1473708573422; Mon, 12 Sep 2016 12:29:33 -0700 (PDT) Received: from veci.piliscsaba.szeredi.hu (pool-dsl-2c-0018.externet.hu. [217.173.44.24]) by smtp.gmail.com with ESMTPSA id f8sm19250418wjh.45.2016.09.12.12.29.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Sep 2016 12:29:32 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Al Viro Subject: [PATCH 08/17] proc: merge proc_pid_readlink() into proc_pid_get_link() Date: Mon, 12 Sep 2016 21:29:10 +0200 Message-Id: <1473708559-12714-9-git-send-email-mszeredi@redhat.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1473708559-12714-1-git-send-email-mszeredi@redhat.com> References: <1473708559-12714-1-git-send-email-mszeredi@redhat.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This will allow us to move the generic readlink logic into the VFS and get rid of the readlink method. And it's a cleanup, removing more lines than it adds, since the two functions have a lot in common. /proc/$$/map_files/A allowed reading the symlink with the normal proc permission checks, but following only allowed for CAP_SYS_ADMIN capable tasks. So in proc_map_files_get_link() check for is_following_link() before bailing out if not CAP_SYS_ADMIN capable. Signed-off-by: Miklos Szeredi --- fs/proc/base.c | 68 ++++++++++++++++++---------------------------------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index ac0df4dde823..84769c763afe 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1578,6 +1578,7 @@ static const char *proc_pid_get_link(struct dentry *dentry, { struct path path; int error = -EACCES; + char *res; if (!dentry) return ERR_PTR(-ECHILD); @@ -1590,58 +1591,31 @@ static const char *proc_pid_get_link(struct dentry *dentry, if (error) goto out; - nd_jump_link(&path); - return NULL; -out: - return ERR_PTR(error); -} - -static int do_proc_readlink(struct path *path, char __user *buffer, int buflen) -{ - char *tmp = (char*)__get_free_page(GFP_TEMPORARY); - char *pathname; - int len; - - if (!tmp) - return -ENOMEM; - - pathname = d_path(path, tmp, PAGE_SIZE); - len = PTR_ERR(pathname); - if (IS_ERR(pathname)) - goto out; - len = tmp + PAGE_SIZE - 1 - pathname; - - if (len > buflen) - len = buflen; - if (copy_to_user(buffer, pathname, len)) - len = -EFAULT; - out: - free_page((unsigned long)tmp); - return len; -} - -static int proc_pid_readlink(struct dentry * dentry, char __user * buffer, int buflen) -{ - int error = -EACCES; - struct inode *inode = d_inode(dentry); - struct path path; + if (is_following_link()) { + nd_jump_link(&path); + res = NULL; + } else { + char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); - /* Are we allowed to snoop on the tasks file descriptors? */ - if (!proc_fd_access_allowed(inode)) - goto out; + error = -ENOMEM; + if (!buf) + goto out; - error = PROC_I(inode)->op.proc_get_link(dentry, &path); - if (error) - goto out; + res = d_path(&path, buf, PAGE_SIZE); + if (IS_ERR(res)) + kfree(buf); + else + set_delayed_call(done, kfree_link, buf); + } + return res; - error = do_proc_readlink(&path, buffer, buflen); - path_put(&path); out: - return error; + return ERR_PTR(error); } + const struct inode_operations proc_pid_link_inode_operations = { - .readlink = proc_pid_readlink, + .readlink = generic_readlink, .get_link = proc_pid_get_link, .setattr = proc_setattr, }; @@ -1966,7 +1940,7 @@ proc_map_files_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done) { - if (!capable(CAP_SYS_ADMIN)) + if (is_following_link() && !capable(CAP_SYS_ADMIN)) return ERR_PTR(-EPERM); return proc_pid_get_link(dentry, inode, done); @@ -1976,7 +1950,7 @@ proc_map_files_get_link(struct dentry *dentry, * Identical to proc_pid_link_inode_operations except for get_link() */ static const struct inode_operations proc_map_files_link_inode_operations = { - .readlink = proc_pid_readlink, + .readlink = generic_readlink, .get_link = proc_map_files_get_link, .setattr = proc_setattr, };