From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f43.google.com ([74.125.82.43]:37272 "EHLO mail-wm0-f43.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932765AbcILT3x (ORCPT ); Mon, 12 Sep 2016 15:29:53 -0400 Received: by mail-wm0-f43.google.com with SMTP id c131so75128986wmh.0 for ; Mon, 12 Sep 2016 12:29:53 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Al Viro , Tyler Hicks Subject: [PATCH 17/17] ecryptfs: use vfs_get_link() Date: Mon, 12 Sep 2016 21:29:19 +0200 Message-Id: <1473708559-12714-18-git-send-email-mszeredi@redhat.com> 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 List-ID: Here again we are copying form one buffer to another, while jumping through hoops to make kernel memory look like userspace memory. For no good reason, since vfs_get_link() provides exactly what is needed. As a bonus, now the security hook for readlink is also called on the underlying inode. Note: this can be called from link-following context. But this is okay: - not in RCU mode - e54ad7f1ee26 ("proc: prevent stacking filesystems on top") - ecryptfs is *reading* the underlying symlink not following it, so the right security hook is being called Signed-off-by: Miklos Szeredi Cc: Tyler Hicks --- fs/ecryptfs/inode.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index fb2d831b7030..95e51b2af2de 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -627,26 +627,23 @@ out_lock: static char *ecryptfs_readlink_lower(struct dentry *dentry, size_t *bufsiz) { + DEFINE_DELAYED_CALL(done); struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); - char *lower_buf; + const char *link; char *buf; - mm_segment_t old_fs; int rc; - lower_buf = kmalloc(PATH_MAX, GFP_KERNEL); - if (!lower_buf) - return ERR_PTR(-ENOMEM); - old_fs = get_fs(); - set_fs(get_ds()); - rc = vfs_readlink(lower_dentry, (char __user *)lower_buf, PATH_MAX); - set_fs(old_fs); - if (rc < 0) - goto out; + link = vfs_get_link(lower_dentry, d_inode(lower_dentry), &done); + if (IS_ERR(link)) + return ERR_CAST(link); + rc = ecryptfs_decode_and_decrypt_filename(&buf, bufsiz, dentry->d_sb, - lower_buf, rc); -out: - kfree(lower_buf); - return rc ? ERR_PTR(rc) : buf; + link, strlen(link)); + do_delayed_call(&done); + if (rc) + return ERR_PTR(rc); + + return buf; } static const char *ecryptfs_get_link(struct dentry *dentry, -- 2.5.5