From: Michal Privoznik <[email protected]>

The virDomainGetInfo() fills virDomainInfo structure for given
domain. The struct contains memory and maxMem members (among
others) to store current and maximum memory for the domain. Both
members are of 'unsigned long' type. Now, inside the ESX driver's
implementation (esxDomainGetInfo()) these values are stored in a
variables of int64_t and int32_t, respectively. But since both
values, as reported by hypervisor are in MiB, they are multiplied
by 1024 because we report memory sizes in KiB. Well, for very
large guests, and 32bit hosts, unsigned long might not be large
enough to hold the value. Check for overflow and also in case of
'maxMem' (which is multiplied directly) specify the type of
'1024' constant to ensure proper typecast before multiplication.

Resolves: https://gitlab.com/libvirt/libvirt/-/work_items/937
Signed-off-by: Michal Privoznik <[email protected]>
---
 src/esx/esx_driver.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 75bbd07750..daca30aeca 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2088,7 +2088,16 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr 
info)
                 goto cleanup;
             }
 
-            info->maxMem = dynamicProperty->val->int32 * 1024; /* Scale from 
megabyte to kilobyte */
+            if (VIR_MULTIPLY_ADD_IS_OVERFLOW(ULONG_MAX,
+                                             dynamicProperty->val->int32, 
1024, 0)) {
+                virReportError(VIR_ERR_OVERFLOW,
+                               _("the maximum memory value too large: %1$llu"),
+                               (unsigned long long) 
dynamicProperty->val->int32);
+                goto cleanup;
+            }
+
+            /* Scale from megabyte to kilobyte */
+            info->maxMem = dynamicProperty->val->int32 * 1024UL;
         } else if (STREQ(dynamicProperty->name, "config.hardware.numCPU")) {
             if (esxVI_AnyType_ExpectType(dynamicProperty->val,
                                          esxVI_Type_Int) < 0) {
@@ -2105,8 +2114,16 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr 
info)
 
             memory_limit = dynamicProperty->val->int64;
 
-            if (memory_limit > 0)
+            if (memory_limit > 0) {
+                if (VIR_MULTIPLY_ADD_IS_OVERFLOW(ULONG_MAX, memory_limit, 
1024, 0)) {
+                    virReportError(VIR_ERR_OVERFLOW,
+                                   _("the current memory value too large: 
%1$llu"),
+                                   (unsigned long long) memory_limit);
+                    goto cleanup;
+                }
+
                 memory_limit *= 1024; /* Scale from megabyte to kilobyte */
+            }
         } else {
             VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
         }
-- 
2.56.0

Reply via email to