[PATCH v6 1/2] kexec_file: stop the top-down search before it underflows

From: Breno Leitao

Date: Wed Aug 12 2026 - 07:36:24 EST


locate_mem_hole_top_down() walks candidates downwards by subtracting
PAGE_SIZE whenever the window conflicts with an existing segment or with
an architecture exclude range.

Nothing stops that subtraction at zero, so a search that reaches the
bottom of the address space wraps temp_start around and continues.

The walk starts inside the range being scanned and only moves down, so
bail out once a candidate ends up above end. That covers every step in
the loop rather than the subtractions alone, and it matches
locate_mem_hole_bottom_up(), which already bounds its candidate on both
sides.

This is a better check than subtracting with check_sub_overflow(), given
that we would have 3 subtractions in this block, and this single fix
would take care of them all (instead of three check_sub_overflow()).

Fixes: cb1052581e2b ("kexec: implementation of new syscall kexec_file_load")
Signed-off-by: Breno Leitao <leitao@xxxxxxxxxx>
---
kernel/kexec_file.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 59fb9d71e9d86..01a64d98fbcd7 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -484,7 +484,9 @@ static int locate_mem_hole_top_down(unsigned long start, unsigned long end,
/* align down start */
temp_start = ALIGN_DOWN(temp_start, kbuf->buf_align);

- if (temp_start < start || temp_start < kbuf->buf_min)
+ /* A candidate above the range means the walk wrapped around */
+ if (temp_start < start || temp_start < kbuf->buf_min ||
+ temp_start > end)
return 0;

temp_end = temp_start + kbuf->memsz - 1;

--
2.53.0-Meta