[merged mm-stable] mm-fix-mapping_seek_hole_data-overflow-on-last-page.patch removed from -mm tree

Andrew Morton <[email protected]> Thu, 30 Jul 2026 19:42:57 -0700
Newsgroups org.kernel.vger.mm-commits
Message-ID <[email protected]>
The quilt patch titled
     Subject: mm: fix mapping_seek_hole_data() overflow on last page
has been removed from the -mm tree.  Its filename was
     mm-fix-mapping_seek_hole_data-overflow-on-last-page.patch

This patch was dropped because it was merged into the mm-stable branch
of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

------------------------------------------------------
From: Zhen Yan <[email protected]>
Subject: mm: fix mapping_seek_hole_data() overflow on last page
Date: Tue, 30 Jun 2026 20:50:47 +0800

A local unprivileged process can create a shmem/tmpfs file with i_size ==
LLONG_MAX using memfd_create() and fallocate().  If the last page is
present in the page cache, lseek(SEEK_HOLE) on that page returns
0x8000000000000000 as a successful offset, which is LLONG_MIN when stored
in loff_t.

The same file has readable data at the last byte, but SEEK_DATA from that
offset returns ENXIO.

The overflow is in mapping_seek_hole_data():

  pos = round_up((u64)pos + 1, seek_size);

For the final page below LLONG_MAX, the next page boundary is
0x8000000000000000, which is then used as a signed file offset.  When
assigned to the loff_t pos, this overflows to LLONG_MIN, so a subsequent
"pos > end" comparison does not catch it.

Keep mapping_seek_hole_data() inside its documented [start, end) search
range: compute round_up() into a u64 variable and compare against (u64)end
so the overflow is detected, then clamp pos to end when the rounded-up
value goes past the search limit.

Link: https://lore.kernel.org/[email protected]
Signed-off-by: Zhen Yan <[email protected]>
Cc: Christian Brauner <[email protected]>
Cc: Hugh Dickins <[email protected]>
Cc: Jan Kara <[email protected]>
Cc: Matthew Wilcox (Oracle) <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---

 mm/filemap.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

--- a/mm/filemap.c~mm-fix-mapping_seek_hole_data-overflow-on-last-page
+++ a/mm/filemap.c
@@ -3229,6 +3229,7 @@ loff_t mapping_seek_hole_data(struct add
 	while ((folio = find_get_entry(&xas, max, XA_PRESENT))) {
 		loff_t pos = (u64)xas.xa_index << PAGE_SHIFT;
 		size_t seek_size;
+		u64 next;
 
 		if (start < pos) {
 			if (!seek_data)
@@ -3237,7 +3238,11 @@ loff_t mapping_seek_hole_data(struct add
 		}
 
 		seek_size = seek_folio_size(&xas, folio);
-		pos = round_up((u64)pos + 1, seek_size);
+		next = round_up((u64)pos + 1, seek_size);
+		if (next > (u64)end)
+			pos = end;
+		else
+			pos = next;
 		start = folio_seek_hole_data(&xas, mapping, folio, start, pos,
 				seek_data);
 		if (start < pos)
_

Patches currently in -mm which might be from [email protected] are