[PATCH] esx: Avoid integer overflow in esxDomainGetInfo()
From: Michal Privoznik <mprivozn@redhat.com> 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 <mprivozn@redhat.com> --- 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
participants (1)
-
Michal Privoznik