From ed9b6a1296f10e4881d93dfe6d76013fbbaeee87 Mon Sep 17 00:00:00 2001 From: Zqiang Date: Tue, 1 Sep 2026 13:47:14 -0400 Subject: [PATCH] dlm: wait for outstanding SRCU callbacks to complete in exit paths The dlm_lowcomms_exit() and dlm_midcomms_exit() iterate over the srcu protected connection and node hash tables and hand each element to call_srcu() for deferred freeing (connection_release() and midcomms_node_release()). call_srcu() is asynchronous: the callbacks are invoked only after an SRCU grace period, which may happen after the exit function has already returned. These exit functions are reached from exit_dlm() on module unload. Once they return, module teardown continues and the module text may be unloaded while call_srcu() callbacks are still pending. When such a callback finally runs, it executes freed module code and touches the static SRCU domains that are being torn down, resulting in a use-after-free. Add an srcu_barrier() after the call_srcu() loop in each exit function to wait for all outstanding callbacks of the respective SRCU domain to complete before returning. In dlm_midcomms_exit() the barrier is issued before dlm_lowcomms_exit() so that node callbacks are drained prior to tearing down the lower layer. Signed-off-by: Zqiang Acked-by: Alexander Aring Signed-off-by: Alexander Aring Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 1 + fs/dlm/midcomms.c | 1 + 2 files changed, 2 insertions(+) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 2aff1c7c17de..ea8353c4638d 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1984,4 +1984,5 @@ void dlm_lowcomms_exit(void) } } srcu_read_unlock(&connections_srcu, idx); + srcu_barrier(&connections_srcu); } diff --git a/fs/dlm/midcomms.c b/fs/dlm/midcomms.c index 8964164600d2..045431524494 100644 --- a/fs/dlm/midcomms.c +++ b/fs/dlm/midcomms.c @@ -1178,6 +1178,7 @@ void dlm_midcomms_exit(void) } } srcu_read_unlock(&nodes_srcu, idx); + srcu_barrier(&nodes_srcu); dlm_lowcomms_exit(); }