linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Zizhi Wo <wozizhi@huawei.com>
To: <netfs@lists.linux.dev>, <dhowells@redhat.com>, <jlayton@kernel.org>
Cc: <hsiangkao@linux.alibaba.com>, <jefflexu@linux.alibaba.com>,
	<zhujia.zj@bytedance.com>, <linux-erofs@lists.ozlabs.org>,
	<linux-fsdevel@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<wozizhi@huawei.com>, <libaokun1@huawei.com>,
	<yangerkun@huawei.com>, <houtao1@huawei.com>,
	<yukuai3@huawei.com>
Subject: [PATCH 7/8] cachefiles: Fix NULL pointer dereference in object->file
Date: Wed, 21 Aug 2024 10:43:00 +0800	[thread overview]
Message-ID: <20240821024301.1058918-8-wozizhi@huawei.com> (raw)
In-Reply-To: <20240821024301.1058918-1-wozizhi@huawei.com>

At present, the object->file has the NULL pointer dereference problem in
ondemand-mode. The root cause is that the allocated fd and object->file
lifetime are inconsistent, and the user-space invocation to anon_fd uses
object->file. Following is the process that triggers the issue:

	  [write fd]				[umount]
cachefiles_ondemand_fd_write_iter
				       fscache_cookie_state_machine
					 cachefiles_withdraw_cookie
  if (!file) return -ENOBUFS
					   cachefiles_clean_up_object
					     cachefiles_unmark_inode_in_use
					     fput(object->file)
					     object->file = NULL
  // file NULL pointer dereference!
  __cachefiles_write(..., file, ...)

Fix this issue by add an additional reference count to the object->file
before write/llseek, and decrement after it finished.

Fixes: c8383054506c ("cachefiles: notify the user daemon when looking up cookie")
Signed-off-by: Zizhi Wo <wozizhi@huawei.com>
---
 fs/cachefiles/interface.c |  3 +++
 fs/cachefiles/ondemand.c  | 30 ++++++++++++++++++++++++------
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
index 35ba2117a6f6..d30127ead911 100644
--- a/fs/cachefiles/interface.c
+++ b/fs/cachefiles/interface.c
@@ -342,10 +342,13 @@ static void cachefiles_clean_up_object(struct cachefiles_object *object,
 	}
 
 	cachefiles_unmark_inode_in_use(object, object->file);
+
+	spin_lock(&object->lock);
 	if (object->file) {
 		fput(object->file);
 		object->file = NULL;
 	}
