linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] fuse: Fix possible memleak at startup with immediate teardown
@ 2025-10-21 21:33 Bernd Schubert
  2025-10-21 21:33 ` [PATCH 1/2] fuse: Move ring queues_refs decrement Bernd Schubert
  2025-10-21 21:33 ` [PATCH 2/2] fs/fuse: fix potential memory leak from fuse_uring_cancel Bernd Schubert
  0 siblings, 2 replies; 3+ messages in thread
From: Bernd Schubert @ 2025-10-21 21:33 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: Joanne Koong, linux-fsdevel, Jian Huang Li, Bernd Schubert,
	stable

Do not merge yet, the current series has not been tested yet.
The race is only easily reproducible with additional patches that
pin pages during FUSE_IO_URING_CMD_REGISTER - slows it down and then
xfstest's generic/001 triggers it reliably. However, I need to update
these pin patches for linux master.

Signed-off-by: Bernd Schubert <bschubert@ddn.com>
---
Bernd Schubert (1):
      fuse: Move ring queues_refs decrement

Jian Huang Li (1):
      fs/fuse: fix potential memory leak from fuse_uring_cancel

 fs/fuse/dev_uring.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)
---
base-commit: 6548d364a3e850326831799d7e3ea2d7bb97ba08
change-id: 20251021-io-uring-fixes-cancel-mem-leak-820642677c37

Best regards,
-- 
Bernd Schubert <bschubert@ddn.com>


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH 1/2] fuse: Move ring queues_refs decrement
  2025-10-21 21:33 [PATCH 0/2] fuse: Fix possible memleak at startup with immediate teardown Bernd Schubert
@ 2025-10-21 21:33 ` Bernd Schubert
  2025-10-21 21:33 ` [PATCH 2/2] fs/fuse: fix potential memory leak from fuse_uring_cancel Bernd Schubert
  1 sibling, 0 replies; 3+ messages in thread
From: Bernd Schubert @ 2025-10-21 21:33 UTC (permalink / raw)
  To: Miklos Szeredi; +Cc: Joanne Koong, linux-fsdevel, Jian Huang Li, Bernd Schubert

This is just to avoid code dup with an upcoming commit.

Signed-off-by: Bernd Schubert <bschubert@ddn.com>
---
 fs/fuse/dev_uring.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
index f6b12aebb8bbe7d255980593b75b5fb5af9c669e..e7c1095b83b11fe46080c24f539df17e70969e21 100644
--- a/fs/fuse/dev_uring.c
+++ b/fs/fuse/dev_uring.c
@@ -328,7 +328,7 @@ static void fuse_uring_entry_teardown(struct fuse_ring_ent *ent)
 {
 	struct fuse_req *req;
 	struct io_uring_cmd *cmd;
-
+	ssize_t queue_refs;
 	struct fuse_ring_queue *queue = ent->queue;
 
 	spin_lock(&queue->lock);
@@ -356,15 +356,16 @@ static void fuse_uring_entry_teardown(struct fuse_ring_ent *ent)
 
 	if (req)
 		fuse_uring_stop_fuse_req_end(req);
+
+	queue_refs = atomic_dec_return(&queue->ring->queue_refs);
+	WARN_ON_ONCE(queue_refs < 0);
 }
 
 static void fuse_uring_stop_list_entries(struct list_head *head,
 					 struct fuse_ring_queue *queue,
 					 enum fuse_ring_req_state exp_state)
 {
-	struct fuse_ring *ring = queue->ring;
 	struct fuse_ring_ent *ent, *next;
-	ssize_t queue_refs = SSIZE_MAX;
 	LIST_HEAD(to_teardown);
 
 	spin_lock(&queue->lock);
@@ -381,11 +382,8 @@ static void fuse_uring_stop_list_entries(struct list_head *head,
 	spin_unlock(&queue->lock);
 
 	/* no queue lock to avoid lock order issues */
-	list_for_each_entry_safe(ent, next, &to_teardown, list) {
+	list_for_each_entry_safe(ent, next, &to_teardown, list)
 		fuse_uring_entry_teardown(ent);
-		queue_refs = atomic_dec_return(&ring->queue_refs);
-		WARN_ON_ONCE(queue_refs < 0);
-	}
 }
 
 static void fuse_uring_teardown_entries(struct fuse_ring_queue *queue)

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] fs/fuse: fix potential memory leak from fuse_uring_cancel
  2025-10-21 21:33 [PATCH 0/2] fuse: Fix possible memleak at startup with immediate teardown Bernd Schubert
  2025-10-21 21:33 ` [PATCH 1/2] fuse: Move ring queues_refs decrement Bernd Schubert
@ 2025-10-21 21:33 ` Bernd Schubert
  1 sibling, 0 replies; 3+ messages in thread
From: Bernd Schubert @ 2025-10-21 21:33 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: Joanne Koong, linux-fsdevel, Jian Huang Li, Bernd Schubert,
	stable

From: Jian Huang Li <ali@ddn.com>

