From: Kalesh Singh <kaleshsingh@xxxxxxxxxx> Subject: mm/mremap.c: fix extent calculation When `next < old_addr`, `next - old_addr` arithmetic underflows causing `extent` to be incorrect. Make `extent` the smaller of `next - old_addr` or `old_end - old_addr`. Link: https://lkml.kernel.org/r/20201219170433.2418867-1-kaleshsingh@xxxxxxxxxx Fixes: c49dd34018026 ("mm: speedup mremap on 1GB or larger regions") Signed-off-by: Kalesh Singh <kaleshsingh@xxxxxxxxxx> Reported-by: Guenter Roeck <linux@xxxxxxxxxxxx> Tested-by: Guenter Roeck <linux@xxxxxxxxxxxx> Cc: Suren Baghdasaryan <surenb@xxxxxxxxxx> Cc: Minchan Kim <minchan@xxxxxxxxxx> Cc: Lokesh Gidra <lokeshgidra@xxxxxxxxxx> Cc: Helge Deller <deller@xxxxxx> Cc: Kalesh Singh <kaleshsingh@xxxxxxxxxx> Cc: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- mm/mremap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) --- a/mm/mremap.c~mm-mremap-fix-extent-calculation +++ a/mm/mremap.c @@ -358,7 +358,9 @@ static unsigned long get_extent(enum pgt next = (old_addr + size) & mask; /* even if next overflowed, extent below will be ok */ - extent = (next > old_end) ? old_end - old_addr : next - old_addr; + extent = next - old_addr; + if (extent > old_end - old_addr) + extent = old_end - old_addr; next = (new_addr + size) & mask; if (extent > next - new_addr) extent = next - new_addr; _