On Tue, Oct 21, 2025 at 1:46 PM Bernd Schubert bschubert@ddn.com wrote:
From: Cheng Ding cding@ddn.com
Fix a possible reference count leak of payload pages during fuse argument copies.
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
fs/fuse/dev.c | 2 +- fs/fuse/dev_uring.c | 12 +++++++++--- fs/fuse/fuse_dev_i.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 132f38619d70720ce74eedc002a7b8f31e760a61..49b18d7accb39927e49bc3814ad2c3e51db84bb4 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -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; diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c index f6b12aebb8bbe7d255980593b75b5fb5af9c669e..3721c2d91627f5438b6997df3de63734704e56ff 100644 --- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -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;}
/* @@ -651,13 +653,17 @@ static int fuse_uring_args_to_ring(struct fuse_ring *ring, struct fuse_req *req, (struct fuse_arg *)in_args, 0); if (err) { pr_info_ratelimited("%s fuse_copy_args failed\n", __func__);
return err;
goto copy_finish; } ent_in_out.payload_sz = cs.ring.copied_sz; err = copy_to_user(&ent->headers->ring_ent_in_out, &ent_in_out, sizeof(ent_in_out));
return err ? -EFAULT : 0;
if (err)err = -EFAULT;+copy_finish:
fuse_copy_finish(&cs);return err;}
nit: this could just be
--- a/fs/fuse/dev_uring.c +++ b/fs/fuse/dev_uring.c @@ -649,6 +649,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;
Reviewed-by: Joanne Koong joannelkoong@gmail.com