From: Jann Horn Date: Tue, 19 May 2026 14:29:38 +0000 (+0200) Subject: fuse: reject fuse_notify() pagecache ops on directories X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=9c954499d43aefac01c5dfb57a82b13d2dcf4b94;p=thirdparty%2Fkernel%2Flinux.git fuse: reject fuse_notify() pagecache ops on directories The operations FUSE_NOTIFY_STORE and FUSE_NOTIFY_RETRIEVE allow the FUSE daemon to actively write/read pagecache contents. For directories with FOPEN_CACHE_DIR, the pagecache is used as kernel-internal cache storage, and userspace is not supposed to have direct access to this cache - in particular, fuse_parse_cache() will hit WARN_ON() if the cache contains bogus data. Reject FUSE_NOTIFY_STORE and FUSE_NOTIFY_RETRIEVE on anything other than regular files with -EINVAL. Fixes: 5d7bc7e8680c ("fuse: allow using readdir cache") Cc: stable@vger.kernel.org Signed-off-by: Jann Horn Link: https://patch.msgid.link/20260519-fuse-dir-pagecache-v2-1-5428fa48e175@google.com Acked-by: Miklos Szeredi Signed-off-by: Christian Brauner (Amutable) --- diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 08d364ed7d6c..c105aaf9ff5d 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -1793,6 +1793,10 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size, inode = fuse_ilookup(fc, nodeid, NULL); if (!inode) goto out_up_killsb; + if (!S_ISREG(inode->i_mode)) { + err = -EINVAL; + goto out_iput; + } mapping = inode->i_mapping; file_size = i_size_read(inode); @@ -1970,7 +1974,10 @@ static int fuse_notify_retrieve(struct fuse_conn *fc, unsigned int size, inode = fuse_ilookup(fc, nodeid, &fm); if (inode) { - err = fuse_retrieve(fm, inode, &outarg); + if (!S_ISREG(inode->i_mode)) + err = -EINVAL; + else + err = fuse_retrieve(fm, inode, &outarg); iput(inode); } up_read(&fc->killsb);