]> git.ipfire.org Git - thirdparty/kernel/linux.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)
committerMiklos Szeredi <mszeredi@redhat.com>
Wed, 12 Nov 2025 10:45:03 +0000 (11:45 +0100)
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>
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 f6b12aebb8bbe7d255980593b75b5fb5af9c669e..ed34676703e35c629fe2c40e804679b81b2769d2 100644 (file)
@@ -598,7 +598,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;
 }
 
  /*
@@ -649,6 +651,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);