mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 17:34:18 +03:00
api: add overflow error
Overflow can be user-induced, so it deserves more than being called an internal error. Note that in general, 32-bit platforms have far more places to trigger this error (anywhere the public API used 'unsigned long' but the other side of the connection is a 64-bit server); but some are possible on 64-bit platforms (where the public API computes the product of two numbers). * include/libvirt/virterror.h (VIR_ERR_OVERFLOW): New error. * src/util/virterror.c (virErrorMsg): Translate it. * src/libvirt.c (virDomainSetVcpusFlags, virDomainGetVcpuPinInfo) (virDomainGetVcpus, virDomainGetCPUStats): Use it. * daemon/remote.c (HYPER_TO_TYPE): Likewise. * src/qemu/qemu_driver.c (qemuDomainBlockResize): Likewise.
This commit is contained in:
parent
9dfdeadc8a
commit
239fb8c46b
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user