+	spin_unlock(&object->lock);
 }
 
 /*
diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c
index 38ca6dce8ef2..fe3de9ad57bf 100644
--- a/fs/cachefiles/ondemand.c
+++ b/fs/cachefiles/ondemand.c
@@ -60,20 +60,26 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
 {
 	struct cachefiles_object *object = kiocb->ki_filp->private_data;
 	struct cachefiles_cache *cache = object->volume->cache;
-	struct file *file = object->file;
+	struct file *file;
 	size_t len = iter->count, aligned_len = len;
 	loff_t pos = kiocb->ki_pos;
 	const struct cred *saved_cred;
 	int ret;
 
-	if (!file)
+	spin_lock(&object->lock);
+	file = object->file;
+	if (!file) {
+		spin_unlock(&object->lock);
 		return -ENOBUFS;
+	}
+	get_file(file);
+	spin_unlock(&object->lock);
 
 	cachefiles_begin_secure(cache, &saved_cred);
 	ret = __cachefiles_prepare_write(object, file, &pos, &aligned_len, len, true);
 	cachefiles_end_secure(cache, saved_cred);
 	if (ret < 0)
-		return ret;
+		goto out;
 
 	trace_cachefiles_ondemand_fd_write(object, file_inode(file), pos, len);
 	ret = __cachefiles_write(object, file, pos, iter, NULL, NULL);
@@ -82,6 +88,8 @@ static ssize_t cachefiles_ondemand_fd_write_iter(struct kiocb *kiocb,
 		kiocb->ki_pos += ret;
 	}
 
+out:
+	fput(file);
 	return ret;
 }
 
@@ -89,12 +97,22 @@ static loff_t cachefiles_ondemand_fd_llseek(struct file *filp, loff_t pos,
 					    int whence)
 {
 	struct cachefiles_object *object = filp->private_data;
-	struct file *file = object->file;
+	struct file *file;
+	loff_t ret;
 
-	if (!file)
+	spin_lock(&object->lock);
+	file = object->file;
+	if (!file) {
+		spin_unlock(&object->lock);
 		return -ENOBUFS;
+	}
+	get_file(file);
+	spin_unlock(&object->lock);
 
-	return vfs_llseek(file, pos, whence);
+	ret = vfs_llseek(file, pos, whence);
+	fput(file);
+
+	return ret;
 }
 
 static long cachefiles_ondemand_fd_ioctl(struct file *filp, unsigned int ioctl,
-- 
2.39.2


  parent reply	other threads:[~2024-08-21  2:47 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-08-21  2:42 [PATCH 0/8] netfs/cachefiles: Some bugfixes Zizhi Wo
2024-08-21  2:42 ` [PATCH 1/8] cachefiles: Fix incorrect block calculations in __cachefiles_prepare_write() Zizhi Wo
2024-08-21  2:42 ` [PATCH 2/8] cachefiles: Fix incorrect length return value in cachefiles_ondemand_fd_write_iter() Zizhi Wo
2024-08-21  2:42 ` [PATCH 3/8] cachefiles: Fix missing pos updates " Zizhi Wo
2024-08-21  2:42 ` [PATCH 4/8] cachefiles: Clear invalid cache data in advance Zizhi Wo
2024-08-21  2:42 ` [PATCH 5/8] cachefiles: Clean up in cachefiles_commit_tmpfile() Zizhi Wo
2024-08-21  2:42 ` [PATCH 6/8] cachefiles: Modify inappropriate error return value in cachefiles_daemon_secctx() Zizhi Wo
2024-08-21  2:43 ` Zizhi Wo [this message]
2024-08-21  2:43 ` [PATCH 8/8] netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING Zizhi Wo
2024-10-10  3:08 ` [PATCH 0/8] netfs/cachefiles: Some bugfixes Zizhi Wo
2024-10-10  3:31   ` Gao Xiang
2024-10-10  4:08     ` Zizhi Wo
2024-10-10 10:34 ` [PATCH 1/8] cachefiles: Fix incorrect block calculations in __cachefiles_prepare_write() David Howells
2024-10-10 11:11   ` Zizhi Wo
2024-10-10 11:36   ` David Howells
2024-10-10 12:17     ` Zizhi Wo
2024-10-10 13:15     ` Zizhi Wo
2024-10-10 11:16 ` [PATCH 4/8] cachefiles: Clear invalid cache data in advance David Howells
2024-10-10 11:23 ` [PATCH 5/8] cachefiles: Clean up in cachefiles_commit_tmpfile() David Howells
2024-10-10 11:24 ` [PATCH 8/8] netfs/fscache: Add a memory barrier for FSCACHE_VOLUME_CREATING David Howells
2024-10-10 11:26 ` [PATCH 7/8] cachefiles: Fix NULL pointer dereference in object->file David Howells
2024-10-10 12:04   ` Zizhi Wo
2024-10-10 14:52   ` David Howells
2024-10-11  1:31     ` Zizhi Wo
2024-10-10 11:26 ` [PATCH 3/8] cachefiles: Fix missing pos updates in cachefiles_ondemand_fd_write_iter() David Howells
2024-10-10 11:31 ` [PATCH 6/8] cachefiles: Modify inappropriate error return value in cachefiles_daemon_secctx() David Howells
2024-10-10 11:47   ` Zizhi Wo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240821024301.1058918-8-wozizhi@huawei.com \
    --to=wozizhi@huawei.com \
    --cc=dhowells@redhat.com \
    --cc=houtao1@huawei.com \
    --cc=hsiangkao@linux.alibaba.com \
    --cc=jefflexu@linux.alibaba.com \
    --cc=jlayton@kernel.org \
    --cc=libaokun1@huawei.com \
    --cc=linux-erofs@lists.ozlabs.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netfs@lists.linux.dev \
    --cc=yangerkun@huawei.com \
    --cc=yukuai3@huawei.com \
    --cc=zhujia.zj@bytedance.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).