Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > ebe084c140192657f9094e135a84202c > files > 128

libvirt-0.8.2-29.el5.src.rpm

From f9d84acbc1ba44cdb09726ff8e48bb2d0de60527 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Wed, 29 Jun 2011 14:28:45 +0800
Subject: [PATCH] remote: protect against integer overflow
To: libvir-list@redhat.com

5.6.z: https://bugzilla.redhat.com/show_bug.cgi?id=717206

Integer overflow and remote code are never a nice mix.

This has existed since commit 56cd414.

* src/libvirt.c (virDomainGetVcpus): Reject overflow up front.
* src/remote/remote_driver.c (remoteDomainGetVcpus): Avoid overflow
on sending rpc.
* daemon/remote.c (remoteDispatchDomainGetVcpus): Avoid overflow on
receiving rpc.
(cherry picked from commit 774b21c163845170c9ffa873f5720d318812eaf6)

Conflicts:

    daemon/remote.c
        src/libvirt.c
        src/remote/remote_driver.c

Change to internal.h required to avoid backporting 89d994ad.

Signed-off-by: Daniel Veillard <veillard@redhat.com>
---
 daemon/remote.c            |    3 ++-
 src/internal.h             |   17 +++++++++++++++++
 src/libvirt.c              |    4 ++--
 src/remote/remote_driver.c |    3 ++-
 4 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/daemon/remote.c b/daemon/remote.c
index 1739f0d..9c09593 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1681,7 +1681,8 @@ remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
         return -1;
     }
 
-    if (args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) {
+    if (INT_MULTIPLY_OVERFLOW(args->maxinfo, args->maplen) ||
+        args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) {
         virDomainFree(dom);
         remoteDispatchFormatError (rerr, "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX"));
         return -1;
diff --git a/src/internal.h b/src/internal.h
index fab3e11..f3587ce 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -226,4 +226,21 @@
         }                                                               \
     } while (0)
 
+/* RHEL-specific: we don't want to update gnulib in z-stream, so this
+ * backports just one required macro from newer gnulib's intprops.h.
+ * This version requires that both a and b are 'int', rather than
+ * the fully type-generic version from gnulib.  */
+# define INT_MULTIPLY_OVERFLOW(a, b)            \
+    ((b) < 0                                    \
+     ? ((a) < 0                                 \
+        ? (a) < INT_MAX / (b)                   \
+        : (b) == -1                             \
+        ? 0                                     \
+        : INT_MIN / (b) < (a))                  \
+     : (b) == 0                                 \
+     ? 0                                        \
+     : ((a) < 0                                 \
+        ? (a) < INT_MIN / (b)                   \
+        : INT_MAX / (b) < (a)))
+
 #endif                          /* __VIR_INTERNAL_H__ */
diff --git a/src/libvirt.c b/src/libvirt.c
index 9c76111..f55de22 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -5232,8 +5232,8 @@ virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
 
     /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not
        try to memcpy anything into a NULL pointer.  */
-    if ((cpumaps == NULL && maplen != 0)
-        || (cpumaps && maplen <= 0)) {
+    if (!cpumaps ? maplen != 0
+        : (maplen <= 0 || INT_MULTIPLY_OVERFLOW(maxinfo, maplen))) {
         virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
         goto error;
     }
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 2d18935..e66b65c 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2465,7 +2465,8 @@ remoteDomainGetVcpus (virDomainPtr domain,
                     maxinfo, REMOTE_VCPUINFO_MAX);
         goto done;
     }
-    if (maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
+    if (INT_MULTIPLY_OVERFLOW(maxinfo, maplen) ||
+        maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
         remoteError(VIR_ERR_RPC,
                     _("vCPU map buffer length exceeds maximum: %d > %d"),
                     maxinfo * maplen, REMOTE_CPUMAPS_MAX);
-- 
1.7.4.4