Linux-mm Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Hao Zhang <hao_zhang_kdev@163.com>
To: Andrew Morton <akpm@linux-foundation.org>
Cc: David Hildenbrand <david@kernel.org>,
	Lorenzo Stoakes <ljs@kernel.org>,
	linux-mm@kvack.org
Subject: [PATCH] mm: thp: unlock i_mmap before releasing split folios
Date: Fri, 10 Jul 2026 15:13:44 +0800	[thread overview]
Message-ID: <20260710071344.GA106129@zh-pc> (raw)

From: Hao Zhang <zhanghao1@kylinos.cn>
Date: Thu, 9 Jul 2026 16:30:00 +0800

__folio_split() takes mapping->i_mmap_rwsem while unmapping and
splitting a file-backed large folio. The lock is currently released
only after the split folios that are not returned locked to the caller
have been unlocked and put.

That leaves a lifetime hole. Once the split folios are unlocked and
their references are dropped, inode eviction can make progress through
the final page-cache truncation path. After the folios are removed from
the page cache and the last inode reference is dropped, the inode that
embeds the address_space can be freed after an RCU grace period. A later
i_mmap_unlock_read(mapping) then dereferences mapping->i_mmap_rwsem
from freed memory.

A possible race is:

  CPU0                                    CPU1
  __folio_split()
    i_mmap_lock_read(mapping)
    ...
    remap_page()
    folio_unlock(new_folio)
    free_folio_and_swap_cache(new_folio)
                                          evict inode
                                          truncate_inode_pages_final()
                                          destroy_inode()
                                          call_rcu()
                                          RCU callback frees inode
    i_mmap_unlock_read(mapping)

Release mapping->i_mmap_rwsem after the page-cache and reverse-mapping
work has completed, but before unlocking and putting any of the split
folios. Clear the local mapping pointer after the early unlock so the
common exit path does not unlock it a second time.

Tested with syz-repro on the two available crash logs; neither reproduced
the __folio_split KASAN report on the patched kernel.

Fixes: baa355fd3314 ("thp: file pages support for split_huge_page()")
Signed-off-by: Hao Zhang <zhanghao1@kylinos.cn>
---
 mm/huge_memory.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 2bccb0a53a0a..fadc067df179 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4109,6 +4109,11 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
 
 	remap_page(folio, 1 << old_order, ttu_flags);
 
+	if (mapping) {
+		i_mmap_unlock_read(mapping);
+		mapping = NULL;
+	}
+
 	/*
 	 * Unlock all after-split folios except the one containing
 	 * @lock_at page. If @folio is not split, it will be kept locked.

base-commit: 0e35b9b6ec0ffcc5e23cbdec09f5c622ad532b53
-- 
2.15.0



             reply	other threads:[~2026-07-10  7:14 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10  7:13 Hao Zhang [this message]
2026-07-10 11:16 ` [PATCH] mm: thp: unlock i_mmap before releasing split folios Kiryl Shutsemau
2026-07-10 15:56   ` Hao Zhang
2026-07-10 17:04     ` Lorenzo Stoakes
2026-07-10 17:17     ` Kiryl Shutsemau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260710071344.GA106129@zh-pc \
    --to=hao_zhang_kdev@163.com \
    --cc=akpm@linux-foundation.org \
    --cc=david@kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox