All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] mm: fix inode UAF when splitting a file folio past EOF
@ 2026-07-14 12:23 Kiryl Shutsemau
  2026-07-14 12:23 ` [PATCH v2 1/5] mm/memory-failure: keep the folio, not the poisoned subpage, locked across split Kiryl Shutsemau
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Kiryl Shutsemau @ 2026-07-14 12:23 UTC (permalink / raw)
  To: Andrew Morton, David Hildenbrand, Lorenzo Stoakes, Miaohe Lin,
	Naoya Horiguchi
  Cc: Zi Yan, Baolin Wang, Liam R . Howlett, Nico Pache, Ryan Roberts,
	Dev Jain, Barry Song, Lance Yang, Usama Arif, Hao Zhang,
	Hao Zhang, linux-mm, linux-kernel, Kiryl Shutsemau (Meta)

From: "Kiryl Shutsemau (Meta)" <kas@kernel.org>

This fixes a use-after-free of the inode in __folio_split(), reported by
Hao Zhang, and cleans up the split helpers the fix leaves unused.

The bug: __folio_split() keeps dereferencing folio->mapping after the
split (shmem_uncharge(), i_mmap_unlock_read()), relying on the locked
@lock_at folio staying in the page cache to hold off inode eviction.
memory_failure() splits at a poisoned *tail*, and when that tail is
beyond EOF the split drops it from the page cache yet still returns it
locked -- the inode pin is gone, and a racing final iput() can evict and
free the inode mid-split.

v1 [1] pinned the inode with igrab()/iput() inside __folio_split().
Sashiko pointed out that the iput() under the folio lock can
self-deadlock: if it drops the last reference, eviction blocks on the
very folio the caller still holds locked. Thanks!

v2 drops that approach for two smaller changes:

 - memory_failure() is the only caller that passed a tail as the split
   anchor. Patch 1 makes it lock and split at the head instead. The head
   is piece 0, which the beyond-EOF drop loop never removes, so it always
   stays in the page cache and keeps the inode pinned. This alone fixes
   the UAF.

 - Patch 2 makes the requirement explicit in __folio_split(): refuse the
   split with -EBUSY when the anchor is beyond EOF, so no future caller
   can reintroduce it. No refcounting, no lock reordering.

Both are tagged for stable; patch 1 comes first so patch 2's guard never
changes memory_failure() behaviour.

Patches 3-5 are cleanups (not for stable). Patch 1 leaves
split_huge_page_to_order() with no callers, and the audit found
can_split_folio() (dead) and split_folio_to_list_to_order() (only ever
called with a NULL list) alongside it. Remove/fold them.

Only compile- and boot-tested: I could confirm memory_failure() enters
__folio_split() with a tail anchor (the pattern patch 1 removes) and that
the fixed kernel is stable, but not land the exact UAF -- the race window
is narrow enough that my instrumentation could not open it reliably.

[1] https://lore.kernel.org/all/20260713170915.239819-1-kirill@shutemov.name

Kiryl Shutsemau (Meta) (5):
  mm/memory-failure: keep the folio, not the poisoned subpage, locked
    across split
  mm/huge_memory: refuse to split a file folio when the anchor is beyond
    EOF
  mm/huge_memory: remove unused split_huge_page_to_order()
  mm/huge_memory: remove unused can_split_folio()
  mm/huge_memory: fold split_folio_to_list_to_order() into
    split_folio_to_order()

 include/linux/huge_mm.h | 22 +---------------------
 mm/huge_memory.c        | 14 ++++++++++++++
 mm/memory-failure.c     | 13 ++++++++++---
 3 files changed, 25 insertions(+), 24 deletions(-)


base-commit: 0e35b9b6ec0ffcc5e23cbdec09f5c622ad532b53
-- 
2.54.0


^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2026-07-15 13:27 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14 12:23 [PATCH v2 0/5] mm: fix inode UAF when splitting a file folio past EOF Kiryl Shutsemau
2026-07-14 12:23 ` [PATCH v2 1/5] mm/memory-failure: keep the folio, not the poisoned subpage, locked across split Kiryl Shutsemau
2026-07-14 13:01   ` David Hildenbrand (Arm)
2026-07-14 14:53     ` Kiryl Shutsemau
2026-07-14 14:58       ` David Hildenbrand (Arm)
2026-07-14 15:44         ` Zi Yan
2026-07-14 16:40           ` Kiryl Shutsemau
2026-07-14 17:31             ` Zi Yan
2026-07-15 10:42               ` Kiryl Shutsemau
2026-07-15 13:01                 ` David Hildenbrand (Arm)
2026-07-15 13:27                 ` Zi Yan
2026-07-14 13:05   ` Kiryl Shutsemau
2026-07-14 12:23 ` [PATCH v2 2/5] mm/huge_memory: refuse to split a file folio when the anchor is beyond EOF Kiryl Shutsemau
2026-07-14 12:23 ` [PATCH v2 3/5] mm/huge_memory: remove unused split_huge_page_to_order() Kiryl Shutsemau
2026-07-14 12:23 ` [PATCH v2 4/5] mm/huge_memory: remove unused can_split_folio() Kiryl Shutsemau
2026-07-14 12:23 ` [PATCH v2 5/5] mm/huge_memory: fold split_folio_to_list_to_order() into split_folio_to_order() Kiryl Shutsemau
2026-07-15  5:55 ` [syzbot ci] Re: mm: fix inode UAF when splitting a file folio past EOF syzbot ci

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.