Codebase list libvirt / eafb3d8
CVE-2011-2511 Fix integer overflow in VirDomainGetVcpus Closes: #633630 Guido Günther 12 years ago
2 changed file(s) with 153 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 From: =?UTF-8?q?Guido=20G=C3=BCnther?= <agx@sigxcpu.org>
1 Date: Tue, 12 Jul 2011 15:03:09 +0200
2 Subject: Fix integer overflow in VirDomainGetVcpus
3
4 Patch taken from upsteam. (CVE-2011-2511)
5
6 Closes: #633630
7 ---
8 daemon/remote.c | 4 ++-
9 gnulib/lib/intprops.h | 61 ++++++++++++++++++++++++++++++++++++++++++++
10 src/libvirt.c | 5 ++-
11 src/remote/remote_driver.c | 4 ++-
12 4 files changed, 70 insertions(+), 4 deletions(-)
13
14 diff --git a/daemon/remote.c b/daemon/remote.c
15 index a8258ca..4c45044 100644
16 --- a/daemon/remote.c
17 +++ b/daemon/remote.c
18 @@ -58,6 +58,7 @@
19 #include "util.h"
20 #include "stream.h"
21 #include "libvirt/libvirt-qemu.h"
22 +#include "intprops.h"
23
24 #define VIR_FROM_THIS VIR_FROM_REMOTE
25 #define REMOTE_DEBUG(fmt, ...) DEBUG(fmt, __VA_ARGS__)
26 @@ -1697,7 +1698,8 @@ remoteDispatchDomainGetVcpus (struct qemud_server *server ATTRIBUTE_UNUSED,
27 return -1;
28 }
29
30 - if (args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) {
31 + if (INT_MULTIPLY_OVERFLOW(args->maxinfo, args->maplen) ||
32 + args->maxinfo * args->maplen > REMOTE_CPUMAPS_MAX) {
33 virDomainFree(dom);
34 remoteDispatchFormatError (rerr, "%s", _("maxinfo * maplen > REMOTE_CPUMAPS_MAX"));
35 return -1;
36 diff --git a/gnulib/lib/intprops.h b/gnulib/lib/intprops.h
37 index 6c84df6..e842db1 100644
38 --- a/gnulib/lib/intprops.h
39 +++ b/gnulib/lib/intprops.h
40 @@ -82,4 +82,65 @@
41 including the terminating null. */
42 # define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
43
44 +#define INT_MULTIPLY_OVERFLOW(a, b) \
45 + _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
46 +
47 +/* Return 1 if the expression A <op> B would overflow,
48 + where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test,
49 + assuming MIN and MAX are the minimum and maximum for the result type.
50 + Arguments should be free of side effects. */
51 +#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \
52 + op_result_overflow (a, b, \
53 + _GL_INT_MINIMUM (0 * (b) + (a)), \
54 + _GL_INT_MAXIMUM (0 * (b) + (a)))
55 +
56 +/* The maximum and minimum values for the type of the expression E,
57 + after integer promotion. E should not have side effects. */
58 +#define _GL_INT_MINIMUM(e) \
59 + (_GL_INT_SIGNED (e) \
60 + ? - _GL_INT_TWOS_COMPLEMENT (e) - _GL_SIGNED_INT_MAXIMUM (e) \
61 + : _GL_INT_CONVERT (e, 0))
62 +#define _GL_INT_MAXIMUM(e) \
63 + (_GL_INT_SIGNED (e) \
64 + ? _GL_SIGNED_INT_MAXIMUM (e) \
65 + : _GL_INT_NEGATE_CONVERT (e, 1))
66 +#define _GL_SIGNED_INT_MAXIMUM(e) \
67 + (((_GL_INT_CONVERT (e, 1) << (sizeof ((e) + 0) * CHAR_BIT - 2)) - 1) * 2 + 1)
68 +
69 +/* Return 1 if the integer expression E, after integer promotion, has
70 + a signed type. */
71 +#define _GL_INT_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
72 +
73 +/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
74 + <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00406.html>. */
75 +#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v))
76 +
77 +/* Return an integer value, converted to the same type as the integer
78 + expression E after integer type promotion. V is the unconverted value. */
79 +#define _GL_INT_CONVERT(e, v) (0 * (e) + (v))
80 +
81 +/* True if the signed integer expression E uses two's complement. */
82 +#define _GL_INT_TWOS_COMPLEMENT(e) (~ _GL_INT_CONVERT (e, 0) == -1)
83 +
84 +#define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \
85 + (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \
86 + || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))
87 +
88 +/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
89 + See above for restrictions. Avoid && and || as they tickle
90 + bugs in Sun C 5.11 2010/08/13 and other compilers; see
91 + <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00401.html>. */
92 +#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \
93 + ((b) < 0 \
94 + ? ((a) < 0 \
95 + ? (a) < (max) / (b) \
96 + : (b) == -1 \
97 + ? 0 \
98 + : (min) / (b) < (a)) \
99 + : (b) == 0 \
100 + ? 0 \
101 + : ((a) < 0 \
102 + ? (a) < (min) / (b) \
103 + : (max) / (b) < (a)))
104 +
105 #endif /* GL_INTPROPS_H */
106 diff --git a/src/libvirt.c b/src/libvirt.c
107 index 5e5a758..6981852 100644
108 --- a/src/libvirt.c
109 +++ b/src/libvirt.c
110 @@ -39,6 +39,7 @@
111 #include "uuid.h"
112 #include "util.h"
113 #include "memory.h"
114 +#include "intprops.h"
115
116 #ifndef WITH_DRIVER_MODULES
117 # ifdef WITH_TEST
118 @@ -5218,8 +5219,8 @@ virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
119
120 /* Ensure that domainGetVcpus (aka remoteDomainGetVcpus) does not
121 try to memcpy anything into a NULL pointer. */
122 - if ((cpumaps == NULL && maplen != 0)
123 - || (cpumaps && maplen <= 0)) {
124 + if (!cpumaps ? maplen != 0
125 + : (maplen <= 0 || INT_MULTIPLY_OVERFLOW(maxinfo, maplen))) {
126 virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
127 goto error;
128 }
129 diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
130 index 5fab9c1..11b2e21 100644
131 --- a/src/remote/remote_driver.c
132 +++ b/src/remote/remote_driver.c
133 @@ -82,6 +82,7 @@
134 #include "util.h"
135 #include "event.h"
136 #include "ignore-value.h"
137 +#include "intprops.h"
138
139 #define VIR_FROM_THIS VIR_FROM_REMOTE
140
141 @@ -2500,7 +2501,8 @@ remoteDomainGetVcpus (virDomainPtr domain,
142 maxinfo, REMOTE_VCPUINFO_MAX);
143 goto done;
144 }
145 - if (maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
146 + if (INT_MULTIPLY_OVERFLOW(maxinfo, maplen) ||
147 + maxinfo * maplen > REMOTE_CPUMAPS_MAX) {
148 remoteError(VIR_ERR_RPC,
149 _("vCPU map buffer length exceeds maximum: %d > %d"),
150 maxinfo * maplen, REMOTE_CPUMAPS_MAX);
151 --
1111 0012-OpenVZ-Fix-some-overwritten-error-codes.patch
1212 security/0013-Add-missing-checks-for-read-only-connections.patch
1313 security/0014-Make-error-reporting-in-libvirtd-thread-safe.patch
14 security/0015-Fix-integer-overflow-in-VirDomainGetVcpus.patch