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,
-- 
2.16.1

-- 
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/20210330120632.23496-1-chase.conklin%40arm.com.

Reply via email to