On 30.03.21 14:06, Chase Conklin wrote:
> It is possible for the ending address in paging_destroy to overflow to
> exactly 0. For example, in a build with 32-bit addresses, a request to
> unmap 512MB at 0xe0000000 will result in an overflow (0xe0000000 +
> 0x20000000 = 0x100000000 which exceeds 32 bits).
>
> This overflow can be avoided by comparing the last address in the
> region to be unmapped rather than the first address to not be
> unmapped.
>
> Fixes: 7cffb9b7d54d ("core: fix hugepage splitting in paging_destroy")
> Signed-off-by: Chase Conklin <[email protected]>
> ---
>  hypervisor/paging.c | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
>
> diff --git a/hypervisor/paging.c b/hypervisor/paging.c
> index 75d5da59..e77fac30 100644
> --- a/hypervisor/paging.c
> +++ b/hypervisor/paging.c
> @@ -399,8 +399,21 @@ int paging_destroy(const struct paging_structures 
> *pg_structs,
>                                       paging->page_size : PAGE_SIZE;
>                               page_start = virt & ~(page_size-1);
>
> +                             /*
> +                              * It's possible that virt + size overflows to
> +                              * exactly 0 (e.g. a 512MB region starting at
> +                              * 0xe0000000 with 32-bit addresses) during
> +                              * normal execution. Any overflow beyond that is
> +                              * a programming error.
> +                              *
> +                              * To handle this case, subtract 1 from the size
> +                              * when comparing both sides. Note that
> +                              * page_size is always > 0, so there's no risk
> +                              * of underflow.
> +                              */
>                               if (virt <= page_start &&
> -                                 virt + size >= page_start + page_size)
> +                                 virt + (size - 1) >=
> +                                 page_start + (page_size - 1))
>                                       break;
>
>                               err = split_hugepage(pg_structs->hv_paging,
>

Good catch!. Applied - with a minor comment tweak:

"Note that size and page_size are always > 0..."

Thanks,
Jan

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/4b848060-fae4-0f46-8d47-34a55cff16a7%40web.de.

Reply via email to