1 |
commit: 606c4d5b81243fb243bd38a21326e60c3318138c |
2 |
Author: Matthias Maier <tamiko <AT> gentoo <DOT> org> |
3 |
AuthorDate: Wed Jul 26 18:53:25 2017 +0000 |
4 |
Commit: Matthias Maier <tamiko <AT> gentoo <DOT> org> |
5 |
CommitDate: Wed Jul 26 18:57:05 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=606c4d5b |
7 |
|
8 |
app-emulation/qemu: security patches |
9 |
|
10 |
CVE-2017-7539, bug #625850 |
11 |
CVE-2017-10664, bug #623016 |
12 |
CVE-2017-10806, bug #624088 |
13 |
|
14 |
Package-Manager: Portage-2.3.6, Repoman-2.3.3 |
15 |
|
16 |
.../qemu/files/qemu-2.9.0-CVE-2017-10664.patch | 47 +++ |
17 |
.../qemu/files/qemu-2.9.0-CVE-2017-10806.patch | 50 +++ |
18 |
.../qemu/files/qemu-2.9.0-CVE-2017-7539.patch | 433 ++++++++++++++++++--- |
19 |
...qemu-2.9.0-r55.ebuild => qemu-2.9.0-r56.ebuild} | 4 +- |
20 |
4 files changed, 481 insertions(+), 53 deletions(-) |
21 |
|
22 |
diff --git a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10664.patch b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10664.patch |
23 |
new file mode 100644 |
24 |
index 00000000000..7db06929cf2 |
25 |
--- /dev/null |
26 |
+++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10664.patch |
27 |
@@ -0,0 +1,47 @@ |
28 |
+From 041e32b8d9d076980b4e35317c0339e57ab888f1 Mon Sep 17 00:00:00 2001 |
29 |
+From: Max Reitz <mreitz@××××××.com> |
30 |
+Date: Sun, 11 Jun 2017 14:37:14 +0200 |
31 |
+Subject: [PATCH] qemu-nbd: Ignore SIGPIPE |
32 |
+ |
33 |
+qemu proper has done so for 13 years |
34 |
+(8a7ddc38a60648257dc0645ab4a05b33d6040063), qemu-img and qemu-io have |
35 |
+done so for four years (526eda14a68d5b3596be715505289b541288ef2a). |
36 |
+Ignoring this signal is especially important in qemu-nbd because |
37 |
+otherwise a client can easily take down the qemu-nbd server by dropping |
38 |
+the connection when the server wants to send something, for example: |
39 |
+ |
40 |
+$ qemu-nbd -x foo -f raw -t null-co:// & |
41 |
+[1] 12726 |
42 |
+$ qemu-io -c quit nbd://localhost/bar |
43 |
+can't open device nbd://localhost/bar: No export with name 'bar' available |
44 |
+[1] + 12726 broken pipe qemu-nbd -x foo -f raw -t null-co:// |
45 |
+ |
46 |
+In this case, the client sends an NBD_OPT_ABORT and closes the |
47 |
+connection (because it is not required to wait for a reply), but the |
48 |
+server replies with an NBD_REP_ACK (because it is required to reply). |
49 |
+ |
50 |
+Signed-off-by: Max Reitz <mreitz@××××××.com> |
51 |
+Message-Id: <20170611123714.31292-1-mreitz@××××××.com> |
52 |
+Signed-off-by: Paolo Bonzini <pbonzini@××××××.com> |
53 |
+--- |
54 |
+ qemu-nbd.c | 4 ++++ |
55 |
+ 1 file changed, 4 insertions(+) |
56 |
+ |
57 |
+diff --git a/qemu-nbd.c b/qemu-nbd.c |
58 |
+index 9464a0461c..4dd3fd4732 100644 |
59 |
+--- a/qemu-nbd.c |
60 |
++++ b/qemu-nbd.c |
61 |
+@@ -581,6 +581,10 @@ int main(int argc, char **argv) |
62 |
+ sa_sigterm.sa_handler = termsig_handler; |
63 |
+ sigaction(SIGTERM, &sa_sigterm, NULL); |
64 |
+ |
65 |
++#ifdef CONFIG_POSIX |
66 |
++ signal(SIGPIPE, SIG_IGN); |
67 |
++#endif |
68 |
++ |
69 |
+ module_call_init(MODULE_INIT_TRACE); |
70 |
+ qcrypto_init(&error_fatal); |
71 |
+ |
72 |
+-- |
73 |
+2.13.0 |
74 |
+ |
75 |
|
76 |
diff --git a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10806.patch b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10806.patch |
77 |
new file mode 100644 |
78 |
index 00000000000..0074f5f8c77 |
79 |
--- /dev/null |
80 |
+++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10806.patch |
81 |
@@ -0,0 +1,50 @@ |
82 |
+From bd4a683505b27adc1ac809f71e918e58573d851d Mon Sep 17 00:00:00 2001 |
83 |
+From: Gerd Hoffmann <kraxel@××××××.com> |
84 |
+Date: Tue, 9 May 2017 13:01:28 +0200 |
85 |
+Subject: [PATCH] usb-redir: fix stack overflow in usbredir_log_data |
86 |
+MIME-Version: 1.0 |
87 |
+Content-Type: text/plain; charset=UTF-8 |
88 |
+Content-Transfer-Encoding: 8bit |
89 |
+ |
90 |
+Don't reinvent a broken wheel, just use the hexdump function we have. |
91 |
+ |
92 |
+Impact: low, broken code doesn't run unless you have debug logging |
93 |
+enabled. |
94 |
+ |
95 |
+Reported-by: 李强 <liqiang6-s@×××.cn> |
96 |
+Signed-off-by: Gerd Hoffmann <kraxel@××××××.com> |
97 |
+Message-id: 20170509110128.27261-1-kraxel@××××××.com |
98 |
+--- |
99 |
+ hw/usb/redirect.c | 13 +------------ |
100 |
+ 1 file changed, 1 insertion(+), 12 deletions(-) |
101 |
+ |
102 |
+diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c |
103 |
+index b001a27f05..ad5ef783a6 100644 |
104 |
+--- a/hw/usb/redirect.c |
105 |
++++ b/hw/usb/redirect.c |
106 |
+@@ -229,21 +229,10 @@ static void usbredir_log(void *priv, int level, const char *msg) |
107 |
+ static void usbredir_log_data(USBRedirDevice *dev, const char *desc, |
108 |
+ const uint8_t *data, int len) |
109 |
+ { |
110 |
+- int i, j, n; |
111 |
+- |
112 |
+ if (dev->debug < usbredirparser_debug_data) { |
113 |
+ return; |
114 |
+ } |
115 |
+- |
116 |
+- for (i = 0; i < len; i += j) { |
117 |
+- char buf[128]; |
118 |
+- |
119 |
+- n = sprintf(buf, "%s", desc); |
120 |
+- for (j = 0; j < 8 && i + j < len; j++) { |
121 |
+- n += sprintf(buf + n, " %02X", data[i + j]); |
122 |
+- } |
123 |
+- error_report("%s", buf); |
124 |
+- } |
125 |
++ qemu_hexdump((char *)data, stderr, desc, len); |
126 |
+ } |
127 |
+ |
128 |
+ /* |
129 |
+-- |
130 |
+2.13.0 |
131 |
+ |
132 |
|
133 |
diff --git a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch |
134 |
index 0b5987c6623..3af16977b93 100644 |
135 |
--- a/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch |
136 |
+++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch |
137 |
@@ -23,8 +23,281 @@ Signed-off-by: Paolo Bonzini <pbonzini@××××××.com> |
138 |
nbd/server.c | 107 ++++++++++++----------------------------------------------- |
139 |
1 file changed, 22 insertions(+), 85 deletions(-) |
140 |
|
141 |
+diff --git a/nbd/client.c b/nbd/client.c |
142 |
+index a58fb02..6b74a62 100644 |
143 |
+--- a/nbd/client.c |
144 |
++++ b/nbd/client.c |
145 |
+@@ -86,9 +86,9 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); |
146 |
+ |
147 |
+ */ |
148 |
+ |
149 |
+-/* Discard length bytes from channel. Return -errno on failure, or |
150 |
+- * the amount of bytes consumed. */ |
151 |
+-static ssize_t drop_sync(QIOChannel *ioc, size_t size) |
152 |
++/* Discard length bytes from channel. Return -errno on failure and 0 on |
153 |
++ * success*/ |
154 |
++static int drop_sync(QIOChannel *ioc, size_t size) |
155 |
+ { |
156 |
+ ssize_t ret = 0; |
157 |
+ char small[1024]; |
158 |
+@@ -96,14 +96,13 @@ static ssize_t drop_sync(QIOChannel *ioc, size_t size) |
159 |
+ |
160 |
+ buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size)); |
161 |
+ while (size > 0) { |
162 |
+- ssize_t count = read_sync(ioc, buffer, MIN(65536, size)); |
163 |
++ ssize_t count = MIN(65536, size); |
164 |
++ ret = read_sync(ioc, buffer, MIN(65536, size)); |
165 |
+ |
166 |
+- if (count <= 0) { |
167 |
++ if (ret < 0) { |
168 |
+ goto cleanup; |
169 |
+ } |
170 |
+- assert(count <= size); |
171 |
+ size -= count; |
172 |
+- ret += count; |
173 |
+ } |
174 |
+ |
175 |
+ cleanup: |
176 |
+@@ -136,12 +135,12 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt, |
177 |
+ stl_be_p(&req.option, opt); |
178 |
+ stl_be_p(&req.length, len); |
179 |
+ |
180 |
+- if (write_sync(ioc, &req, sizeof(req)) != sizeof(req)) { |
181 |
++ if (write_sync(ioc, &req, sizeof(req)) < 0) { |
182 |
+ error_setg(errp, "Failed to send option request header"); |
183 |
+ return -1; |
184 |
+ } |
185 |
+ |
186 |
+- if (len && write_sync(ioc, (char *) data, len) != len) { |
187 |
++ if (len && write_sync(ioc, (char *) data, len) < 0) { |
188 |
+ error_setg(errp, "Failed to send option request data"); |
189 |
+ return -1; |
190 |
+ } |
191 |
+@@ -170,7 +169,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt, |
192 |
+ nbd_opt_reply *reply, Error **errp) |
193 |
+ { |
194 |
+ QEMU_BUILD_BUG_ON(sizeof(*reply) != 20); |
195 |
+- if (read_sync(ioc, reply, sizeof(*reply)) != sizeof(*reply)) { |
196 |
++ if (read_sync(ioc, reply, sizeof(*reply)) < 0) { |
197 |
+ error_setg(errp, "failed to read option reply"); |
198 |
+ nbd_send_opt_abort(ioc); |
199 |
+ return -1; |
200 |
+@@ -219,7 +218,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, nbd_opt_reply *reply, |
201 |
+ goto cleanup; |
202 |
+ } |
203 |
+ msg = g_malloc(reply->length + 1); |
204 |
+- if (read_sync(ioc, msg, reply->length) != reply->length) { |
205 |
++ if (read_sync(ioc, msg, reply->length) < 0) { |
206 |
+ error_setg(errp, "failed to read option error message"); |
207 |
+ goto cleanup; |
208 |
+ } |
209 |
+@@ -321,7 +320,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, |
210 |
+ nbd_send_opt_abort(ioc); |
211 |
+ return -1; |
212 |
+ } |
213 |
+- if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) { |
214 |
++ if (read_sync(ioc, &namelen, sizeof(namelen)) < 0) { |
215 |
+ error_setg(errp, "failed to read option name length"); |
216 |
+ nbd_send_opt_abort(ioc); |
217 |
+ return -1; |
218 |
+@@ -334,7 +333,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, |
219 |
+ return -1; |
220 |
+ } |
221 |
+ if (namelen != strlen(want)) { |
222 |
+- if (drop_sync(ioc, len) != len) { |
223 |
++ if (drop_sync(ioc, len) < 0) { |
224 |
+ error_setg(errp, "failed to skip export name with wrong length"); |
225 |
+ nbd_send_opt_abort(ioc); |
226 |
+ return -1; |
227 |
+@@ -343,14 +342,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, |
228 |
+ } |
229 |
+ |
230 |
+ assert(namelen < sizeof(name)); |
231 |
+- if (read_sync(ioc, name, namelen) != namelen) { |
232 |
++ if (read_sync(ioc, name, namelen) < 0) { |
233 |
+ error_setg(errp, "failed to read export name"); |
234 |
+ nbd_send_opt_abort(ioc); |
235 |
+ return -1; |
236 |
+ } |
237 |
+ name[namelen] = '\0'; |
238 |
+ len -= namelen; |
239 |
+- if (drop_sync(ioc, len) != len) { |
240 |
++ if (drop_sync(ioc, len) < 0) { |
241 |
+ error_setg(errp, "failed to read export description"); |
242 |
+ nbd_send_opt_abort(ioc); |
243 |
+ return -1; |
244 |
+@@ -477,7 +476,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
245 |
+ goto fail; |
246 |
+ } |
247 |
+ |
248 |
+- if (read_sync(ioc, buf, 8) != 8) { |
249 |
++ if (read_sync(ioc, buf, 8) < 0) { |
250 |
+ error_setg(errp, "Failed to read data"); |
251 |
+ goto fail; |
252 |
+ } |
253 |
+@@ -503,7 +502,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
254 |
+ goto fail; |
255 |
+ } |
256 |
+ |
257 |
+- if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) { |
258 |
++ if (read_sync(ioc, &magic, sizeof(magic)) < 0) { |
259 |
+ error_setg(errp, "Failed to read magic"); |
260 |
+ goto fail; |
261 |
+ } |
262 |
+@@ -515,8 +514,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
263 |
+ uint16_t globalflags; |
264 |
+ bool fixedNewStyle = false; |
265 |
+ |
266 |
+- if (read_sync(ioc, &globalflags, sizeof(globalflags)) != |
267 |
+- sizeof(globalflags)) { |
268 |
++ if (read_sync(ioc, &globalflags, sizeof(globalflags)) < 0) { |
269 |
+ error_setg(errp, "Failed to read server flags"); |
270 |
+ goto fail; |
271 |
+ } |
272 |
+@@ -534,8 +532,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
273 |
+ } |
274 |
+ /* client requested flags */ |
275 |
+ clientflags = cpu_to_be32(clientflags); |
276 |
+- if (write_sync(ioc, &clientflags, sizeof(clientflags)) != |
277 |
+- sizeof(clientflags)) { |
278 |
++ if (write_sync(ioc, &clientflags, sizeof(clientflags)) < 0) { |
279 |
+ error_setg(errp, "Failed to send clientflags field"); |
280 |
+ goto fail; |
281 |
+ } |
282 |
+@@ -573,13 +570,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
283 |
+ } |
284 |
+ |
285 |
+ /* Read the response */ |
286 |
+- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { |
287 |
++ if (read_sync(ioc, &s, sizeof(s)) < 0) { |
288 |
+ error_setg(errp, "Failed to read export length"); |
289 |
+ goto fail; |
290 |
+ } |
291 |
+ *size = be64_to_cpu(s); |
292 |
+ |
293 |
+- if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) { |
294 |
++ if (read_sync(ioc, flags, sizeof(*flags)) < 0) { |
295 |
+ error_setg(errp, "Failed to read export flags"); |
296 |
+ goto fail; |
297 |
+ } |
298 |
+@@ -596,14 +593,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
299 |
+ goto fail; |
300 |
+ } |
301 |
+ |
302 |
+- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { |
303 |
++ if (read_sync(ioc, &s, sizeof(s)) < 0) { |
304 |
+ error_setg(errp, "Failed to read export length"); |
305 |
+ goto fail; |
306 |
+ } |
307 |
+ *size = be64_to_cpu(s); |
308 |
+ TRACE("Size is %" PRIu64, *size); |
309 |
+ |
310 |
+- if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) { |
311 |
++ if (read_sync(ioc, &oldflags, sizeof(oldflags)) < 0) { |
312 |
+ error_setg(errp, "Failed to read export flags"); |
313 |
+ goto fail; |
314 |
+ } |
315 |
+@@ -619,7 +616,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, |
316 |
+ } |
317 |
+ |
318 |
+ TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags); |
319 |
+- if (zeroes && drop_sync(ioc, 124) != 124) { |
320 |
++ if (zeroes && drop_sync(ioc, 124) < 0) { |
321 |
+ error_setg(errp, "Failed to read reserved block"); |
322 |
+ goto fail; |
323 |
+ } |
324 |
+@@ -744,7 +741,6 @@ int nbd_disconnect(int fd) |
325 |
+ ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request) |
326 |
+ { |
327 |
+ uint8_t buf[NBD_REQUEST_SIZE]; |
328 |
+- ssize_t ret; |
329 |
+ |
330 |
+ TRACE("Sending request to server: " |
331 |
+ "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 |
332 |
+@@ -759,16 +755,7 @@ ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request) |
333 |
+ stq_be_p(buf + 16, request->from); |
334 |
+ stl_be_p(buf + 24, request->len); |
335 |
+ |
336 |
+- ret = write_sync(ioc, buf, sizeof(buf)); |
337 |
+- if (ret < 0) { |
338 |
+- return ret; |
339 |
+- } |
340 |
+- |
341 |
+- if (ret != sizeof(buf)) { |
342 |
+- LOG("writing to socket failed"); |
343 |
+- return -EINVAL; |
344 |
+- } |
345 |
+- return 0; |
346 |
++ return write_sync(ioc, buf, sizeof(buf)); |
347 |
+ } |
348 |
+ |
349 |
+ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply) |
350 |
+@@ -777,7 +764,7 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply) |
351 |
+ uint32_t magic; |
352 |
+ ssize_t ret; |
353 |
+ |
354 |
+- ret = read_sync(ioc, buf, sizeof(buf)); |
355 |
++ ret = read_sync_eof(ioc, buf, sizeof(buf)); |
356 |
+ if (ret <= 0) { |
357 |
+ return ret; |
358 |
+ } |
359 |
+diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h |
360 |
+index f43d990..e6bbc7c 100644 |
361 |
+--- a/nbd/nbd-internal.h |
362 |
++++ b/nbd/nbd-internal.h |
363 |
+@@ -94,7 +94,13 @@ |
364 |
+ #define NBD_ENOSPC 28 |
365 |
+ #define NBD_ESHUTDOWN 108 |
366 |
+ |
367 |
+-static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) |
368 |
++/* read_sync_eof |
369 |
++ * Tries to read @size bytes from @ioc. Returns number of bytes actually read. |
370 |
++ * May return a value >= 0 and < size only on EOF, i.e. when iteratively called |
371 |
++ * qio_channel_readv() returns 0. So, there are no needs to call read_sync_eof |
372 |
++ * iteratively. |
373 |
++ */ |
374 |
++static inline ssize_t read_sync_eof(QIOChannel *ioc, void *buffer, size_t size) |
375 |
+ { |
376 |
+ struct iovec iov = { .iov_base = buffer, .iov_len = size }; |
377 |
+ /* Sockets are kept in blocking mode in the negotiation phase. After |
378 |
+@@ -105,12 +111,32 @@ static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) |
379 |
+ return nbd_wr_syncv(ioc, &iov, 1, size, true); |
380 |
+ } |
381 |
+ |
382 |
+-static inline ssize_t write_sync(QIOChannel *ioc, const void *buffer, |
383 |
+- size_t size) |
384 |
++/* read_sync |
385 |
++ * Reads @size bytes from @ioc. Returns 0 on success. |
386 |
++ */ |
387 |
++static inline int read_sync(QIOChannel *ioc, void *buffer, size_t size) |
388 |
++{ |
389 |
++ ssize_t ret = read_sync_eof(ioc, buffer, size); |
390 |
++ |
391 |
++ if (ret >= 0 && ret != size) { |
392 |
++ ret = -EINVAL; |
393 |
++ } |
394 |
++ |
395 |
++ return ret < 0 ? ret : 0; |
396 |
++} |
397 |
++ |
398 |
++/* write_sync |
399 |
++ * Writes @size bytes to @ioc. Returns 0 on success. |
400 |
++ */ |
401 |
++static inline int write_sync(QIOChannel *ioc, const void *buffer, size_t size) |
402 |
+ { |
403 |
+ struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size }; |
404 |
+ |
405 |
+- return nbd_wr_syncv(ioc, &iov, 1, size, false); |
406 |
++ ssize_t ret = nbd_wr_syncv(ioc, &iov, 1, size, false); |
407 |
++ |
408 |
++ assert(ret < 0 || ret == size); |
409 |
++ |
410 |
++ return ret < 0 ? ret : 0; |
411 |
+ } |
412 |
+ |
413 |
+ struct NBDTLSHandshakeData { |
414 |
diff --git a/nbd/server.c b/nbd/server.c |
415 |
-index d8bd927013..7f44ef0b15 100644 |
416 |
+index 924a1fe..a1f106b 100644 |
417 |
--- a/nbd/server.c |
418 |
+++ b/nbd/server.c |
419 |
@@ -104,69 +104,6 @@ struct NBDClient { |
420 |
@@ -39,7 +312,7 @@ index d8bd927013..7f44ef0b15 100644 |
421 |
- return TRUE; |
422 |
-} |
423 |
- |
424 |
--static int nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) |
425 |
+-static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) |
426 |
-{ |
427 |
- ssize_t ret; |
428 |
- guint watch; |
429 |
@@ -51,13 +324,14 @@ index d8bd927013..7f44ef0b15 100644 |
430 |
- nbd_negotiate_continue, |
431 |
- qemu_coroutine_self(), |
432 |
- NULL); |
433 |
-- ret = nbd_read(ioc, buffer, size, NULL); |
434 |
+- ret = read_sync(ioc, buffer, size); |
435 |
- g_source_remove(watch); |
436 |
- return ret; |
437 |
- |
438 |
-} |
439 |
- |
440 |
--static int nbd_negotiate_write(QIOChannel *ioc, const void *buffer, size_t size) |
441 |
+-static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer, |
442 |
+- size_t size) |
443 |
-{ |
444 |
- ssize_t ret; |
445 |
- guint watch; |
446 |
@@ -69,204 +343,259 @@ index d8bd927013..7f44ef0b15 100644 |
447 |
- nbd_negotiate_continue, |
448 |
- qemu_coroutine_self(), |
449 |
- NULL); |
450 |
-- ret = nbd_write(ioc, buffer, size, NULL); |
451 |
+- ret = write_sync(ioc, buffer, size); |
452 |
- g_source_remove(watch); |
453 |
- return ret; |
454 |
-} |
455 |
- |
456 |
--static int nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size) |
457 |
+-static ssize_t nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size) |
458 |
-{ |
459 |
-- ssize_t ret; |
460 |
+- ssize_t ret, dropped = size; |
461 |
- uint8_t *buffer = g_malloc(MIN(65536, size)); |
462 |
- |
463 |
- while (size > 0) { |
464 |
-- size_t count = MIN(65536, size); |
465 |
-- ret = nbd_negotiate_read(ioc, buffer, count); |
466 |
+- ret = nbd_negotiate_read(ioc, buffer, MIN(65536, size)); |
467 |
- if (ret < 0) { |
468 |
- g_free(buffer); |
469 |
- return ret; |
470 |
- } |
471 |
- |
472 |
-- size -= count; |
473 |
+- assert(ret <= size); |
474 |
+- size -= ret; |
475 |
- } |
476 |
- |
477 |
- g_free(buffer); |
478 |
-- return 0; |
479 |
+- return dropped; |
480 |
-} |
481 |
-- |
482 |
+ |
483 |
/* Basic flow for negotiation |
484 |
|
485 |
- Server Client |
486 |
-@@ -205,22 +142,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type, |
487 |
+@@ -206,22 +143,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type, |
488 |
type, opt, len); |
489 |
|
490 |
magic = cpu_to_be64(NBD_REP_MAGIC); |
491 |
-- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) < 0) { |
492 |
+- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) { |
493 |
+ if (nbd_write(ioc, &magic, sizeof(magic), NULL) < 0) { |
494 |
LOG("write failed (rep magic)"); |
495 |
return -EINVAL; |
496 |
} |
497 |
opt = cpu_to_be32(opt); |
498 |
-- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) < 0) { |
499 |
+- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) != sizeof(opt)) { |
500 |
+ if (nbd_write(ioc, &opt, sizeof(opt), NULL) < 0) { |
501 |
LOG("write failed (rep opt)"); |
502 |
return -EINVAL; |
503 |
} |
504 |
type = cpu_to_be32(type); |
505 |
-- if (nbd_negotiate_write(ioc, &type, sizeof(type)) < 0) { |
506 |
+- if (nbd_negotiate_write(ioc, &type, sizeof(type)) != sizeof(type)) { |
507 |
+ if (nbd_write(ioc, &type, sizeof(type), NULL) < 0) { |
508 |
LOG("write failed (rep type)"); |
509 |
return -EINVAL; |
510 |
} |
511 |
len = cpu_to_be32(len); |
512 |
-- if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) { |
513 |
+- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { |
514 |
+ if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) { |
515 |
LOG("write failed (rep data length)"); |
516 |
return -EINVAL; |
517 |
} |
518 |
-@@ -255,7 +192,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type, |
519 |
+@@ -256,7 +193,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type, |
520 |
if (ret < 0) { |
521 |
goto out; |
522 |
} |
523 |
-- if (nbd_negotiate_write(ioc, msg, len) < 0) { |
524 |
+- if (nbd_negotiate_write(ioc, msg, len) != len) { |
525 |
+ if (nbd_write(ioc, msg, len, NULL) < 0) { |
526 |
LOG("write failed (error message)"); |
527 |
ret = -EIO; |
528 |
} else { |
529 |
-@@ -286,15 +223,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) |
530 |
+@@ -287,15 +224,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) |
531 |
} |
532 |
|
533 |
len = cpu_to_be32(name_len); |
534 |
-- if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) { |
535 |
+- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { |
536 |
+ if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) { |
537 |
LOG("write failed (name length)"); |
538 |
return -EINVAL; |
539 |
} |
540 |
-- if (nbd_negotiate_write(ioc, name, name_len) < 0) { |
541 |
+- if (nbd_negotiate_write(ioc, name, name_len) != name_len) { |
542 |
+ if (nbd_write(ioc, name, name_len, NULL) < 0) { |
543 |
LOG("write failed (name buffer)"); |
544 |
return -EINVAL; |
545 |
} |
546 |
-- if (nbd_negotiate_write(ioc, desc, desc_len) < 0) { |
547 |
+- if (nbd_negotiate_write(ioc, desc, desc_len) != desc_len) { |
548 |
+ if (nbd_write(ioc, desc, desc_len, NULL) < 0) { |
549 |
LOG("write failed (description buffer)"); |
550 |
return -EINVAL; |
551 |
} |
552 |
-@@ -308,7 +245,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) |
553 |
+@@ -309,7 +246,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) |
554 |
NBDExport *exp; |
555 |
|
556 |
if (length) { |
557 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { |
558 |
+- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
559 |
+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
560 |
return -EIO; |
561 |
} |
562 |
return nbd_negotiate_send_rep_err(client->ioc, |
563 |
-@@ -339,7 +276,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) |
564 |
+@@ -340,7 +277,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) |
565 |
LOG("Bad length received"); |
566 |
goto fail; |
567 |
} |
568 |
-- if (nbd_negotiate_read(client->ioc, name, length) < 0) { |
569 |
+- if (nbd_negotiate_read(client->ioc, name, length) != length) { |
570 |
+ if (nbd_read(client->ioc, name, length, NULL) < 0) { |
571 |
LOG("read failed"); |
572 |
goto fail; |
573 |
} |
574 |
-@@ -372,7 +309,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, |
575 |
+@@ -373,7 +310,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, |
576 |
TRACE("Setting up TLS"); |
577 |
ioc = client->ioc; |
578 |
if (length) { |
579 |
-- if (nbd_negotiate_drop_sync(ioc, length) < 0) { |
580 |
+- if (nbd_negotiate_drop_sync(ioc, length) != length) { |
581 |
+ if (nbd_drop(ioc, length, NULL) < 0) { |
582 |
return NULL; |
583 |
} |
584 |
nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS, |
585 |
-@@ -436,7 +373,7 @@ static int nbd_negotiate_options(NBDClient *client) |
586 |
+@@ -437,8 +374,7 @@ static int nbd_negotiate_options(NBDClient *client) |
587 |
... Rest of request |
588 |
*/ |
589 |
|
590 |
-- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) < 0) { |
591 |
+- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) != |
592 |
+- sizeof(flags)) { |
593 |
+ if (nbd_read(client->ioc, &flags, sizeof(flags), NULL) < 0) { |
594 |
LOG("read failed"); |
595 |
return -EIO; |
596 |
} |
597 |
-@@ -462,7 +399,7 @@ static int nbd_negotiate_options(NBDClient *client) |
598 |
+@@ -464,8 +400,7 @@ static int nbd_negotiate_options(NBDClient *client) |
599 |
uint32_t clientflags, length; |
600 |
uint64_t magic; |
601 |
|
602 |
-- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) < 0) { |
603 |
+- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) != |
604 |
+- sizeof(magic)) { |
605 |
+ if (nbd_read(client->ioc, &magic, sizeof(magic), NULL) < 0) { |
606 |
LOG("read failed"); |
607 |
return -EINVAL; |
608 |
} |
609 |
-@@ -472,15 +409,15 @@ static int nbd_negotiate_options(NBDClient *client) |
610 |
+@@ -475,15 +410,15 @@ static int nbd_negotiate_options(NBDClient *client) |
611 |
return -EINVAL; |
612 |
} |
613 |
|
614 |
- if (nbd_negotiate_read(client->ioc, &clientflags, |
615 |
-- sizeof(clientflags)) < 0) |
616 |
+- sizeof(clientflags)) != sizeof(clientflags)) { |
617 |
+ if (nbd_read(client->ioc, &clientflags, |
618 |
+ sizeof(clientflags), NULL) < 0) |
619 |
- { |
620 |
++ { |
621 |
LOG("read failed"); |
622 |
return -EINVAL; |
623 |
} |
624 |
clientflags = be32_to_cpu(clientflags); |
625 |
|
626 |
-- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) < 0) { |
627 |
+- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) != |
628 |
+- sizeof(length)) { |
629 |
+ if (nbd_read(client->ioc, &length, sizeof(length), NULL) < 0) { |
630 |
LOG("read failed"); |
631 |
return -EINVAL; |
632 |
} |
633 |
-@@ -510,7 +447,7 @@ static int nbd_negotiate_options(NBDClient *client) |
634 |
+@@ -513,7 +448,7 @@ static int nbd_negotiate_options(NBDClient *client) |
635 |
return -EINVAL; |
636 |
|
637 |
default: |
638 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { |
639 |
+- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
640 |
+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
641 |
return -EIO; |
642 |
} |
643 |
ret = nbd_negotiate_send_rep_err(client->ioc, |
644 |
-@@ -548,7 +485,7 @@ static int nbd_negotiate_options(NBDClient *client) |
645 |
+@@ -551,7 +486,7 @@ static int nbd_negotiate_options(NBDClient *client) |
646 |
return nbd_negotiate_handle_export_name(client, length); |
647 |
|
648 |
case NBD_OPT_STARTTLS: |
649 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { |
650 |
+- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
651 |
+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
652 |
return -EIO; |
653 |
} |
654 |
if (client->tlscreds) { |
655 |
-@@ -567,7 +504,7 @@ static int nbd_negotiate_options(NBDClient *client) |
656 |
+@@ -570,7 +505,7 @@ static int nbd_negotiate_options(NBDClient *client) |
657 |
} |
658 |
break; |
659 |
default: |
660 |
-- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { |
661 |
+- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { |
662 |
+ if (nbd_drop(client->ioc, length, NULL) < 0) { |
663 |
return -EIO; |
664 |
} |
665 |
ret = nbd_negotiate_send_rep_err(client->ioc, |
666 |
-@@ -656,12 +593,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
667 |
+@@ -659,12 +594,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
668 |
TRACE("TLS cannot be enabled with oldstyle protocol"); |
669 |
goto fail; |
670 |
} |
671 |
-- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) < 0) { |
672 |
+- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) != sizeof(buf)) { |
673 |
+ if (nbd_write(client->ioc, buf, sizeof(buf), NULL) < 0) { |
674 |
LOG("write failed"); |
675 |
goto fail; |
676 |
} |
677 |
} else { |
678 |
-- if (nbd_negotiate_write(client->ioc, buf, 18) < 0) { |
679 |
+- if (nbd_negotiate_write(client->ioc, buf, 18) != 18) { |
680 |
+ if (nbd_write(client->ioc, buf, 18, NULL) < 0) { |
681 |
LOG("write failed"); |
682 |
goto fail; |
683 |
} |
684 |
-@@ -676,7 +613,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
685 |
+@@ -679,7 +614,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) |
686 |
stq_be_p(buf + 18, client->exp->size); |
687 |
stw_be_p(buf + 26, client->exp->nbdflags | myflags); |
688 |
len = client->no_zeroes ? 10 : sizeof(buf) - 18; |
689 |
-- if (nbd_negotiate_write(client->ioc, buf + 18, len) < 0) { |
690 |
+- if (nbd_negotiate_write(client->ioc, buf + 18, len) != len) { |
691 |
+ if (nbd_write(client->ioc, buf + 18, len, NULL) < 0) { |
692 |
LOG("write failed"); |
693 |
goto fail; |
694 |
} |
695 |
--- |
696 |
-2.13.0 |
697 |
- |
698 |
+@@ -702,11 +637,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request) |
699 |
+ return ret; |
700 |
+ } |
701 |
+ |
702 |
+- if (ret != sizeof(buf)) { |
703 |
+- LOG("read failed"); |
704 |
+- return -EINVAL; |
705 |
+- } |
706 |
+- |
707 |
+ /* Request |
708 |
+ [ 0 .. 3] magic (NBD_REQUEST_MAGIC) |
709 |
+ [ 4 .. 5] flags (NBD_CMD_FLAG_FUA, ...) |
710 |
+@@ -737,7 +667,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request) |
711 |
+ static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply) |
712 |
+ { |
713 |
+ uint8_t buf[NBD_REPLY_SIZE]; |
714 |
+- ssize_t ret; |
715 |
+ |
716 |
+ reply->error = system_errno_to_nbd_errno(reply->error); |
717 |
+ |
718 |
+@@ -754,16 +683,7 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply) |
719 |
+ stl_be_p(buf + 4, reply->error); |
720 |
+ stq_be_p(buf + 8, reply->handle); |
721 |
+ |
722 |
+- ret = write_sync(ioc, buf, sizeof(buf)); |
723 |
+- if (ret < 0) { |
724 |
+- return ret; |
725 |
+- } |
726 |
+- |
727 |
+- if (ret != sizeof(buf)) { |
728 |
+- LOG("writing to socket failed"); |
729 |
+- return -EINVAL; |
730 |
+- } |
731 |
+- return 0; |
732 |
++ return write_sync(ioc, buf, sizeof(buf)); |
733 |
+ } |
734 |
+ |
735 |
+ #define MAX_NBD_REQUESTS 16 |
736 |
+@@ -1067,7 +987,7 @@ static ssize_t nbd_co_send_reply(NBDRequestData *req, NBDReply *reply, |
737 |
+ rc = nbd_send_reply(client->ioc, reply); |
738 |
+ if (rc >= 0) { |
739 |
+ ret = write_sync(client->ioc, req->data, len); |
740 |
+- if (ret != len) { |
741 |
++ if (ret < 0) { |
742 |
+ rc = -EIO; |
743 |
+ } |
744 |
+ } |
745 |
+@@ -1141,7 +1061,7 @@ static ssize_t nbd_co_receive_request(NBDRequestData *req, |
746 |
+ if (request->type == NBD_CMD_WRITE) { |
747 |
+ TRACE("Reading %" PRIu32 " byte(s)", request->len); |
748 |
+ |
749 |
+- if (read_sync(client->ioc, req->data, request->len) != request->len) { |
750 |
++ if (read_sync(client->ioc, req->data, request->len) < 0) { |
751 |
+ LOG("reading from socket failed"); |
752 |
+ rc = -EIO; |
753 |
+ goto out; |
754 |
|
755 |
diff --git a/app-emulation/qemu/qemu-2.9.0-r55.ebuild b/app-emulation/qemu/qemu-2.9.0-r56.ebuild |
756 |
similarity index 99% |
757 |
rename from app-emulation/qemu/qemu-2.9.0-r55.ebuild |
758 |
rename to app-emulation/qemu/qemu-2.9.0-r56.ebuild |
759 |
index 4a7f4b1c5f1..438834b538e 100644 |
760 |
--- a/app-emulation/qemu/qemu-2.9.0-r55.ebuild |
761 |
+++ b/app-emulation/qemu/qemu-2.9.0-r56.ebuild |
762 |
@@ -205,9 +205,11 @@ PATCHES=( |
763 |
"${FILESDIR}"/${PN}-2.9.0-CVE-2017-9524-2.patch |
764 |
"${FILESDIR}"/${PN}-2.9.0-CVE-2017-9503-1.patch # bug 621184 |
765 |
"${FILESDIR}"/${PN}-2.9.0-CVE-2017-9503-2.patch |
766 |
+ "${FILESDIR}"/${PN}-2.9.0-CVE-2017-10664.patch # bug 623016 |
767 |
+ "${FILESDIR}"/${PN}-2.9.0-CVE-2017-10806.patch # bug 624088 |
768 |
+ "${FILESDIR}"/${PN}-2.9.0-CVE-2017-7539.patch # bug 625850 |
769 |
) |
770 |
|
771 |
- |
772 |
STRIP_MASK="/usr/share/qemu/palcode-clipper" |
773 |
|
774 |
QA_PREBUILT=" |