Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fuse: missing copy_finish in fuse-over-io-uring argument copies

Fix a possible reference count leak of payload pages during
fuse argument copies.

[Joanne: simplified error cleanup]

Fixes: c090c8abae4b ("fuse: Add io-uring sqe commit and fetch support")
Cc: stable@vger.kernel.org # v6.14
Signed-off-by: Cheng Ding <cding@ddn.com>
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
Reviewed-by: Joanne Koong <joannelkoong@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

authored by

Cheng Ding and committed by
Miklos Szeredi
6e0d7f7f bd5603ea

+6 -2
+1 -1
fs/fuse/dev.c
··· 846 846 } 847 847 848 848 /* Unmap and put previous page of userspace buffer */ 849 - static void fuse_copy_finish(struct fuse_copy_state *cs) 849 + void fuse_copy_finish(struct fuse_copy_state *cs) 850 850 { 851 851 if (cs->currbuf) { 852 852 struct pipe_buffer *buf = cs->currbuf;
+4 -1
fs/fuse/dev_uring.c
··· 598 598 cs.is_uring = true; 599 599 cs.req = req; 600 600 601 - return fuse_copy_out_args(&cs, args, ring_in_out.payload_sz); 601 + err = fuse_copy_out_args(&cs, args, ring_in_out.payload_sz); 602 + fuse_copy_finish(&cs); 603 + return err; 602 604 } 603 605 604 606 /* ··· 651 649 /* copy the payload */ 652 650 err = fuse_copy_args(&cs, num_args, args->in_pages, 653 651 (struct fuse_arg *)in_args, 0); 652 + fuse_copy_finish(&cs); 654 653 if (err) { 655 654 pr_info_ratelimited("%s fuse_copy_args failed\n", __func__); 656 655 return err;
+1
fs/fuse/fuse_dev_i.h
··· 62 62 63 63 void fuse_copy_init(struct fuse_copy_state *cs, bool write, 64 64 struct iov_iter *iter); 65 + void fuse_copy_finish(struct fuse_copy_state *cs); 65 66 int fuse_copy_args(struct fuse_copy_state *cs, unsigned int numargs, 66 67 unsigned int argpages, struct fuse_arg *args, 67 68 int zeroing);