[PATCH] ocfs2: fix use-after-free in ocfs2_fault() when VM_FAULT_RETRY

From: tejas bharambe

Date: Tue Mar 31 2026 - 02:22:32 EST


filemap_fault() may drop the mmap_lock before returning VM_FAULT_RETRY,
as documented in mm/filemap.c:

"If our return value has VM_FAULT_RETRY set, it's because the mmap_lock
may be dropped before doing I/O or by lock_folio_maybe_drop_mmap()."

When this happens, a concurrent munmap() can call remove_vma() and free
the vm_area_struct via RCU. The saved 'vma' pointer in ocfs2_fault() then
becomes a dangling pointer, and the subsequent trace_ocfs2_fault() call
dereferences it -- a use-after-free.

Fix this by returning early when VM_FAULT_RETRY is set, skipping the
trace that dereferences the potentially freed vma.

Reported-by: syzbot+a49010a0e8fcdeea075f@xxxxxxxxxxxxxxxxxxxxxxxxx
Closes: https://syzkaller.appspot.com/bug?extid=a49010a0e8fcdeea075f
Signed-off-by: Tejas Bharambe <tejas.bharambe@xxxxxxxxxxx>
---
fs/ocfs2/mmap.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 50e2faf64c..adf6423ae9 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -38,6 +38,14 @@ static vm_fault_t ocfs2_fault(struct vm_fault *vmf)
ret = filemap_fault(vmf);
ocfs2_unblock_signals(&oldset);

+ /*
+ * filemap_fault() may drop the mmap_lock and return VM_FAULT_RETRY.
+ * In that case the vma may have been freed by a concurrent munmap(),
+ * so we must not dereference it.
+ */
+ if (ret & VM_FAULT_RETRY)
+ return ret;
+
trace_ocfs2_fault(OCFS2_I(vma->vm_file->f_mapping->host)->ip_blkno,
vma, vmf->page, vmf->pgoff);
return ret;
--
2.53.0