Re: [PATCH] kho: fix signed shift UB in kho_preserved_memory_reserve()

Mike Rapoport <[email protected]>
Newsgroups gmane.linux.kernel.stable,gmane.linux.kernel.kexec,gmane.linux.kernel.mm,gmane.linux.kernel
Message-ID <[email protected]>
On Sun, Aug 16, 2026 at 12:30:37PM +0330, Kiarash Azarnia wrote:
> kho_preserved_memory_reserve() computes the size of a preserved
> reservation as:
> 
> 	sz = 1 << (order + PAGE_SHIFT);
> 
> `1` is a signed int, so the shift is signed-int arithmetic. For order
> 19 (a 2 GiB region) it produces 1 << 31, which is unrepresentable in
> int and is undefined behavior; in practice it yields 0x80000000,
> sign-extended on the assignment to the u64 sz. For order >= 20 the
> shift count exceeds the width of int, which is also undefined. The
> return value of memblock_reserve() is ignored and memblock_cap_size()
> clamps the bogus size, so the kernel silently reserves the wrong
> amount of memory for the preserved region.
> 
> kho_alloc_preserve() caps order at MAX_PAGE_ORDER and cannot reach
> order 19, but a boot-time reserve_mem= region of at least 2 GiB drives
> kho_preserve_pages() to compute order 19, and kho_preserve_pages() is
> EXPORT_SYMBOL_GPL(), so the path is reachable.

This looks like LLM generated, please make sure to add Assisted-by tag next
time.
 
> Cast the shift operand to u64 so the arithmetic is done in 64 bits:
> 
> 	sz = (u64)1 << (order + PAGE_SHIFT);
> 
> Fixes: 3f2ad90060f6 ("kho: adopt radix tree for preserved memory tracking")
> Cc: [email protected]
> Signed-off-by: Kiarash Azarnia <[email protected]>
> ---
>  kernel/liveupdate/kexec_handover.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c
> index 175c08a6e41e..c79f48bd64ac 100644
> --- a/kernel/liveupdate/kexec_handover.c
> +++ b/kernel/liveupdate/kexec_handover.c
> @@ -501,7 +501,7 @@ static int __init kho_preserved_memory_reserve(phys_addr_t phys,
>  	struct page *page;
>  	u64 sz;
>  
> -	sz = 1 << (order + PAGE_SHIFT);
> +	sz = (u64)1 << (order + PAGE_SHIFT);
>  	page = kho_get_preserved_page(phys, order);

This is already fixed:
https://patch.msgid.link/[email protected]
  
>  	/* Reserve the memory preserved in KHO in memblock */
> -- 
> 2.53.0
> 

-- 
Sincerely yours,
Mike.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.