When collapse_file() fails after xas_create_range() succeeds, the rollback path does not clean up pre-allocated XArray nodes stored in xas->xa_alloc. These nodes are allocated by xas_nomem() when xas_create() fails with GFP_NOWAIT and need to be freed. The leak occurs because: 1. xas_create_range() may call xas_nomem() which allocates a node and stores it in xas->xa_alloc 2. If the collapse operation fails later, the rollback path jumps to the 'rollback:' label 3. The rollback path cleans up folios but does not call xas_destroy() to free the pre-allocated nodes in xas->xa_alloc Fix this by calling xas_destroy(&xas) at the beginning of the rollback path to free any pre-allocated nodes. This is safe because xas_destroy() only frees nodes in xas->xa_alloc that were never inserted into the XArray tree. Note: This fixes the leak of pre-allocated nodes. A separate fix will be needed to clean up empty nodes that were inserted into the tree by xas_create_range() but never populated. Link: https://syzkaller.appspot.com/bug?id=a274d65fc733448ed518ad15481ed575669dd98c Fixes: cae106dd67b9 ("mm/khugepaged: refactor collapse_file control flow") Signed-off-by: Shardul Bankar --- mm/khugepaged.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index abe54f0043c7..f2fe7924afa0 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -2230,6 +2230,7 @@ static int collapse_file(struct mm_struct *mm, unsigned long addr, goto out; rollback: + xas_destroy(&xas); /* Something went wrong: roll back page cache changes */ if (nr_none) { xas_lock_irq(&xas); -- 2.34.1