Re: [PATCH v6] loop: Fix NULL pointer dereference in lo_rw_aio()
From: Bart Van Assche
Date: Mon Aug 24 2026 - 19:28:13 EST
On 8/24/26 3:53 PM, Bart Van Assche wrote:
On 8/24/26 3:06 PM, Tetsuo Handa wrote:
I still cannot catch why Bart's approach can become safe without
synchronize_rcu() and drain_workqueue().
Agreed that drain_workqueue() or flush_workqueue() is necessary. I do
not agree that an explicit synchronize_rcu() call is required. Waiting
until the request queue is frozen includes this call implicitly.
See also __percpu_ref_switch_to_atomic().
A correction: it is not safe to call drain_workqueue() nor to freeze the
request queue in __loop_clr_fd(). I'm considering to modify the comment
in that function as follows:
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1203,8 +1203,13 @@ static void __loop_clr_fd(struct loop_device *lo)
/*
* Reset the block size to the default.
*
- * No queue freezing needed because this is called from the final
- * ->release call only, so there can't be any outstanding I/O.
+ * Asynchronously submitted I/O may still be in progress. Freezing the
+ * request queue is not possible without triggering lock inversion.
+ * Freezing a request queue must happen between the
+ * queue_limits_start_update() and queue_limits_commit_update calls. If
+ * the request queue would be frozen between these two calls, a deadlock
+ * can be triggered with the loop_clear_limits() call from the I/O path
+ * since loop_clear_limits() also calls queue_limits_start_update().
*/
Thanks,
Bart.