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.