mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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 <qiang.zhang@linux.dev> Acked-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: Alexander Aring <aahringo@redhat.com> Signed-off-by: David Teigland <teigland@redhat.com>
This commit is contained in:
parent
b4e6ae7ba7
commit
ed9b6a1296
|
|
@ -1984,4 +1984,5 @@ void dlm_lowcomms_exit(void)
|
|||
}
|
||||
}
|
||||
srcu_read_unlock(&connections_srcu, idx);
|
||||
srcu_barrier(&connections_srcu);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1178,6 +1178,7 @@ void dlm_midcomms_exit(void)
|
|||
}
|
||||
}
|
||||
srcu_read_unlock(&nodes_srcu, idx);
|
||||
srcu_barrier(&nodes_srcu);
|
||||
|
||||
dlm_lowcomms_exit();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user