Re: [PATCH v5 1/4] mm/truncate: align truncation boundaries to mapping minimum folio order

From: Zhang Yi

Date: Mon Sep 28 2026 - 09:16:47 EST


On 9/28/2026 8:31 PM, sashiko-bot@xxxxxxxxxx wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Critical] mm: integer overflow in round_up() during truncation causes complete file data loss
> --

As mentioned in the cover litter, this is a pre-existing issue related
to the file system that needs to be addressed separately.

Thanks,
Yi.

>
> commit 583804d300760dcf60e3ec5aab6503a560ad3e7e
> Author: Zhang Yi <yi.zhang@xxxxxxxxxx>
>
> mm/truncate: align truncation boundaries to mapping minimum folio order
>
> When the mapping has a non-zero minimum folio order, this patch changes
> folio_split() in truncate_inode_partial_folio() to stop at min_order instead
> of order 0. It also aligns both start and end to the mapping minimum folio
> order so they always fall on a folio boundary, preventing valid out-of-range
> tails from being dropped.
>
> Link: https://lore.kernel.org/linux-mm/CAJnrk1bQYUe6+1ryyJur5EEnZYrC+_5AYsy=OWzVRgD4202y1g@xxxxxxxxxxxxxx/
>
>> diff --git a/mm/truncate.c b/mm/truncate.c
>> index b58ba940be474..8a28f4a212677 100644
>> --- a/mm/truncate.c
>> +++ b/mm/truncate.c
> [ ... ]
>> @@ -395,6 +397,10 @@ void truncate_inode_pages_range(struct address_space *mapping,
>> else
>> end = (lend + 1) >> PAGE_SHIFT;
>>
>> + start = round_up(start, min_nrpages);
>
> [Severity: Critical]
> Could this round_up() result in an integer overflow that changes a very large
> start index to 0 on 32-bit architectures?
>
> When an unprivileged user issues fallocate(PUNCH_HOLE) or truncate at an offset
> near ULONG_MAX << PAGE_SHIFT (e.g., 16TB on 32-bit systems) on a filesystem with
> min_nrpages > 1 (like ext4 with large folio/iomap), start approaches
> ULONG_MAX (e.g., 0xFFFFFFFF on 32-bit x86).
>
> The macro round_up(start, min_nrpages) performs 32-bit arithmetic. With
> start approaching 0xFFFFFFFF, start + min_nrpages - 1 can overflow to a value
> less than min_nrpages, causing round_up to evaluate to 0.
>
> This would corrupt the start index to 0 in truncate_inode_pages_range(), and
> the subsequent loop would unintentionally truncate the entire page cache from
> index 0 to end, causing complete data loss of unwritten data.
>
>> + if (end != (pgoff_t)-1)
>> + end = round_down(end, min_nrpages);
>> +
>> folio_batch_init(&fbatch);
>> index = start;
>> while (index < end && find_lock_entries(mapping, &index, end - 1,
>