On Wed, Mar 30, 2022 at 08:45:04AM -0700, Zach O'Keefe wrote:
From: Miklos Szeredi mszeredi@redhat.com
commit 0c4bcfdecb1ac0967619ee7ff44871d93c08c909 upstream.
In FOPEN_DIRECT_IO mode, fuse_file_write_iter() calls fuse_direct_write_iter(), which normally calls fuse_direct_io(), which then imports the write buffer with fuse_get_user_pages(), which uses iov_iter_get_pages() to grab references to userspace pages instead of actually copying memory.
On the filesystem device side, these pages can then either be read to userspace (via fuse_dev_read()), or splice()d over into a pipe using fuse_dev_splice_read() as pipe buffers with &nosteal_pipe_buf_ops.
This is wrong because after fuse_dev_do_read() unlocks the FUSE request, the userspace filesystem can mark the request as completed, causing write() to return. At that point, the userspace filesystem should no longer have access to the pipe buffer.
Fix by copying pages coming from the user address space to new pipe buffers.
Reported-by: Jann Horn jannh@google.com Fixes: c3021629a0d8 ("fuse: support splice() reading from fuse device") Cc: stable@vger.kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Zach O'Keefe zokeefe@google.com
Applies against stable-v4.14 and stable-v4.19
struct fuse_args hasn't been piped through relevant functions yet, so place user_pages flag in an empty hole in struct fuse_req instead.
Thanks for the backport, now queued up.
greg k-h