Re: [PATCH] ocfs2: fix NULL deref in ocfs2_wait_for_recovery after recovery_exit

From: Joseph Qi

Date: Tue May 19 2026 - 08:03:42 EST




On 5/19/26 9:36 AM, Jiakai Xu wrote:
> In ocfs2_recovery_exit(), the recovery_map is freed via kfree() but
> osb->recovery_map is not set to NULL afterward. If ocfs2_wait_for_recovery()
> is called subsequently (e.g. during inode eviction in the dismount path or

evict_inodes() runs before ocfs2_recovery_exit(), which is called through put_super.

> via a racing stat() syscall), ocfs2_recovery_completed() dereferences the
> stale pointer, leading to a NULL pointer dereference at rm->rm_used.
>
> Fix this by:
> 1. Setting osb->recovery_map = NULL after kfree() in ocfs2_recovery_exit()
> 2. Adding a NULL guard in ocfs2_recovery_completed() so that it safely
> returns "recovery completed" when the map has been freed
>
> Fixes: 553abd046af6 ("ocfs2: Change the recovery map to an array of node numbers.")
> Signed-off-by: Jiakai Xu <xujiakai24@xxxxxxxxxxxxxxxx>
> ---
> fs/ocfs2/journal.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
> index f9bf3bac085d..5529a177f90e 100644
> --- a/fs/ocfs2/journal.c
> +++ b/fs/ocfs2/journal.c
> @@ -243,6 +243,7 @@ void ocfs2_recovery_exit(struct ocfs2_super *osb)
> /* XXX: Should we bug if there are dirty entries? */
>
> kfree(rm);
> + osb->recovery_map = NULL;
> }
>
> static int __ocfs2_recovery_map_test(struct ocfs2_super *osb,
> @@ -1225,6 +1226,9 @@ static int ocfs2_recovery_completed(struct ocfs2_super *osb)
> int empty;
> struct ocfs2_recovery_map *rm = osb->recovery_map;
>
Seems still cannot fully close the race?

Thanks,
Joseph

> + if (!rm)
> + return 1;
> +
> spin_lock(&osb->osb_lock);
> empty = (rm->rm_used == 0);
> spin_unlock(&osb->osb_lock);