The both the size and base of a media sanitize operation are both provided
by the VM, an overflow is possible which may result in checks on valid
range passing when they should not.  Close that by checking for overflow
on the addition.

Fixes: 40ab4ed10775 ("hw/cxl/cxl-mailbox-utils: Media operations Sanitize and 
Write Zeros commands CXL r3.2(8.2.10.9.5.3)")
Closes: 
https://lore.kernel.org/qemu-devel/cafeaca8rqop+ju0fuxn+0t57nbg+bep80z45f6py0ci2fz_...@mail.gmail.com/
Reported-by: Peter Maydell <[email protected]>
Signed-off-by: Jonathan Cameron <[email protected]>
---
 hw/cxl/cxl-mailbox-utils.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index a64b8ba5351f..d8f62a13a8ec 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -2411,7 +2411,7 @@ static uint64_t get_dc_size(CXLType3Dev *ct3d, 
MemoryRegion **dc_mr)
 static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t dpa_addr,
                              size_t length)
 {
-    uint64_t vmr_size, pmr_size, dc_size;
+    uint64_t vmr_size, pmr_size, dc_size, dpa_end;
 
     if ((dpa_addr % CXL_CACHE_LINE_SIZE) ||
         (length % CXL_CACHE_LINE_SIZE)  ||
@@ -2423,7 +2423,12 @@ static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t 
dpa_addr,
     pmr_size = get_pmr_size(ct3d, NULL);
     dc_size = get_dc_size(ct3d, NULL);
 
-    if (dpa_addr + length > vmr_size + pmr_size + dc_size) {
+    /* sanitize 64 bit values coming from guest */
+    if (uadd64_overflow(dpa_addr, length, &dpa_end)) {
+        return -EINVAL;
+    }
+
+    if (dpa_end > vmr_size + pmr_size + dc_size) {
         return -EINVAL;
     }
 
-- 
2.48.1


Reply via email to