mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2026-11-08 18:57:22 +00:00
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/20260630125047.703170-1-yanzhen20011121@163.com Signed-off-by: Zhen Yan <yanzhen20011121@163.com> Cc: Christian Brauner <brauner@kernel.org> Cc: Hugh Dickins <hughd@google.com> Cc: Jan Kara <jack@suse.cz> Cc: Matthew Wilcox (Oracle) <willy@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
4794 lines
136 KiB
4794 lines
136 KiB