> On 03/24/2026 9:05 PM PDT Junrui Luo <[email protected]> wrote:
>
Hi Junrui,
I think that checking for overflow as implemented can be improved.
`guest_pfn` is a guest page frame number (GPA/page size). Hyper-V uses
page size of 4KiB (`HV_HYP_PAGE_SIZE`). On x86_64 GPAs are limited to
52 bits, and max GFN = (1<<52)/(1<<12) = 1<<40. On ARM64, 52 bits is
also the limit for the bits used in GPA. Thus checking for overflowing is
not the only thing needed here because _well_ before overflowing there is
that (1<<40)-th GFN which is problematic as using it or going above means
going over the arch limits of bits used in GPA (the processor won't be able
to map the memory through the page tables).
So we could check for (1<<40)-th GFN, too. That is, if we'd like to return
an error early instead of trying to do physically impossible things and
erroring out later anyway.
Perhaps something along the lines of
| if (mem->guest_pfn + nr_pages > HVPFN_DOWN(1ULL << MAX_PHYSMEM_BITS))
| return -EINVAL;
could be an meaningful improvement in addition to checking overflow which
alone doesn't take into account the specifics outlined above.
If folks like that, maybe could hoist an improved check out into a function
and apply throughout the file.
--
Cheers,
Roman
>
> mshv_partition_create_region() computes mem->guest_pfn + nr_pages to
> check for overlapping regions without verifying u64 wraparound. A
> sufficiently large guest_pfn can cause the addition to overflow,
> bypassing the overlap check and allowing creation of regions that wrap
> around the address space.
>
> Fix by using check_add_overflow() to reject such regions.
>
> Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose
> /dev/mshv to VMMs")
> Reported-by: Yuhao Jiang <[email protected]>
> Cc: [email protected]
> Signed-off-by: Junrui Luo <[email protected]>
> ---
> drivers/hv/mshv_root_main.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c
> index 6f42423f7faa..6ddb315fc2c2 100644
> --- a/drivers/hv/mshv_root_main.c
> +++ b/drivers/hv/mshv_root_main.c
> @@ -1174,11 +1174,16 @@ static int mshv_partition_create_region(struct
> mshv_partition *partition,
> {
> struct mshv_mem_region *rg;
> u64 nr_pages = HVPFN_DOWN(mem->size);
> + u64 new_region_end;
> +
> + /* Reject regions whose end address would wrap around */
> + if (check_add_overflow(mem->guest_pfn, nr_pages, &new_region_end))
> + return -EOVERFLOW;
>
> /* Reject overlapping regions */
> spin_lock(&partition->pt_mem_regions_lock);
> hlist_for_each_entry(rg, &partition->pt_mem_regions, hnode) {
> - if (mem->guest_pfn + nr_pages <= rg->start_gfn ||
> + if (new_region_end <= rg->start_gfn ||
> rg->start_gfn + rg->nr_pages <= mem->guest_pfn)
> continue;
> spin_unlock(&partition->pt_mem_regions_lock);
>
> ---
> base-commit: c369299895a591d96745d6492d4888259b004a9e
> change-id: 20260325-fixes-9a58895aea55
>
> Best regards,
> --
> Junrui Luo <[email protected]>