]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fuse: missing copy_finish in fuse-over-io-uring argument copies
authorCheng Ding <cding@ddn.com>
Tue, 21 Oct 2025 20:46:42 +0000 (22:46 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 Jan 2026 11:57:31 +0000 (12:57 +0100)
commit 6e0d7f7f4a43ac8868e98c87ecf48805aa8c24dd upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/fuse/dev.c
fs/fuse/dev_uring.c
fs/fuse/fuse_dev_i.h

index 132f38619d70720ce74eedc002a7b8f31e760a61..49b18d7accb39927e49bc3814ad2c3e51db84bb4 100644 (file)
@@ -846,7 +846,7 @@ void fuse_copy_init(struct fuse_copy_state *cs, bool write,
 }
 
 /* Unmap and put previous page of userspace buffer */
-static void fuse_copy_finish(struct fuse_copy_state *cs)
+void fuse_copy_finish(struct fuse_copy_state *cs)
 {
        if (cs->currbuf) {
                struct pipe_buffer *buf = cs->currbuf;
index d2bc05a8b3d10911b9dd09f6c5fea8cf025f1bd9..f0846694822ddf897cd5fe8206a0227f733a7fb8 100644 (file)
@@ -599,7 +599,9 @@ static int fuse_uring_copy_from_ring(struct fuse_ring *ring,
        cs.is_uring = true;
        cs.req = req;
 
-       return fuse_copy_out_args(&cs, args, ring_in_out.payload_sz);
+       err = fuse_copy_out_args(&cs, args, ring_in_out.payload_sz);
+       fuse_copy_finish(&cs);
+       return err;
 }
 
  /*
@@ -650,6 +652,7 @@ static int fuse_uring_args_to_ring(struct fuse_ring *ring, struct fuse_req *req,
        /* copy the payload */
        err = fuse_copy_args(&cs, num_args, args->in_pages,
                             (struct fuse_arg *)in_args, 0);
+       fuse_copy_finish(&cs);
        if (err) {
                pr_info_ratelimited("%s fuse_copy_args failed\n", __func__);
                return err;
index 6e8373f970409e83efdc5d5cfc3d943a8948d3a7..134bf44aff0d39ae8d5d47cf1518efcf2f1cfc23 100644 (file)
@@ -62,6 +62,7 @@ void fuse_dev_end_requests(struct list_head *head);
 
 void fuse_copy_init(struct fuse_copy_state *cs, bool write,
                           struct iov_iter *iter);
+void fuse_copy_finish(struct fuse_copy_state *cs);
 int fuse_copy_args(struct fuse_copy_state *cs, unsigned int numargs,
                   unsigned int argpages, struct fuse_arg *args,
                   int zeroing);