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
next prev 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).