diff --git a/daemon/remote.c b/daemon/remote.c index 39302cc3bd..0dd4f2e354 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -57,14 +57,15 @@ __FUNCTION__, __LINE__, __VA_ARGS__) #if SIZEOF_LONG < 8 -# define HYPER_TO_TYPE(_type, _to, _from) \ - do { \ - if ((_from) != (_type)(_from)) { \ - virNetError(VIR_ERR_INTERNAL_ERROR, \ - _("conversion from hyper to %s overflowed"), #_type); \ - goto cleanup; \ - } \ - (_to) = (_from); \ +# define HYPER_TO_TYPE(_type, _to, _from) \ + do { \ + if ((_from) != (_type)(_from)) { \ + virNetError(VIR_ERR_OVERFLOW, \ + _("conversion from hyper to %s overflowed"), \ + #_type); \ + goto cleanup; \ + } \ + (_to) = (_from); \ } while (0) # define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from) diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index a3f9199abd..38ac15e05c 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -4,7 +4,7 @@ * Description: Provides the interfaces of the libvirt library to handle * errors raised while using the library. * - * Copy: Copyright (C) 2006, 2010-2011 Red Hat, Inc. + * Copy: Copyright (C) 2006, 2010-2012 Red Hat, Inc. * * See COPYING.LIB for the License of this software * @@ -246,6 +246,7 @@ typedef enum { VIR_ERR_AUTH_CANCELLED = 79, /* authentication cancelled */ VIR_ERR_NO_DOMAIN_METADATA = 80, /* The metadata is not present */ VIR_ERR_MIGRATE_UNSAFE = 81, /* Migration is not safe */ + VIR_ERR_OVERFLOW = 82, /* integer overflow */ } virErrorNumber; /** diff --git a/src/libvirt.c b/src/libvirt.c index 5de6e6800c..21b4766088 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -8507,10 +8507,14 @@ virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus, } /* Perform some argument validation common to all implementations. */ - if (nvcpus < 1 || (unsigned short) nvcpus != nvcpus) { + if (nvcpus < 1) { virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); goto error; } + if ((unsigned short) nvcpus != nvcpus) { + virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u"), nvcpus); + goto error; + } conn = domain->conn; if (conn->driver->domainSetVcpusFlags) { @@ -8774,11 +8778,15 @@ virDomainGetVcpuPinInfo(virDomainPtr domain, int ncpumaps, return -1; } - if (ncpumaps < 1 || !cpumaps || maplen <= 0 || - INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) { + if (ncpumaps < 1 || !cpumaps || maplen <= 0) { virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); goto error; } + if (INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) { + virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"), + ncpumaps, maplen); + goto error; + } /* At most one of these two flags should be set. */ if ((flags & VIR_DOMAIN_AFFECT_LIVE) && @@ -8853,11 +8861,15 @@ virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not try to memcpy anything into a NULL pointer. */ - if (!cpumaps ? maplen != 0 - : (maplen <= 0 || INT_MULTIPLY_OVERFLOW(maxinfo, maplen))) { + if (!cpumaps ? maplen != 0 : maplen <= 0) { virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); goto error; } + if (cpumaps && INT_MULTIPLY_OVERFLOW(maxinfo, maplen)) { + virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %d * %d"), + maxinfo, maplen); + goto error; + } conn = domain->conn; @@ -18618,11 +18630,15 @@ int virDomainGetCPUStats(virDomainPtr domain, if (start_cpu < -1 || (start_cpu == -1 && ncpus != 1) || ((params == NULL) != (nparams == 0)) || - (ncpus == 0 && params != NULL) || - (nparams && ncpus > UINT_MAX / nparams)) { + (ncpus == 0 && params != NULL)) { virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); goto error; } + if (nparams && ncpus > UINT_MAX / nparams) { + virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u * %u"), + nparams, ncpus); + goto error; + } if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn, VIR_DRV_FEATURE_TYPED_PARAM_STRING)) flags |= VIR_TYPED_PARAM_STRING_OKAY; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index ddb381a655..b364b2c3c1 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7371,7 +7371,7 @@ qemuDomainBlockResize(virDomainPtr dom, /* We prefer operating on bytes. */ if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) { if (size > ULLONG_MAX / 1024) { - qemuReportError(VIR_ERR_INVALID_ARG, + qemuReportError(VIR_ERR_OVERFLOW, _("size must be less than %llu"), ULLONG_MAX / 1024); return -1; diff --git a/src/util/virterror.c b/src/util/virterror.c index 48c61a2e12..b4e496ac77 100644 --- a/src/util/virterror.c +++ b/src/util/virterror.c @@ -1238,6 +1238,12 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("Unsafe migration: %s"); break; + case VIR_ERR_OVERFLOW: + if (!info) + errmsg = _("numerical overflow"); + else + errmsg = _("numerical overflow: %s"); + break; } return (errmsg); }