提交 239fb8c4 编写于 作者: E Eric Blake

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.
上级 9dfdeadc
...@@ -57,14 +57,15 @@ ...@@ -57,14 +57,15 @@
__FUNCTION__, __LINE__, __VA_ARGS__) __FUNCTION__, __LINE__, __VA_ARGS__)
#if SIZEOF_LONG < 8 #if SIZEOF_LONG < 8
# define HYPER_TO_TYPE(_type, _to, _from) \ # define HYPER_TO_TYPE(_type, _to, _from) \
do { \ do { \
if ((_from) != (_type)(_from)) { \ if ((_from) != (_type)(_from)) { \
virNetError(VIR_ERR_INTERNAL_ERROR, \ virNetError(VIR_ERR_OVERFLOW, \
_("conversion from hyper to %s overflowed"), #_type); \ _("conversion from hyper to %s overflowed"), \
goto cleanup; \ #_type); \
} \ goto cleanup; \
(_to) = (_from); \ } \
(_to) = (_from); \
} while (0) } while (0)
# define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from) # define HYPER_TO_LONG(_to, _from) HYPER_TO_TYPE(long, _to, _from)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* Description: Provides the interfaces of the libvirt library to handle * Description: Provides the interfaces of the libvirt library to handle
* errors raised while using the library. * 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 * See COPYING.LIB for the License of this software
* *
...@@ -246,6 +246,7 @@ typedef enum { ...@@ -246,6 +246,7 @@ typedef enum {
VIR_ERR_AUTH_CANCELLED = 79, /* authentication cancelled */ VIR_ERR_AUTH_CANCELLED = 79, /* authentication cancelled */
VIR_ERR_NO_DOMAIN_METADATA = 80, /* The metadata is not present */ VIR_ERR_NO_DOMAIN_METADATA = 80, /* The metadata is not present */
VIR_ERR_MIGRATE_UNSAFE = 81, /* Migration is not safe */ VIR_ERR_MIGRATE_UNSAFE = 81, /* Migration is not safe */
VIR_ERR_OVERFLOW = 82, /* integer overflow */
} virErrorNumber; } virErrorNumber;
/** /**
......
...@@ -8507,10 +8507,14 @@ virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus, ...@@ -8507,10 +8507,14 @@ virDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
} }
/* Perform some argument validation common to all implementations. */ /* Perform some argument validation common to all implementations. */
if (nvcpus < 1 || (unsigned short) nvcpus != nvcpus) { if (nvcpus < 1) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error; goto error;
} }
if ((unsigned short) nvcpus != nvcpus) {
virLibDomainError(VIR_ERR_OVERFLOW, _("input too large: %u"), nvcpus);
goto error;
}
conn = domain->conn; conn = domain->conn;
if (conn->driver->domainSetVcpusFlags) { if (conn->driver->domainSetVcpusFlags) {
...@@ -8774,11 +8778,15 @@ virDomainGetVcpuPinInfo(virDomainPtr domain, int ncpumaps, ...@@ -8774,11 +8778,15 @@ virDomainGetVcpuPinInfo(virDomainPtr domain, int ncpumaps,
return -1; return -1;
} }
if (ncpumaps < 1 || !cpumaps || maplen <= 0 || if (ncpumaps < 1 || !cpumaps || maplen <= 0) {
INT_MULTIPLY_OVERFLOW(ncpumaps, maplen)) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error; 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. */ /* At most one of these two flags should be set. */
if ((flags & VIR_DOMAIN_AFFECT_LIVE) && if ((flags & VIR_DOMAIN_AFFECT_LIVE) &&
...@@ -8853,11 +8861,15 @@ virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo, ...@@ -8853,11 +8861,15 @@ virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
/* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not
try to memcpy anything into a NULL pointer. */ try to memcpy anything into a NULL pointer. */
if (!cpumaps ? maplen != 0 if (!cpumaps ? maplen != 0 : maplen <= 0) {
: (maplen <= 0 || INT_MULTIPLY_OVERFLOW(maxinfo, maplen))) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error; 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; conn = domain->conn;
...@@ -18618,11 +18630,15 @@ int virDomainGetCPUStats(virDomainPtr domain, ...@@ -18618,11 +18630,15 @@ int virDomainGetCPUStats(virDomainPtr domain,
if (start_cpu < -1 || if (start_cpu < -1 ||
(start_cpu == -1 && ncpus != 1) || (start_cpu == -1 && ncpus != 1) ||
((params == NULL) != (nparams == 0)) || ((params == NULL) != (nparams == 0)) ||
(ncpus == 0 && params != NULL) || (ncpus == 0 && params != NULL)) {
(nparams && ncpus > UINT_MAX / nparams)) {
virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__); virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
goto error; 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, if (VIR_DRV_SUPPORTS_FEATURE(domain->conn->driver, domain->conn,
VIR_DRV_FEATURE_TYPED_PARAM_STRING)) VIR_DRV_FEATURE_TYPED_PARAM_STRING))
flags |= VIR_TYPED_PARAM_STRING_OKAY; flags |= VIR_TYPED_PARAM_STRING_OKAY;
......
...@@ -7371,7 +7371,7 @@ qemuDomainBlockResize(virDomainPtr dom, ...@@ -7371,7 +7371,7 @@ qemuDomainBlockResize(virDomainPtr dom,
/* We prefer operating on bytes. */ /* We prefer operating on bytes. */
if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) { if ((flags & VIR_DOMAIN_BLOCK_RESIZE_BYTES) == 0) {
if (size > ULLONG_MAX / 1024) { if (size > ULLONG_MAX / 1024) {
qemuReportError(VIR_ERR_INVALID_ARG, qemuReportError(VIR_ERR_OVERFLOW,
_("size must be less than %llu"), _("size must be less than %llu"),
ULLONG_MAX / 1024); ULLONG_MAX / 1024);
return -1; return -1;
......
...@@ -1238,6 +1238,12 @@ virErrorMsg(virErrorNumber error, const char *info) ...@@ -1238,6 +1238,12 @@ virErrorMsg(virErrorNumber error, const char *info)
else else
errmsg = _("Unsafe migration: %s"); errmsg = _("Unsafe migration: %s");
break; break;
case VIR_ERR_OVERFLOW:
if (!info)
errmsg = _("numerical overflow");
else
errmsg = _("numerical overflow: %s");
break;
} }
return (errmsg); return (errmsg);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册