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
                   ` (4 more replies)
  0 siblings, 5 replies; 13+ 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] 13+ messages in thread

end of thread, other threads:[~2026-07-14 17:32 UTC | newest]

Thread overview: 13+ 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-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

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.