This is a note to let you know that I've just added the patch titled fuse: fix page stealing to the 4.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: fuse-fix-page-stealing.patch and it can be found in the queue-4.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 712a951025c0667ff00b25afc360f74e639dfabe Mon Sep 17 00:00:00 2001 From: Miklos Szeredi <mszeredi@xxxxxxxxxx> Date: Tue, 2 Nov 2021 11:10:37 +0100 Subject: fuse: fix page stealing From: Miklos Szeredi <mszeredi@xxxxxxxxxx> commit 712a951025c0667ff00b25afc360f74e639dfabe upstream. It is possible to trigger a crash by splicing anon pipe bufs to the fuse device. The reason for this is that anon_pipe_buf_release() will reuse buf->page if the refcount is 1, but that page might have already been stolen and its flags modified (e.g. PG_lru added). This happens in the unlikely case of fuse_dev_splice_write() getting around to calling pipe_buf_release() after a page has been stolen, added to the page cache and removed from the page cache. Fix by calling pipe_buf_release() right after the page was inserted into the page cache. In this case the page has an elevated refcount so any release function will know that the page isn't reusable. Reported-by: Frank Dinoff <fdinoff@xxxxxxxxxx> Link: https://lore.kernel.org/r/CAAmZXrsGg2xsP1CK+cbuEMumtrqdvD-NKnWzhNcvn71RV3c1yw@xxxxxxxxxxxxxx/ Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device") Cc: <stable@xxxxxxxxxxxxxxx> # v2.6.35 Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- fs/fuse/dev.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -922,6 +922,13 @@ static int fuse_try_move_page(struct fus return err; } + /* + * Release while we have extra ref on stolen page. Otherwise + * anon_pipe_buf_release() might think the page can be reused. + */ + buf->ops->release(cs->pipe, buf); + buf->ops = NULL; + page_cache_get(newpage); if (!(buf->flags & PIPE_BUF_FLAG_LRU)) @@ -2090,7 +2097,8 @@ static ssize_t fuse_dev_splice_write(str out_free: for (idx = 0; idx < nbuf; idx++) { struct pipe_buffer *buf = &bufs[idx]; - buf->ops->release(pipe, buf); + if (buf->ops) + buf->ops->release(pipe, buf); } pipe_unlock(pipe); Patches currently in stable-queue which might be from mszeredi@xxxxxxxxxx are queue-4.4/fuse-fix-page-stealing.patch