This issue could be observed sometimes during libfuse xfstests, from
dmseg prints some like "kernel: WARNING: CPU: 4 PID: 0 at
fs/fuse/dev_uring.c:204 fuse_uring_destruct+0x1f5/0x200 [fuse]".

The cause is, if when fuse daemon just submitted
FUSE_IO_URING_CMD_REGISTER SQEs, then umount or fuse daemon quits at
this very early stage. After all uring queues stopped, might have one or
more unprocessed FUSE_IO_URING_CMD_REGISTER SQEs get processed then some
new ring entities are created and added to ent_avail_queue, and
immediately fuse_uring_cancel moved them to ent_in_userspace after SQEs
get canceled. These ring entities were not moved to ent_released, and
stayed in ent_in_userspace when fuse_uring_destruct was called.

One way to solve it would be to also free 'ent_in_userspace' in
fuse_uring_destruct(), but from code point of view it is hard to see why
it is needed. As suggested by Joanne, another solution is to avoid moving
entries in fuse_uring_cancel() to the 'ent_in_userspace' list and just
releasing them directly.

Fixes: b6236c8407cb ("fuse: {io-uring} Prevent mount point hang on fuse-server termination")
Cc: Joanne Koong <joannelkoong@gmail.com>
Cc: <stable@vger.kernel.org> # v6.14
Signed-off-by: Jian Huang Li <ali@ddn.com>
Signed-off-by: Bernd Schubert <bschubert@ddn.com>
---
 fs/fuse/dev_uring.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/fs/fuse/dev_uring.c b/fs/fuse/dev_uring.c
index e7c1095b83b11fe46080c24f539df17e70969e21..d88a0c05434a04668241f09f123d5e3a9cc1621d 100644
--- a/fs/fuse/dev_uring.c
+++ b/fs/fuse/dev_uring.c
@@ -324,7 +324,7 @@ static void fuse_uring_stop_fuse_req_end(struct fuse_req *req)
 /*
  * Release a request/entry on connection tear down
  */
-static void fuse_uring_entry_teardown(struct fuse_ring_ent *ent)
+static void fuse_uring_entry_teardown(struct fuse_ring_ent *ent, int issue_flags)
 {
 	struct fuse_req *req;
 	struct io_uring_cmd *cmd;
@@ -352,7 +352,7 @@ static void fuse_uring_entry_teardown(struct fuse_ring_ent *ent)
 	spin_unlock(&queue->lock);
 
 	if (cmd)
-		io_uring_cmd_done(cmd, -ENOTCONN, IO_URING_F_UNLOCKED);
+		io_uring_cmd_done(cmd, -ENOTCONN, issue_flags);
 
 	if (req)
 		fuse_uring_stop_fuse_req_end(req);
@@ -383,7 +383,7 @@ static void fuse_uring_stop_list_entries(struct list_head *head,
 
 	/* no queue lock to avoid lock order issues */
 	list_for_each_entry_safe(ent, next, &to_teardown, list)
-		fuse_uring_entry_teardown(ent);
+		fuse_uring_entry_teardown(ent, IO_URING_F_UNLOCKED);
 }
 
 static void fuse_uring_teardown_entries(struct fuse_ring_queue *queue)
@@ -499,7 +499,7 @@ static void fuse_uring_cancel(struct io_uring_cmd *cmd,
 {
 	struct fuse_ring_ent *ent = uring_cmd_to_ring_ent(cmd);
 	struct fuse_ring_queue *queue;
-	bool need_cmd_done = false;
+	bool teardown = false;
 
 	/*
 	 * direct access on ent - it must not be destructed as long as
@@ -508,17 +508,14 @@ static void fuse_uring_cancel(struct io_uring_cmd *cmd,
 	queue = ent->queue;
 	spin_lock(&queue->lock);
 	if (ent->state == FRRS_AVAILABLE) {
-		ent->state = FRRS_USERSPACE;
-		list_move_tail(&ent->list, &queue->ent_in_userspace);
-		need_cmd_done = true;
-		ent->cmd = NULL;
+		ent->state = FRRS_TEARDOWN;
+		list_del_init(&ent->list);
+		teardown = true;
 	}
 	spin_unlock(&queue->lock);
 
-	if (need_cmd_done) {
-		/* no queue lock to avoid lock order issues */
-		io_uring_cmd_done(cmd, -ENOTCONN, issue_flags);
-	}
+	if (teardown)
+		fuse_uring_entry_teardown(ent, issue_flags);
 }
 
 static void fuse_uring_prepare_cancel(struct io_uring_cmd *cmd, int issue_flags,

-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2025-10-21 21:33 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-21 21:33 [PATCH 0/2] fuse: Fix possible memleak at startup with immediate teardown Bernd Schubert
2025-10-21 21:33 ` [PATCH 1/2] fuse: Move ring queues_refs decrement Bernd Schubert
2025-10-21 21:33 ` [PATCH 2/2] fs/fuse: fix potential memory leak from fuse_uring_cancel Bernd Schubert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).