diff options
author | Matthias Maier <tamiko@gentoo.org> | 2017-07-26 13:53:25 -0500 |
---|---|---|
committer | Matthias Maier <tamiko@gentoo.org> | 2017-07-26 13:57:05 -0500 |
commit | 606c4d5b81243fb243bd38a21326e60c3318138c (patch) | |
tree | 0d74f579e78364a23428aba90417ad8abf9f2eae /app-emulation/qemu | |
parent | net-libs/serf: bump. (diff) | |
download | gentoo-606c4d5b81243fb243bd38a21326e60c3318138c.tar.gz gentoo-606c4d5b81243fb243bd38a21326e60c3318138c.tar.bz2 gentoo-606c4d5b81243fb243bd38a21326e60c3318138c.zip |
app-emulation/qemu: security patches
CVE-2017-7539, bug #625850
CVE-2017-10664, bug #623016
CVE-2017-10806, bug #624088
Package-Manager: Portage-2.3.6, Repoman-2.3.3
Diffstat (limited to 'app-emulation/qemu')
-rw-r--r-- | app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10664.patch | 47 | ||||
-rw-r--r-- | app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10806.patch | 50 | ||||
-rw-r--r-- | app-emulation/qemu/files/qemu-2.9.0-CVE-2017-7539.patch | 433 | ||||
-rw-r--r-- | app-emulation/qemu/qemu-2.9.0-r56.ebuild (renamed from app-emulation/qemu/qemu-2.9.0-r55.ebuild) | 4 |
4 files changed, 481 insertions, 53 deletions
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 new file mode 100644 index 000000000000..7db06929cf21 --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10664.patch @@ -0,0 +1,47 @@ +From 041e32b8d9d076980b4e35317c0339e57ab888f1 Mon Sep 17 00:00:00 2001 +From: Max Reitz <mreitz@redhat.com> +Date: Sun, 11 Jun 2017 14:37:14 +0200 +Subject: [PATCH] qemu-nbd: Ignore SIGPIPE + +qemu proper has done so for 13 years +(8a7ddc38a60648257dc0645ab4a05b33d6040063), qemu-img and qemu-io have +done so for four years (526eda14a68d5b3596be715505289b541288ef2a). +Ignoring this signal is especially important in qemu-nbd because +otherwise a client can easily take down the qemu-nbd server by dropping +the connection when the server wants to send something, for example: + +$ qemu-nbd -x foo -f raw -t null-co:// & +[1] 12726 +$ qemu-io -c quit nbd://localhost/bar +can't open device nbd://localhost/bar: No export with name 'bar' available +[1] + 12726 broken pipe qemu-nbd -x foo -f raw -t null-co:// + +In this case, the client sends an NBD_OPT_ABORT and closes the +connection (because it is not required to wait for a reply), but the +server replies with an NBD_REP_ACK (because it is required to reply). + +Signed-off-by: Max Reitz <mreitz@redhat.com> +Message-Id: <20170611123714.31292-1-mreitz@redhat.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +--- + qemu-nbd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/qemu-nbd.c b/qemu-nbd.c +index 9464a0461c..4dd3fd4732 100644 +--- a/qemu-nbd.c ++++ b/qemu-nbd.c +@@ -581,6 +581,10 @@ int main(int argc, char **argv) + sa_sigterm.sa_handler = termsig_handler; + sigaction(SIGTERM, &sa_sigterm, NULL); + ++#ifdef CONFIG_POSIX ++ signal(SIGPIPE, SIG_IGN); ++#endif ++ + module_call_init(MODULE_INIT_TRACE); + qcrypto_init(&error_fatal); + +-- +2.13.0 + 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 new file mode 100644 index 000000000000..0074f5f8c77a --- /dev/null +++ b/app-emulation/qemu/files/qemu-2.9.0-CVE-2017-10806.patch @@ -0,0 +1,50 @@ +From bd4a683505b27adc1ac809f71e918e58573d851d Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann <kraxel@redhat.com> +Date: Tue, 9 May 2017 13:01:28 +0200 +Subject: [PATCH] usb-redir: fix stack overflow in usbredir_log_data +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Don't reinvent a broken wheel, just use the hexdump function we have. + +Impact: low, broken code doesn't run unless you have debug logging +enabled. + +Reported-by: 李强 <liqiang6-s@360.cn> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> +Message-id: 20170509110128.27261-1-kraxel@redhat.com +--- + hw/usb/redirect.c | 13 +------------ + 1 file changed, 1 insertion(+), 12 deletions(-) + +diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c +index b001a27f05..ad5ef783a6 100644 +--- a/hw/usb/redirect.c ++++ b/hw/usb/redirect.c +@@ -229,21 +229,10 @@ static void usbredir_log(void *priv, int level, const char *msg) + static void usbredir_log_data(USBRedirDevice *dev, const char *desc, + const uint8_t *data, int len) + { +- int i, j, n; +- + if (dev->debug < usbredirparser_debug_data) { + return; + } +- +- for (i = 0; i < len; i += j) { +- char buf[128]; +- +- n = sprintf(buf, "%s", desc); +- for (j = 0; j < 8 && i + j < len; j++) { +- n += sprintf(buf + n, " %02X", data[i + j]); +- } +- error_report("%s", buf); +- } ++ qemu_hexdump((char *)data, stderr, desc, len); + } + + /* +-- +2.13.0 + 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 index 0b5987c6623a..3af16977b93b 100644 --- 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 @@ -23,8 +23,281 @@ Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> nbd/server.c | 107 ++++++++++++----------------------------------------------- 1 file changed, 22 insertions(+), 85 deletions(-) +diff --git a/nbd/client.c b/nbd/client.c +index a58fb02..6b74a62 100644 +--- a/nbd/client.c ++++ b/nbd/client.c +@@ -86,9 +86,9 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports); + + */ + +-/* Discard length bytes from channel. Return -errno on failure, or +- * the amount of bytes consumed. */ +-static ssize_t drop_sync(QIOChannel *ioc, size_t size) ++/* Discard length bytes from channel. Return -errno on failure and 0 on ++ * success*/ ++static int drop_sync(QIOChannel *ioc, size_t size) + { + ssize_t ret = 0; + char small[1024]; +@@ -96,14 +96,13 @@ static ssize_t drop_sync(QIOChannel *ioc, size_t size) + + buffer = sizeof(small) >= size ? small : g_malloc(MIN(65536, size)); + while (size > 0) { +- ssize_t count = read_sync(ioc, buffer, MIN(65536, size)); ++ ssize_t count = MIN(65536, size); ++ ret = read_sync(ioc, buffer, MIN(65536, size)); + +- if (count <= 0) { ++ if (ret < 0) { + goto cleanup; + } +- assert(count <= size); + size -= count; +- ret += count; + } + + cleanup: +@@ -136,12 +135,12 @@ static int nbd_send_option_request(QIOChannel *ioc, uint32_t opt, + stl_be_p(&req.option, opt); + stl_be_p(&req.length, len); + +- if (write_sync(ioc, &req, sizeof(req)) != sizeof(req)) { ++ if (write_sync(ioc, &req, sizeof(req)) < 0) { + error_setg(errp, "Failed to send option request header"); + return -1; + } + +- if (len && write_sync(ioc, (char *) data, len) != len) { ++ if (len && write_sync(ioc, (char *) data, len) < 0) { + error_setg(errp, "Failed to send option request data"); + return -1; + } +@@ -170,7 +169,7 @@ static int nbd_receive_option_reply(QIOChannel *ioc, uint32_t opt, + nbd_opt_reply *reply, Error **errp) + { + QEMU_BUILD_BUG_ON(sizeof(*reply) != 20); +- if (read_sync(ioc, reply, sizeof(*reply)) != sizeof(*reply)) { ++ if (read_sync(ioc, reply, sizeof(*reply)) < 0) { + error_setg(errp, "failed to read option reply"); + nbd_send_opt_abort(ioc); + return -1; +@@ -219,7 +218,7 @@ static int nbd_handle_reply_err(QIOChannel *ioc, nbd_opt_reply *reply, + goto cleanup; + } + msg = g_malloc(reply->length + 1); +- if (read_sync(ioc, msg, reply->length) != reply->length) { ++ if (read_sync(ioc, msg, reply->length) < 0) { + error_setg(errp, "failed to read option error message"); + goto cleanup; + } +@@ -321,7 +320,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, + nbd_send_opt_abort(ioc); + return -1; + } +- if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) { ++ if (read_sync(ioc, &namelen, sizeof(namelen)) < 0) { + error_setg(errp, "failed to read option name length"); + nbd_send_opt_abort(ioc); + return -1; +@@ -334,7 +333,7 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, + return -1; + } + if (namelen != strlen(want)) { +- if (drop_sync(ioc, len) != len) { ++ if (drop_sync(ioc, len) < 0) { + error_setg(errp, "failed to skip export name with wrong length"); + nbd_send_opt_abort(ioc); + return -1; +@@ -343,14 +342,14 @@ static int nbd_receive_list(QIOChannel *ioc, const char *want, bool *match, + } + + assert(namelen < sizeof(name)); +- if (read_sync(ioc, name, namelen) != namelen) { ++ if (read_sync(ioc, name, namelen) < 0) { + error_setg(errp, "failed to read export name"); + nbd_send_opt_abort(ioc); + return -1; + } + name[namelen] = '\0'; + len -= namelen; +- if (drop_sync(ioc, len) != len) { ++ if (drop_sync(ioc, len) < 0) { + error_setg(errp, "failed to read export description"); + nbd_send_opt_abort(ioc); + return -1; +@@ -477,7 +476,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + goto fail; + } + +- if (read_sync(ioc, buf, 8) != 8) { ++ if (read_sync(ioc, buf, 8) < 0) { + error_setg(errp, "Failed to read data"); + goto fail; + } +@@ -503,7 +502,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + goto fail; + } + +- if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) { ++ if (read_sync(ioc, &magic, sizeof(magic)) < 0) { + error_setg(errp, "Failed to read magic"); + goto fail; + } +@@ -515,8 +514,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + uint16_t globalflags; + bool fixedNewStyle = false; + +- if (read_sync(ioc, &globalflags, sizeof(globalflags)) != +- sizeof(globalflags)) { ++ if (read_sync(ioc, &globalflags, sizeof(globalflags)) < 0) { + error_setg(errp, "Failed to read server flags"); + goto fail; + } +@@ -534,8 +532,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + } + /* client requested flags */ + clientflags = cpu_to_be32(clientflags); +- if (write_sync(ioc, &clientflags, sizeof(clientflags)) != +- sizeof(clientflags)) { ++ if (write_sync(ioc, &clientflags, sizeof(clientflags)) < 0) { + error_setg(errp, "Failed to send clientflags field"); + goto fail; + } +@@ -573,13 +570,13 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + } + + /* Read the response */ +- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { ++ if (read_sync(ioc, &s, sizeof(s)) < 0) { + error_setg(errp, "Failed to read export length"); + goto fail; + } + *size = be64_to_cpu(s); + +- if (read_sync(ioc, flags, sizeof(*flags)) != sizeof(*flags)) { ++ if (read_sync(ioc, flags, sizeof(*flags)) < 0) { + error_setg(errp, "Failed to read export flags"); + goto fail; + } +@@ -596,14 +593,14 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + goto fail; + } + +- if (read_sync(ioc, &s, sizeof(s)) != sizeof(s)) { ++ if (read_sync(ioc, &s, sizeof(s)) < 0) { + error_setg(errp, "Failed to read export length"); + goto fail; + } + *size = be64_to_cpu(s); + TRACE("Size is %" PRIu64, *size); + +- if (read_sync(ioc, &oldflags, sizeof(oldflags)) != sizeof(oldflags)) { ++ if (read_sync(ioc, &oldflags, sizeof(oldflags)) < 0) { + error_setg(errp, "Failed to read export flags"); + goto fail; + } +@@ -619,7 +616,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, const char *name, uint16_t *flags, + } + + TRACE("Size is %" PRIu64 ", export flags %" PRIx16, *size, *flags); +- if (zeroes && drop_sync(ioc, 124) != 124) { ++ if (zeroes && drop_sync(ioc, 124) < 0) { + error_setg(errp, "Failed to read reserved block"); + goto fail; + } +@@ -744,7 +741,6 @@ int nbd_disconnect(int fd) + ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request) + { + uint8_t buf[NBD_REQUEST_SIZE]; +- ssize_t ret; + + TRACE("Sending request to server: " + "{ .from = %" PRIu64", .len = %" PRIu32 ", .handle = %" PRIu64 +@@ -759,16 +755,7 @@ ssize_t nbd_send_request(QIOChannel *ioc, NBDRequest *request) + stq_be_p(buf + 16, request->from); + stl_be_p(buf + 24, request->len); + +- ret = write_sync(ioc, buf, sizeof(buf)); +- if (ret < 0) { +- return ret; +- } +- +- if (ret != sizeof(buf)) { +- LOG("writing to socket failed"); +- return -EINVAL; +- } +- return 0; ++ return write_sync(ioc, buf, sizeof(buf)); + } + + ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply) +@@ -777,7 +764,7 @@ ssize_t nbd_receive_reply(QIOChannel *ioc, NBDReply *reply) + uint32_t magic; + ssize_t ret; + +- ret = read_sync(ioc, buf, sizeof(buf)); ++ ret = read_sync_eof(ioc, buf, sizeof(buf)); + if (ret <= 0) { + return ret; + } +diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h +index f43d990..e6bbc7c 100644 +--- a/nbd/nbd-internal.h ++++ b/nbd/nbd-internal.h +@@ -94,7 +94,13 @@ + #define NBD_ENOSPC 28 + #define NBD_ESHUTDOWN 108 + +-static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) ++/* read_sync_eof ++ * Tries to read @size bytes from @ioc. Returns number of bytes actually read. ++ * May return a value >= 0 and < size only on EOF, i.e. when iteratively called ++ * qio_channel_readv() returns 0. So, there are no needs to call read_sync_eof ++ * iteratively. ++ */ ++static inline ssize_t read_sync_eof(QIOChannel *ioc, void *buffer, size_t size) + { + struct iovec iov = { .iov_base = buffer, .iov_len = size }; + /* Sockets are kept in blocking mode in the negotiation phase. After +@@ -105,12 +111,32 @@ static inline ssize_t read_sync(QIOChannel *ioc, void *buffer, size_t size) + return nbd_wr_syncv(ioc, &iov, 1, size, true); + } + +-static inline ssize_t write_sync(QIOChannel *ioc, const void *buffer, +- size_t size) ++/* read_sync ++ * Reads @size bytes from @ioc. Returns 0 on success. ++ */ ++static inline int read_sync(QIOChannel *ioc, void *buffer, size_t size) ++{ ++ ssize_t ret = read_sync_eof(ioc, buffer, size); ++ ++ if (ret >= 0 && ret != size) { ++ ret = -EINVAL; ++ } ++ ++ return ret < 0 ? ret : 0; ++} ++ ++/* write_sync ++ * Writes @size bytes to @ioc. Returns 0 on success. ++ */ ++static inline int write_sync(QIOChannel *ioc, const void *buffer, size_t size) + { + struct iovec iov = { .iov_base = (void *) buffer, .iov_len = size }; + +- return nbd_wr_syncv(ioc, &iov, 1, size, false); ++ ssize_t ret = nbd_wr_syncv(ioc, &iov, 1, size, false); ++ ++ assert(ret < 0 || ret == size); ++ ++ return ret < 0 ? ret : 0; + } + + struct NBDTLSHandshakeData { diff --git a/nbd/server.c b/nbd/server.c -index d8bd927013..7f44ef0b15 100644 +index 924a1fe..a1f106b 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -104,69 +104,6 @@ struct NBDClient { @@ -39,7 +312,7 @@ index d8bd927013..7f44ef0b15 100644 - return TRUE; -} - --static int nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) +-static ssize_t nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size) -{ - ssize_t ret; - guint watch; @@ -51,13 +324,14 @@ index d8bd927013..7f44ef0b15 100644 - nbd_negotiate_continue, - qemu_coroutine_self(), - NULL); -- ret = nbd_read(ioc, buffer, size, NULL); +- ret = read_sync(ioc, buffer, size); - g_source_remove(watch); - return ret; - -} - --static int nbd_negotiate_write(QIOChannel *ioc, const void *buffer, size_t size) +-static ssize_t nbd_negotiate_write(QIOChannel *ioc, const void *buffer, +- size_t size) -{ - ssize_t ret; - guint watch; @@ -69,204 +343,259 @@ index d8bd927013..7f44ef0b15 100644 - nbd_negotiate_continue, - qemu_coroutine_self(), - NULL); -- ret = nbd_write(ioc, buffer, size, NULL); +- ret = write_sync(ioc, buffer, size); - g_source_remove(watch); - return ret; -} - --static int nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size) +-static ssize_t nbd_negotiate_drop_sync(QIOChannel *ioc, size_t size) -{ -- ssize_t ret; +- ssize_t ret, dropped = size; - uint8_t *buffer = g_malloc(MIN(65536, size)); - - while (size > 0) { -- size_t count = MIN(65536, size); -- ret = nbd_negotiate_read(ioc, buffer, count); +- ret = nbd_negotiate_read(ioc, buffer, MIN(65536, size)); - if (ret < 0) { - g_free(buffer); - return ret; - } - -- size -= count; +- assert(ret <= size); +- size -= ret; - } - - g_free(buffer); -- return 0; +- return dropped; -} -- + /* Basic flow for negotiation - Server Client -@@ -205,22 +142,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type, +@@ -206,22 +143,22 @@ static int nbd_negotiate_send_rep_len(QIOChannel *ioc, uint32_t type, type, opt, len); magic = cpu_to_be64(NBD_REP_MAGIC); -- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) < 0) { +- if (nbd_negotiate_write(ioc, &magic, sizeof(magic)) != sizeof(magic)) { + if (nbd_write(ioc, &magic, sizeof(magic), NULL) < 0) { LOG("write failed (rep magic)"); return -EINVAL; } opt = cpu_to_be32(opt); -- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) < 0) { +- if (nbd_negotiate_write(ioc, &opt, sizeof(opt)) != sizeof(opt)) { + if (nbd_write(ioc, &opt, sizeof(opt), NULL) < 0) { LOG("write failed (rep opt)"); return -EINVAL; } type = cpu_to_be32(type); -- if (nbd_negotiate_write(ioc, &type, sizeof(type)) < 0) { +- if (nbd_negotiate_write(ioc, &type, sizeof(type)) != sizeof(type)) { + if (nbd_write(ioc, &type, sizeof(type), NULL) < 0) { LOG("write failed (rep type)"); return -EINVAL; } len = cpu_to_be32(len); -- if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) { +- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { + if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) { LOG("write failed (rep data length)"); return -EINVAL; } -@@ -255,7 +192,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type, +@@ -256,7 +193,7 @@ nbd_negotiate_send_rep_err(QIOChannel *ioc, uint32_t type, if (ret < 0) { goto out; } -- if (nbd_negotiate_write(ioc, msg, len) < 0) { +- if (nbd_negotiate_write(ioc, msg, len) != len) { + if (nbd_write(ioc, msg, len, NULL) < 0) { LOG("write failed (error message)"); ret = -EIO; } else { -@@ -286,15 +223,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) +@@ -287,15 +224,15 @@ static int nbd_negotiate_send_rep_list(QIOChannel *ioc, NBDExport *exp) } len = cpu_to_be32(name_len); -- if (nbd_negotiate_write(ioc, &len, sizeof(len)) < 0) { +- if (nbd_negotiate_write(ioc, &len, sizeof(len)) != sizeof(len)) { + if (nbd_write(ioc, &len, sizeof(len), NULL) < 0) { LOG("write failed (name length)"); return -EINVAL; } -- if (nbd_negotiate_write(ioc, name, name_len) < 0) { +- if (nbd_negotiate_write(ioc, name, name_len) != name_len) { + if (nbd_write(ioc, name, name_len, NULL) < 0) { LOG("write failed (name buffer)"); return -EINVAL; } -- if (nbd_negotiate_write(ioc, desc, desc_len) < 0) { +- if (nbd_negotiate_write(ioc, desc, desc_len) != desc_len) { + if (nbd_write(ioc, desc, desc_len, NULL) < 0) { LOG("write failed (description buffer)"); return -EINVAL; } -@@ -308,7 +245,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) +@@ -309,7 +246,7 @@ static int nbd_negotiate_handle_list(NBDClient *client, uint32_t length) NBDExport *exp; if (length) { -- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { +- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { + if (nbd_drop(client->ioc, length, NULL) < 0) { return -EIO; } return nbd_negotiate_send_rep_err(client->ioc, -@@ -339,7 +276,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) +@@ -340,7 +277,7 @@ static int nbd_negotiate_handle_export_name(NBDClient *client, uint32_t length) LOG("Bad length received"); goto fail; } -- if (nbd_negotiate_read(client->ioc, name, length) < 0) { +- if (nbd_negotiate_read(client->ioc, name, length) != length) { + if (nbd_read(client->ioc, name, length, NULL) < 0) { LOG("read failed"); goto fail; } -@@ -372,7 +309,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, +@@ -373,7 +310,7 @@ static QIOChannel *nbd_negotiate_handle_starttls(NBDClient *client, TRACE("Setting up TLS"); ioc = client->ioc; if (length) { -- if (nbd_negotiate_drop_sync(ioc, length) < 0) { +- if (nbd_negotiate_drop_sync(ioc, length) != length) { + if (nbd_drop(ioc, length, NULL) < 0) { return NULL; } nbd_negotiate_send_rep_err(ioc, NBD_REP_ERR_INVALID, NBD_OPT_STARTTLS, -@@ -436,7 +373,7 @@ static int nbd_negotiate_options(NBDClient *client) +@@ -437,8 +374,7 @@ static int nbd_negotiate_options(NBDClient *client) ... Rest of request */ -- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) < 0) { +- if (nbd_negotiate_read(client->ioc, &flags, sizeof(flags)) != +- sizeof(flags)) { + if (nbd_read(client->ioc, &flags, sizeof(flags), NULL) < 0) { LOG("read failed"); return -EIO; } -@@ -462,7 +399,7 @@ static int nbd_negotiate_options(NBDClient *client) +@@ -464,8 +400,7 @@ static int nbd_negotiate_options(NBDClient *client) uint32_t clientflags, length; uint64_t magic; -- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) < 0) { +- if (nbd_negotiate_read(client->ioc, &magic, sizeof(magic)) != +- sizeof(magic)) { + if (nbd_read(client->ioc, &magic, sizeof(magic), NULL) < 0) { LOG("read failed"); return -EINVAL; } -@@ -472,15 +409,15 @@ static int nbd_negotiate_options(NBDClient *client) +@@ -475,15 +410,15 @@ static int nbd_negotiate_options(NBDClient *client) return -EINVAL; } - if (nbd_negotiate_read(client->ioc, &clientflags, -- sizeof(clientflags)) < 0) +- sizeof(clientflags)) != sizeof(clientflags)) { + if (nbd_read(client->ioc, &clientflags, + sizeof(clientflags), NULL) < 0) - { ++ { LOG("read failed"); return -EINVAL; } clientflags = be32_to_cpu(clientflags); -- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) < 0) { +- if (nbd_negotiate_read(client->ioc, &length, sizeof(length)) != +- sizeof(length)) { + if (nbd_read(client->ioc, &length, sizeof(length), NULL) < 0) { LOG("read failed"); return -EINVAL; } -@@ -510,7 +447,7 @@ static int nbd_negotiate_options(NBDClient *client) +@@ -513,7 +448,7 @@ static int nbd_negotiate_options(NBDClient *client) return -EINVAL; default: -- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { +- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { + if (nbd_drop(client->ioc, length, NULL) < 0) { return -EIO; } ret = nbd_negotiate_send_rep_err(client->ioc, -@@ -548,7 +485,7 @@ static int nbd_negotiate_options(NBDClient *client) +@@ -551,7 +486,7 @@ static int nbd_negotiate_options(NBDClient *client) return nbd_negotiate_handle_export_name(client, length); case NBD_OPT_STARTTLS: -- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { +- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { + if (nbd_drop(client->ioc, length, NULL) < 0) { return -EIO; } if (client->tlscreds) { -@@ -567,7 +504,7 @@ static int nbd_negotiate_options(NBDClient *client) +@@ -570,7 +505,7 @@ static int nbd_negotiate_options(NBDClient *client) } break; default: -- if (nbd_negotiate_drop_sync(client->ioc, length) < 0) { +- if (nbd_negotiate_drop_sync(client->ioc, length) != length) { + if (nbd_drop(client->ioc, length, NULL) < 0) { return -EIO; } ret = nbd_negotiate_send_rep_err(client->ioc, -@@ -656,12 +593,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) +@@ -659,12 +594,12 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) TRACE("TLS cannot be enabled with oldstyle protocol"); goto fail; } -- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) < 0) { +- if (nbd_negotiate_write(client->ioc, buf, sizeof(buf)) != sizeof(buf)) { + if (nbd_write(client->ioc, buf, sizeof(buf), NULL) < 0) { LOG("write failed"); goto fail; } } else { -- if (nbd_negotiate_write(client->ioc, buf, 18) < 0) { +- if (nbd_negotiate_write(client->ioc, buf, 18) != 18) { + if (nbd_write(client->ioc, buf, 18, NULL) < 0) { LOG("write failed"); goto fail; } -@@ -676,7 +613,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) +@@ -679,7 +614,7 @@ static coroutine_fn int nbd_negotiate(NBDClientNewData *data) stq_be_p(buf + 18, client->exp->size); stw_be_p(buf + 26, client->exp->nbdflags | myflags); len = client->no_zeroes ? 10 : sizeof(buf) - 18; -- if (nbd_negotiate_write(client->ioc, buf + 18, len) < 0) { +- if (nbd_negotiate_write(client->ioc, buf + 18, len) != len) { + if (nbd_write(client->ioc, buf + 18, len, NULL) < 0) { LOG("write failed"); goto fail; } --- -2.13.0 - +@@ -702,11 +637,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request) + return ret; + } + +- if (ret != sizeof(buf)) { +- LOG("read failed"); +- return -EINVAL; +- } +- + /* Request + [ 0 .. 3] magic (NBD_REQUEST_MAGIC) + [ 4 .. 5] flags (NBD_CMD_FLAG_FUA, ...) +@@ -737,7 +667,6 @@ static ssize_t nbd_receive_request(QIOChannel *ioc, NBDRequest *request) + static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply) + { + uint8_t buf[NBD_REPLY_SIZE]; +- ssize_t ret; + + reply->error = system_errno_to_nbd_errno(reply->error); + +@@ -754,16 +683,7 @@ static ssize_t nbd_send_reply(QIOChannel *ioc, NBDReply *reply) + stl_be_p(buf + 4, reply->error); + stq_be_p(buf + 8, reply->handle); + +- ret = write_sync(ioc, buf, sizeof(buf)); +- if (ret < 0) { +- return ret; +- } +- +- if (ret != sizeof(buf)) { +- LOG("writing to socket failed"); +- return -EINVAL; +- } +- return 0; ++ return write_sync(ioc, buf, sizeof(buf)); + } + + #define MAX_NBD_REQUESTS 16 +@@ -1067,7 +987,7 @@ static ssize_t nbd_co_send_reply(NBDRequestData *req, NBDReply *reply, + rc = nbd_send_reply(client->ioc, reply); + if (rc >= 0) { + ret = write_sync(client->ioc, req->data, len); +- if (ret != len) { ++ if (ret < 0) { + rc = -EIO; + } + } +@@ -1141,7 +1061,7 @@ static ssize_t nbd_co_receive_request(NBDRequestData *req, + if (request->type == NBD_CMD_WRITE) { + TRACE("Reading %" PRIu32 " byte(s)", request->len); + +- if (read_sync(client->ioc, req->data, request->len) != request->len) { ++ if (read_sync(client->ioc, req->data, request->len) < 0) { + LOG("reading from socket failed"); + rc = -EIO; + goto out; diff --git a/app-emulation/qemu/qemu-2.9.0-r55.ebuild b/app-emulation/qemu/qemu-2.9.0-r56.ebuild index 4a7f4b1c5f18..438834b538ed 100644 --- a/app-emulation/qemu/qemu-2.9.0-r55.ebuild +++ b/app-emulation/qemu/qemu-2.9.0-r56.ebuild @@ -205,9 +205,11 @@ PATCHES=( "${FILESDIR}"/${PN}-2.9.0-CVE-2017-9524-2.patch "${FILESDIR}"/${PN}-2.9.0-CVE-2017-9503-1.patch # bug 621184 "${FILESDIR}"/${PN}-2.9.0-CVE-2017-9503-2.patch + "${FILESDIR}"/${PN}-2.9.0-CVE-2017-10664.patch # bug 623016 + "${FILESDIR}"/${PN}-2.9.0-CVE-2017-10806.patch # bug 624088 + "${FILESDIR}"/${PN}-2.9.0-CVE-2017-7539.patch # bug 625850 ) - STRIP_MASK="/usr/share/qemu/palcode-clipper" QA_PREBUILT=" |