Hello community, here is the log from the commit of package xen for openSUSE:Factory checked in at 2016-02-07 09:22:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/xen (Old) and /work/SRC/openSUSE:Factory/.xen.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "xen" Changes: -------- --- /work/SRC/openSUSE:Factory/xen/xen.changes 2016-01-08 15:21:58.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.xen.new/xen.changes 2016-02-07 09:22:41.000000000 +0100 @@ -1,0 +2,87 @@ +Wed Jan 27 08:23:26 MST 2016 - [email protected] + +- bsc#963783 - VUL-1: CVE-2016-1981: xen: net: e1000 infinite loop + in start_xmit and e1000_receive_iov routines + CVE-2016-1981-qemuu-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch + CVE-2016-1981-qemut-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch + +------------------------------------------------------------------- +Wed Jan 20 08:21:42 MST 2016 - [email protected] + +- bsc#962758 - VUL-0: CVE-2013-4539: xen: tsc210x: buffer overrun + on invalid state load + CVE-2013-4539-qemut-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch + +------------------------------------------------------------------- +Tue Jan 19 09:23:56 MST 2016 - [email protected] + +- bsc#962632 - VUL-0: CVE-2015-1779: xen: vnc: insufficient + resource limiting in VNC websockets decoder + CVE-2015-1779-qemuu-limit-size-of-HTTP-headers-from-websockets-clients.patch + CVE-2015-1779-qemuu-incrementally-decode-websocket-frames.patch +- bsc#962642 - VUL-0: CVE-2013-4537: xen: ssi-sd: buffer overrun on + invalid state load + CVE-2013-4537-qemut-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch +- bsc#962627 - VUL-0: CVE-2014-7815: xen: vnc: insufficient + bits_per_pixel from the client sanitization + CVE-2014-7815-qemut-vnc-sanitize-bits_per_pixel-from-the-client.patch + +------------------------------------------------------------------- +Mon Jan 18 09:04:10 MST 2016 - [email protected] + +- bsc#962335 - VUL-0: CVE-2013-4538: xen: ssd0323: fix buffer + overun on invalid state + CVE-2013-4538-qemut-ssd0323-fix-buffer-overun-on-invalid-state.patch +- bsc#962360 - VUL-0: CVE-2015-7512: xen: net: pcnet: buffer + overflow in non-loopback mode + CVE-2015-7512-qemuu-net-pcnet-buffer-overflow-in-non-loopback-mode.patch + CVE-2015-7512-qemut-net-pcnet-buffer-overflow-in-non-loopback-mode.patch + +------------------------------------------------------------------- +Wed Jan 13 09:56:52 MST 2016 - [email protected] + +- bsc#961692 - VUL-0: CVE-2016-1714: xen: nvram: OOB r/w access in + processing firmware configurations + CVE-2016-1714-qemuu-fw_cfg-add-check-to-validate-current-entry-value.patch + CVE-2016-1714-qemut-fw_cfg-add-check-to-validate-current-entry-value.patch + +------------------------------------------------------------------- +Mon Jan 11 11:51:45 MST 2016 - [email protected] + +- bsc#961358 - VUL-0: CVE-2015-8613: xen: qemu: scsi: stack based + buffer overflow in megasas_ctrl_get_info + CVE-2015-8613-qemuu-scsi-initialise-info-object-with-appropriate-size.patch +- bsc#961332 - VUL-0: CVE-2016-1568: xen: Qemu: ide: ahci + use-after-free vulnerability in aio port commands + CVE-2016-1568-qemuu-ide-ahci-reset-ncq-object-to-unused-on-error.patch + +------------------------------------------------------------------- +Thu Jan 7 10:38:20 MST 2016 - [email protected] + +- bsc#959695 - missing docs for xen + xen.spec + +------------------------------------------------------------------- +Wed Jan 6 10:38:36 MST 2016 - [email protected] + +- bsc#960862 - VUL-0: CVE-2016-1571: xen: VMX: intercept issue with + INVLPG on non-canonical address (XSA-168) + xsa168.patch +- bsc#960861 - VUL-0: CVE-2016-1570: xen: PV superpage + functionality missing sanity checks (XSA-167) + xsa167.patch +- bsc#960836 - VUL-0: CVE-2015-8744: xen: net: vmxnet3: incorrect + l2 header validation leads to a crash via assert(2) call + CVE-2015-8744-qemuu-net-vmxnet3-incorrect-l2-header-validation-leads-to-crash.patch + +------------------------------------------------------------------- +Tue Jan 5 13:56:08 MST 2016 - [email protected] + +- bsc#960707 - VUL-0: CVE-2015-8745: xen: reading IMR registers + leads to a crash via assert(2) call + CVE-2015-8745-qemuu-net-vmxnet3-read-IMR-registers-instead-of-assert.patch +- bsc#960726 - VUL-0: CVE-2015-8743: xen: ne2000: OOB memory access + in ioport r/w functions + CVE-2015-8743-qemuu-ne2000-OOB-memory-access-in-ioport-rw-functions.patch + +------------------------------------------------------------------- New: ---- CVE-2013-4537-qemut-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch CVE-2013-4538-qemut-ssd0323-fix-buffer-overun-on-invalid-state.patch CVE-2013-4539-qemut-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch CVE-2014-7815-qemut-vnc-sanitize-bits_per_pixel-from-the-client.patch CVE-2015-1779-qemuu-incrementally-decode-websocket-frames.patch CVE-2015-1779-qemuu-limit-size-of-HTTP-headers-from-websockets-clients.patch CVE-2015-7512-qemut-net-pcnet-buffer-overflow-in-non-loopback-mode.patch CVE-2015-7512-qemuu-net-pcnet-buffer-overflow-in-non-loopback-mode.patch CVE-2015-8613-qemuu-scsi-initialise-info-object-with-appropriate-size.patch CVE-2015-8743-qemuu-ne2000-OOB-memory-access-in-ioport-rw-functions.patch CVE-2015-8744-qemuu-net-vmxnet3-incorrect-l2-header-validation-leads-to-crash.patch CVE-2015-8745-qemuu-net-vmxnet3-read-IMR-registers-instead-of-assert.patch CVE-2016-1568-qemuu-ide-ahci-reset-ncq-object-to-unused-on-error.patch CVE-2016-1714-qemut-fw_cfg-add-check-to-validate-current-entry-value.patch CVE-2016-1714-qemuu-fw_cfg-add-check-to-validate-current-entry-value.patch CVE-2016-1981-qemut-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch CVE-2016-1981-qemuu-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch xsa167.patch xsa168.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ xen.spec ++++++ --- /var/tmp/diff_new_pack.XWbtk5/_old 2016-02-07 09:22:45.000000000 +0100 +++ /var/tmp/diff_new_pack.XWbtk5/_new 2016-02-07 09:22:45.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package xen # -# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -15,7 +15,6 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - # needssslcertforbuild Name: xen @@ -163,7 +162,7 @@ %endif %endif -Version: 4.6.0_06 +Version: 4.6.0_08 Release: 0 Summary: Xen Virtualization: Hypervisor (aka VMM aka Microkernel) License: GPL-2.0 @@ -239,6 +238,8 @@ Patch164: xsa164.patch Patch165: xsa165.patch Patch166: xsa166.patch +Patch167: xsa167.patch +Patch168: xsa168.patch # Upstream qemu Patch250: VNC-Support-for-ExtendedKeyEvent-client-message.patch Patch251: 0001-net-move-the-tap-buffer-into-TAPState.patch @@ -260,11 +261,28 @@ Patch267: CVE-2015-7549-qemuu-pci-null-pointer-dereference-issue.patch Patch268: CVE-2015-8558-qemuu-usb-infinite-loop-in-ehci_advance_state-results-in-DoS.patch Patch269: CVE-2015-8568-qemuu-net-vmxnet3-avoid-memory-leakage-in-activate_device.patch +Patch270: CVE-2015-8745-qemuu-net-vmxnet3-read-IMR-registers-instead-of-assert.patch +Patch271: CVE-2015-8744-qemuu-net-vmxnet3-incorrect-l2-header-validation-leads-to-crash.patch +Patch272: CVE-2015-8743-qemuu-ne2000-OOB-memory-access-in-ioport-rw-functions.patch +Patch273: CVE-2015-8613-qemuu-scsi-initialise-info-object-with-appropriate-size.patch +Patch274: CVE-2016-1568-qemuu-ide-ahci-reset-ncq-object-to-unused-on-error.patch +Patch275: CVE-2016-1714-qemuu-fw_cfg-add-check-to-validate-current-entry-value.patch +Patch276: CVE-2016-1714-qemut-fw_cfg-add-check-to-validate-current-entry-value.patch +Patch277: CVE-2013-4538-qemut-ssd0323-fix-buffer-overun-on-invalid-state.patch +Patch278: CVE-2015-7512-qemuu-net-pcnet-buffer-overflow-in-non-loopback-mode.patch +Patch279: CVE-2015-7512-qemut-net-pcnet-buffer-overflow-in-non-loopback-mode.patch +Patch280: CVE-2014-7815-qemut-vnc-sanitize-bits_per_pixel-from-the-client.patch +Patch281: CVE-2013-4537-qemut-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch +Patch282: CVE-2015-1779-qemuu-incrementally-decode-websocket-frames.patch +Patch283: CVE-2015-1779-qemuu-limit-size-of-HTTP-headers-from-websockets-clients.patch +Patch284: CVE-2013-4539-qemut-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch +Patch285: CVE-2016-1981-qemuu-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch +Patch286: CVE-2016-1981-qemut-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch # Our platform specific patches -Patch301: xen-destdir.patch -Patch302: vif-bridge-no-iptables.patch -Patch303: vif-bridge-tap-fix.patch -Patch304: xl-conf-default-bridge.patch +Patch321: xen-destdir.patch +Patch322: vif-bridge-no-iptables.patch +Patch323: vif-bridge-tap-fix.patch +Patch324: xl-conf-default-bridge.patch # Needs to go upstream Patch330: suspend_evtchn_lock.patch Patch331: xenpaging.doc.patch @@ -565,6 +583,8 @@ %patch164 -p1 %patch165 -p1 %patch166 -p1 +%patch167 -p1 +%patch168 -p1 # Upstream qemu patches %patch250 -p1 %patch251 -p1 @@ -586,11 +606,28 @@ %patch267 -p1 %patch268 -p1 %patch269 -p1 +%patch270 -p1 +%patch271 -p1 +%patch272 -p1 +%patch273 -p1 +%patch274 -p1 +%patch275 -p1 +%patch276 -p1 +%patch277 -p1 +%patch278 -p1 +%patch279 -p1 +%patch280 -p1 +%patch281 -p1 +%patch282 -p1 +%patch283 -p1 +%patch284 -p1 +%patch285 -p1 +%patch286 -p1 # Our platform specific patches -%patch301 -p1 -%patch302 -p1 -%patch303 -p1 -%patch304 -p1 +%patch321 -p1 +%patch322 -p1 +%patch323 -p1 +%patch324 -p1 # Needs to go upstream %patch330 -p1 %patch331 -p1 @@ -855,8 +892,9 @@ install -m 644 $name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/ done for name in vtpm.txt crashdb.txt \ - xenpaging.txt xl-disk-configuration.txt xl-network-configuration.markdown \ - xl-numa-placement.markdown; do + xenpaging.txt xl-disk-configuration.txt pci-device-reservations.txt \ + xl-network-configuration.markdown xl-numa-placement.markdown \ + xen-command-line.markdown xenstore-paths.markdown; do install -m 644 docs/misc/$name $RPM_BUILD_ROOT/%{_defaultdocdir}/xen/misc/ done ++++++ CVE-2013-4537-qemut-ssi-sd-fix-buffer-overrun-on-invalid-state-load.patch ++++++ References: bsc#962642 CVE-2013-4537 Subject: ssi-sd: fix buffer overrun on invalid state load From: Michael S. Tsirkin [email protected] Mon Apr 28 16:08:14 2014 +0300 Date: Mon May 5 22:15:03 2014 +0200: Git: a9c380db3b8c6af19546a68145c8d1438a09c92b CVE-2013-4537 s->arglen is taken from wire and used as idx in ssi_sd_transfer(). Validate it before access. Signed-off-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Juan Quintela <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ssi-sd.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/ssi-sd.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ssi-sd.c @@ -221,8 +221,17 @@ static int ssi_sd_load(QEMUFile *f, void for (i = 0; i < 5; i++) s->response[i] = qemu_get_be32(f); s->arglen = qemu_get_be32(f); + if (s->mode == SSI_SD_CMDARG && + (s->arglen < 0 || s->arglen >= ARRAY_SIZE(s->cmdarg))) { + return -EINVAL; + } s->response_pos = qemu_get_be32(f); s->stopping = qemu_get_be32(f); + if (s->mode == SSI_SD_RESPONSE && + (s->response_pos < 0 || s->response_pos >= ARRAY_SIZE(s->response) || + (!s->stopping && s->arglen > ARRAY_SIZE(s->response)))) { + return -EINVAL; + } return 0; } ++++++ CVE-2013-4538-qemut-ssd0323-fix-buffer-overun-on-invalid-state.patch ++++++ References: bsc#962335 CVE-2013-4538 s->cmd_len used as index in ssd0323_transfer() to store 32-bit field. Possible this field might then be supplied by guest to overwrite a return addr somewhere. Same for row/col fields, which are indicies into framebuffer array. To fix validate after load. Signed-off-by: Michael S. Tsirkin <address@hidden> --- hw/display/ssd0323.c | 3 +++ 1 file changed, 3 insertions(+) Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ssd0323.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/ssd0323.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/ssd0323.c @@ -304,6 +304,9 @@ static int ssd0323_load(QEMUFile *f, voi return -EINVAL; s->cmd_len = qemu_get_be32(f); + if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) { + return -EINVAL; + } s->cmd = qemu_get_be32(f); for (i = 0; i < 8; i++) s->cmd_data[i] = qemu_get_be32(f); ++++++ CVE-2013-4539-qemut-tsc210x-fix-buffer-overrun-on-invalid-state-load.patch ++++++ Subject: tsc210x: fix buffer overrun on invalid state load From: Michael S. Tsirkin [email protected] Thu Apr 3 19:52:09 2014 +0300 Date: Mon May 5 22:15:02 2014 +0200: Git: 5193be3be35f29a35bc465036cd64ad60d43385f CVE-2013-4539 s->precision, nextprecision, function and nextfunction come from wire and are used as idx into resolution[] in TSC_CUT_RESOLUTION. Validate after load to avoid buffer overrun. Cc: Andreas Färber <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Juan Quintela <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/tsc210x.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/tsc210x.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/tsc210x.c @@ -1077,9 +1077,21 @@ static int tsc210x_load(QEMUFile *f, voi s->enabled = qemu_get_byte(f); s->host_mode = qemu_get_byte(f); s->function = qemu_get_byte(f); + if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) { + return -EINVAL; + } s->nextfunction = qemu_get_byte(f); + if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) { + return -EINVAL; + } s->precision = qemu_get_byte(f); + if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) { + return -EINVAL; + } s->nextprecision = qemu_get_byte(f); + if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) { + return -EINVAL; + } s->filter = qemu_get_byte(f); s->pin_func = qemu_get_byte(f); s->ref = qemu_get_byte(f); ++++++ CVE-2014-7815-qemut-vnc-sanitize-bits_per_pixel-from-the-client.patch ++++++ References: bsc#962627 CVE-2014-7815 Subject: vnc: sanitize bits_per_pixel from the client From: Petr Matousek [email protected] Mon Oct 27 12:41:44 2014 +0100 Date: Tue Oct 28 11:51:04 2014 +0100: Git: e6908bfe8e07f2b452e78e677da1b45b1c0f6829 bits_per_pixel that are less than 8 could result in accessing non-initialized buffers later in the code due to the expectation that bytes_per_pixel value that is used to initialize these buffers is never zero. To fix this check that bits_per_pixel from the client is one of the values that the rfb protocol specification allows. This is CVE-2014-7815. Signed-off-by: Petr Matousek <[email protected]> [ kraxel: apply codestyle fix ] Signed-off-by: Gerd Hoffmann <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c @@ -1633,6 +1633,16 @@ static void set_pixel_format(VncState *v return; } + switch (bits_per_pixel) { + case 8: + case 16: + case 32: + break; + default: + vnc_client_error(vs); + return; + } + vs->clientds = vs->serverds; vs->clientds.pf.rmax = red_max ? red_max : 0xFF; count_bits(vs->clientds.pf.rbits, red_max); ++++++ CVE-2015-1779-qemuu-incrementally-decode-websocket-frames.patch ++++++ References: bsc#962632 CVE-2015-1779 Subject: CVE-2015-1779: incrementally decode websocket frames From: Daniel P. Berrange [email protected] Mon Mar 23 22:58:21 2015 +0000 Date: Wed Apr 1 17:11:34 2015 +0200: Git: a2bebfd6e09d285aa793cae3fb0fc3a39a9fee6e The logic for decoding websocket frames wants to fully decode the frame header and payload, before allowing the VNC server to see any of the payload data. There is no size limit on websocket payloads, so this allows a malicious network client to consume 2^64 bytes in memory in QEMU. It can trigger this denial of service before the VNC server even performs any authentication. The fix is to decode the header, and then incrementally decode the payload data as it is needed. With this fix the websocket decoder will allow at most 4k of data to be buffered before decoding and processing payload. Signed-off-by: Daniel P. Berrange <[email protected]> Signed-off-by: Gerd Hoffmann <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc-ws.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/ui/vnc-ws.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc-ws.c @@ -115,7 +115,7 @@ long vnc_client_read_ws(VncState *vs) { int ret, err; uint8_t *payload; - size_t payload_size, frame_size; + size_t payload_size, header_size; VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, vs->ws_input.capacity, vs->ws_input.offset); buffer_reserve(&vs->ws_input, 4096); @@ -125,18 +125,39 @@ long vnc_client_read_ws(VncState *vs) } vs->ws_input.offset += ret; - /* make sure that nothing is left in the ws_input buffer */ + ret = 0; + /* consume as much of ws_input buffer as possible */ do { - err = vncws_decode_frame(&vs->ws_input, &payload, - &payload_size, &frame_size); - if (err <= 0) { - return err; + if (vs->ws_payload_remain == 0) { + err = vncws_decode_frame_header(&vs->ws_input, + &header_size, + &vs->ws_payload_remain, + &vs->ws_payload_mask); + if (err <= 0) { + return err; + } + + buffer_advance(&vs->ws_input, header_size); } + if (vs->ws_payload_remain != 0) { + err = vncws_decode_frame_payload(&vs->ws_input, + &vs->ws_payload_remain, + &vs->ws_payload_mask, + &payload, + &payload_size); + if (err < 0) { + return err; + } + if (err == 0) { + return ret; + } + ret += err; - buffer_reserve(&vs->input, payload_size); - buffer_append(&vs->input, payload, payload_size); + buffer_reserve(&vs->input, payload_size); + buffer_append(&vs->input, payload, payload_size); - buffer_advance(&vs->ws_input, frame_size); + buffer_advance(&vs->ws_input, payload_size); + } } while (vs->ws_input.offset > 0); return ret; @@ -274,15 +295,14 @@ void vncws_encode_frame(Buffer *output, buffer_append(output, payload, payload_size); } -int vncws_decode_frame(Buffer *input, uint8_t **payload, - size_t *payload_size, size_t *frame_size) +int vncws_decode_frame_header(Buffer *input, + size_t *header_size, + size_t *payload_remain, + WsMask *payload_mask) { unsigned char opcode = 0, fin = 0, has_mask = 0; - size_t header_size = 0; - uint32_t *payload32; + size_t payload_len; WsHeader *header = (WsHeader *)input->buffer; - WsMask mask; - int i; if (input->offset < WS_HEAD_MIN_LEN + 4) { /* header not complete */ @@ -292,7 +312,7 @@ int vncws_decode_frame(Buffer *input, ui fin = (header->b0 & 0x80) >> 7; opcode = header->b0 & 0x0f; has_mask = (header->b1 & 0x80) >> 7; - *payload_size = header->b1 & 0x7f; + payload_len = header->b1 & 0x7f; if (opcode == WS_OPCODE_CLOSE) { /* disconnect */ @@ -309,40 +329,57 @@ int vncws_decode_frame(Buffer *input, ui return -2; } - if (*payload_size < 126) { - header_size = 6; - mask = header->u.m; - } else if (*payload_size == 126 && input->offset >= 8) { - *payload_size = be16_to_cpu(header->u.s16.l16); - header_size = 8; - mask = header->u.s16.m16; - } else if (*payload_size == 127 && input->offset >= 14) { - *payload_size = be64_to_cpu(header->u.s64.l64); - header_size = 14; - mask = header->u.s64.m64; + if (payload_len < 126) { + *payload_remain = payload_len; + *header_size = 6; + *payload_mask = header->u.m; + } else if (payload_len == 126 && input->offset >= 8) { + *payload_remain = be16_to_cpu(header->u.s16.l16); + *header_size = 8; + *payload_mask = header->u.s16.m16; + } else if (payload_len == 127 && input->offset >= 14) { + *payload_remain = be64_to_cpu(header->u.s64.l64); + *header_size = 14; + *payload_mask = header->u.s64.m64; } else { /* header not complete */ return 0; } - *frame_size = header_size + *payload_size; + return 1; +} - if (input->offset < *frame_size) { - /* frame not complete */ +int vncws_decode_frame_payload(Buffer *input, + size_t *payload_remain, WsMask *payload_mask, + uint8_t **payload, size_t *payload_size) +{ + size_t i; + uint32_t *payload32; + + *payload = input->buffer; + /* If we aren't at the end of the payload, then drop + * off the last bytes, so we're always multiple of 4 + * for purpose of unmasking, except at end of payload + */ + if (input->offset < *payload_remain) { + *payload_size = input->offset - (input->offset % 4); + } else { + *payload_size = *payload_remain; + } + if (*payload_size == 0) { return 0; } - - *payload = input->buffer + header_size; + *payload_remain -= *payload_size; /* unmask frame */ /* process 1 frame (32 bit op) */ payload32 = (uint32_t *)(*payload); for (i = 0; i < *payload_size / 4; i++) { - payload32[i] ^= mask.u; + payload32[i] ^= payload_mask->u; } /* process the remaining bytes (if any) */ for (i *= 4; i < *payload_size; i++) { - (*payload)[i] ^= mask.c[i % 4]; + (*payload)[i] ^= payload_mask->c[i % 4]; } return 1; Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc-ws.h =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/ui/vnc-ws.h +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc-ws.h @@ -83,7 +83,12 @@ long vnc_client_read_ws(VncState *vs); void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size); void vncws_encode_frame(Buffer *output, const void *payload, const size_t payload_size); -int vncws_decode_frame(Buffer *input, uint8_t **payload, - size_t *payload_size, size_t *frame_size); +int vncws_decode_frame_header(Buffer *input, + size_t *header_size, + size_t *payload_remain, + WsMask *payload_mask); +int vncws_decode_frame_payload(Buffer *input, + size_t *payload_remain, WsMask *payload_mask, + uint8_t **payload, size_t *payload_size); #endif /* __QEMU_UI_VNC_WS_H */ Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc.h =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/ui/vnc.h +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc.h @@ -302,6 +302,8 @@ struct VncState #ifdef CONFIG_VNC_WS Buffer ws_input; Buffer ws_output; + size_t ws_payload_remain; + WsMask ws_payload_mask; #endif /* current output mode information */ VncWritePixels *write_pixels; ++++++ CVE-2015-1779-qemuu-limit-size-of-HTTP-headers-from-websockets-clients.patch ++++++ References: bsc#962632 CVE-2015-1779 Subject: CVE-2015-1779: limit size of HTTP headers from websockets clients From: Daniel P. Berrange [email protected] Mon Mar 23 22:58:22 2015 +0000 Date: Wed Apr 1 17:12:55 2015 +0200: Git: 2cdb5e142fb93e875fa53c52864ef5eb8d5d8b41 The VNC server websockets decoder will read and buffer data from websockets clients until it sees the end of the HTTP headers, as indicated by \r\n\r\n. In theory this allows a malicious to trick QEMU into consuming an arbitrary amount of RAM. In practice, because QEMU runs g_strstr_len() across the buffered header data, it will spend increasingly long burning CPU time searching for the substring match and less & less time reading data. So while this does cause arbitrary memory growth, the bigger problem is that QEMU will be burning 100% of available CPU time. A novnc websockets client typically sends headers of around 512 bytes in length. As such it is reasonable to place a 4096 byte limit on the amount of data buffered while searching for the end of HTTP headers. Signed-off-by: Daniel P. Berrange <[email protected]> Signed-off-by: Gerd Hoffmann <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc-ws.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/ui/vnc-ws.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/ui/vnc-ws.c @@ -89,8 +89,11 @@ void vncws_handshake_read(void *opaque) VncState *vs = opaque; uint8_t *handshake_end; long ret; - buffer_reserve(&vs->ws_input, 4096); - ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); + /* Typical HTTP headers from novnc are 512 bytes, so limiting + * total header size to 4096 is easily enough. */ + size_t want = 4096 - vs->ws_input.offset; + buffer_reserve(&vs->ws_input, want); + ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want); if (!ret) { if (vs->csock == -1) { @@ -107,6 +110,9 @@ void vncws_handshake_read(void *opaque) vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); + } else if (vs->ws_input.offset >= 4096) { + VNC_DEBUG("End of headers not found in first 4096 bytes\n"); + vnc_client_error(vs); } } ++++++ CVE-2015-7512-qemut-net-pcnet-buffer-overflow-in-non-loopback-mode.patch ++++++ References: bsc#962360 CVE-2015-7512 Backends could provide a packet whose length is greater than buffer size. Check for this and truncate the packet to avoid rx buffer overflow in this case. Cc: Prasad J Pandit <address@hidden> Cc: address@hidden Signed-off-by: Jason Wang <address@hidden> --- hw/net/pcnet.c | 6 ++++++ 1 file changed, 6 insertions(+) Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/pcnet.c @@ -1133,6 +1133,12 @@ static void pcnet_receive(void *opaque, int pktcount = 0; if (!s->looptest) { + if (size > 4092) { +#ifdef PCNET_DEBUG_RMD + fprintf(stderr, "pcnet: truncates rx packet.\n"); +#endif + size = 4092; + } memcpy(src, buf, size); /* no need to compute the CRC */ src[size] = 0; ++++++ CVE-2015-7512-qemuu-net-pcnet-buffer-overflow-in-non-loopback-mode.patch ++++++ References: bsc#962360 CVE-2015-7512 Backends could provide a packet whose length is greater than buffer size. Check for this and truncate the packet to avoid rx buffer overflow in this case. Cc: Prasad J Pandit <address@hidden> Cc: address@hidden Signed-off-by: Jason Wang <address@hidden> --- hw/net/pcnet.c | 6 ++++++ 1 file changed, 6 insertions(+) Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/pcnet.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/net/pcnet.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/pcnet.c @@ -1086,6 +1086,12 @@ ssize_t pcnet_receive(NetClientState *nc int pktcount = 0; if (!s->looptest) { + if (size > 4092) { +#ifdef PCNET_DEBUG_RMD + fprintf(stderr, "pcnet: truncates rx packet.\n"); +#endif + size = 4092; + } memcpy(src, buf, size); /* no need to compute the CRC */ src[size] = 0; ++++++ CVE-2015-8613-qemuu-scsi-initialise-info-object-with-appropriate-size.patch ++++++ Reference: bsc#961358 CVE-2015-8613 From: Prasad J Pandit <address@hidden> Date: Mon, 21 Dec 2015 14:48:18 +0530 Subject: [PATCH] scsi: initialise info object with appropriate size While processing controller 'CTRL_GET_INFO' command, the routine 'megasas_ctrl_get_info' overflows the '&info' object size. Use its appropriate size to null initialise it. Reported-by: Qinghao Tang <address@hidden> Signed-off-by: Prasad J Pandit <address@hidden> --- hw/scsi/megasas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/scsi/megasas.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/scsi/megasas.c @@ -721,7 +721,7 @@ static int megasas_ctrl_get_info(Megasas BusChild *kid; int num_pd_disks = 0; - memset(&info, 0x0, cmd->iov_size); + memset(&info, 0x0, dcmd_size); if (cmd->iov_size < dcmd_size) { trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size, dcmd_size); ++++++ CVE-2015-8743-qemuu-ne2000-OOB-memory-access-in-ioport-rw-functions.patch ++++++ From: Prasad J Pandit <address@hidden> While doing ioport r/w operations, ne2000 device emulation suffers from OOB r/w errors. Update respective array bounds check to avoid OOB access. Reported-by: Ling Liu <address@hidden> Signed-off-by: Prasad J Pandit <address@hidden> --- hw/net/ne2000.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) Updated as per review in -> https://lists.gnu.org/archive/html/qemu-devel/2015-12/msg04863.html Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/ne2000.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/net/ne2000.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/ne2000.c @@ -476,8 +476,9 @@ static inline void ne2000_mem_writel(NE2 uint32_t val) { addr &= ~1; /* XXX: check exact behaviour if not even */ - if (addr < 32 || - (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { + if (addr < 32 + || (addr >= NE2000_PMEM_START + && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) { stl_le_p(s->mem + addr, val); } } @@ -506,8 +507,9 @@ static inline uint32_t ne2000_mem_readw( static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr) { addr &= ~1; /* XXX: check exact behaviour if not even */ - if (addr < 32 || - (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { + if (addr < 32 + || (addr >= NE2000_PMEM_START + && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) { return ldl_le_p(s->mem + addr); } else { return 0xffffffff; ++++++ CVE-2015-8744-qemuu-net-vmxnet3-incorrect-l2-header-validation-leads-to-crash.patch ++++++ Subject: net/vmxnet3: Refine l2 header validation From: Dana Rubin [email protected] Tue Aug 18 12:45:55 2015 +0300 Date: Mon Oct 12 13:19:29 2015 +0800: Git: a7278b36fcab9af469563bd7b9dadebe2ae25e48 Validation of l2 header length assumed minimal packet size as eth_header + 2 * vlan_header regardless of the actual protocol. This caused crash for valid non-IP packets shorter than 22 bytes, as 'tx_pkt->packet_type' hasn't been assigned for such packets, and 'vmxnet3_on_tx_done_update_stats()' expects it to be properly set. Refine header length validation in 'vmxnet_tx_pkt_parse_headers'. Check its return value during packet processing flow. As a side effect, in case IPv4 and IPv6 header validation failure, corrupt packets will be dropped. Signed-off-by: Dana Rubin <[email protected]> Signed-off-by: Shmulik Ladkani <[email protected]> Signed-off-by: Jason Wang <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c @@ -729,9 +729,7 @@ static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx) } if (txd.eop) { - if (!s->skip_current_tx_pkt) { - vmxnet_tx_pkt_parse(s->tx_pkt); - + if (!s->skip_current_tx_pkt && vmxnet_tx_pkt_parse(s->tx_pkt)) { if (s->needs_vlan) { vmxnet_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci); } Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet_tx_pkt.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/net/vmxnet_tx_pkt.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet_tx_pkt.c @@ -142,11 +142,24 @@ static bool vmxnet_tx_pkt_parse_headers(struct VmxnetTxPkt *pkt) bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base, ETH_MAX_L2_HDR_LEN); - if (bytes_read < ETH_MAX_L2_HDR_LEN) { + if (bytes_read < sizeof(struct eth_header)) { + l2_hdr->iov_len = 0; + return false; + } + + l2_hdr->iov_len = sizeof(struct eth_header); + switch (be16_to_cpu(PKT_GET_ETH_HDR(l2_hdr->iov_base)->h_proto)) { + case ETH_P_VLAN: + l2_hdr->iov_len += sizeof(struct vlan_header); + break; + case ETH_P_DVLAN: + l2_hdr->iov_len += 2 * sizeof(struct vlan_header); + break; + } + + if (bytes_read < l2_hdr->iov_len) { l2_hdr->iov_len = 0; return false; - } else { - l2_hdr->iov_len = eth_get_l2_hdr_length(l2_hdr->iov_base); } l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len); ++++++ CVE-2015-8745-qemuu-net-vmxnet3-read-IMR-registers-instead-of-assert.patch ++++++ Subject: vmxnet3: Support reading IMR registers on bar0 From: Shmulik Ladkani [email protected] Mon Sep 21 17:09:02 2015 +0300 Date: Mon Oct 12 13:19:29 2015 +0800: Git: c6048f849c7e3f009786df76206e895a69de032c Instead of asserting, return the actual IMR register value. This is aligned with what's returned on ESXi. Signed-off-by: Shmulik Ladkani <[email protected]> Tested-by: Dana Rubin <[email protected]> Signed-off-by: Jason Wang <[email protected]> Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/vmxnet3.c @@ -1108,9 +1108,13 @@ vmxnet3_io_bar0_write(void *opaque, hwad static uint64_t vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size) { + VMXNET3State *s = opaque; + if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR, VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) { - g_assert_not_reached(); + int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR, + VMXNET3_REG_ALIGN); + return s->interrupt_states[l].is_masked; } VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size); ++++++ CVE-2016-1568-qemuu-ide-ahci-reset-ncq-object-to-unused-on-error.patch ++++++ Reference: bsc#961332 CVE-2016-1568 From: Prasad J Pandit <address@hidden> When processing NCQ commands, ACHI device emulation prepares a NCQ transfer object; To which an aio control block(aiocb) object is assigned in 'execute_ncq_command'. In case, when the NCQ command is invalid, the 'aiocb' object is not assigned, and NCQ transfer object is left as 'used'. This leads to a use after free kind of error in 'bdrv_aio_cancel_async' via 'ahci_reset_port'. Reset NCQ transfer object to 'unused' to avoid it. Reported-by: Qinghao Tang <address@hidden> Signed-off-by: Prasad J Pandit <address@hidden> --- hw/ide/ahci.c | 1 + 1 file changed, 1 insertion(+) Update as per review in -> https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg01175.html Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/ide/ahci.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/ide/ahci.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/ide/ahci.c @@ -902,7 +902,10 @@ static void process_ncq_command(AHCIStat ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 2, s->dev[port].port.ifs[0].nb_sectors - 1); - ahci_populate_sglist(&s->dev[port], &ncq_tfs->sglist, 0); + if (ahci_populate_sglist(&s->dev[port], &ncq_tfs->sglist, 0) == -1) { + ncq_tfs->used = 0; + return; + } ncq_tfs->tag = tag; switch(ncq_fis->command) { @@ -943,6 +946,7 @@ static void process_ncq_command(AHCIStat "error: tried to process non-NCQ command as NCQ\n"); } qemu_sglist_destroy(&ncq_tfs->sglist); + ncq_tfs->used = 0; } } ++++++ CVE-2016-1714-qemut-fw_cfg-add-check-to-validate-current-entry-value.patch ++++++ Reference: bsc#961692 CVE-2016-1714 When processing firmware configurations, an OOB r/w access occurs if 's->cur_entry' is set to be invalid(FW_CFG_INVALID=0xffff). Add a check to validate 's->cur_entry' to avoid such access. Reported-by: Donghai Zdh <address@hidden> Signed-off-by: Prasad J Pandit <address@hidden> --- hw/nvram/fw_cfg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) Updated as per review in -> https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg00398.html Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/fw_cfg.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/fw_cfg.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/fw_cfg.c @@ -54,11 +54,15 @@ typedef struct _FWCfgState { static void fw_cfg_write(FWCfgState *s, uint8_t value) { int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); - FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL : + &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; FW_CFG_DPRINTF("write %d\n", value); - if (s->cur_entry & FW_CFG_WRITE_CHANNEL && s->cur_offset < e->len) { + if (s->cur_entry & FW_CFG_WRITE_CHANNEL + && e != NULL + && e->callback + && s->cur_offset < e->len) { e->data[s->cur_offset++] = value; if (s->cur_offset == e->len) { e->callback(e->callback_opaque, e->data); @@ -88,7 +92,8 @@ static int fw_cfg_select(FWCfgState *s, static uint8_t fw_cfg_read(FWCfgState *s) { int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); - FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL : + &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; uint8_t ret; if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len) ++++++ CVE-2016-1714-qemuu-fw_cfg-add-check-to-validate-current-entry-value.patch ++++++ Reference: bsc#961692 CVE-2016-1714 When processing firmware configurations, an OOB r/w access occurs if 's->cur_entry' is set to be invalid(FW_CFG_INVALID=0xffff). Add a check to validate 's->cur_entry' to avoid such access. Reported-by: Donghai Zdh <address@hidden> Signed-off-by: Prasad J Pandit <address@hidden> --- hw/nvram/fw_cfg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) Updated as per review in -> https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg00398.html Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/nvram/fw_cfg.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/nvram/fw_cfg.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/nvram/fw_cfg.c @@ -211,12 +211,15 @@ static void fw_cfg_reboot(FWCfgState *s) static void fw_cfg_write(FWCfgState *s, uint8_t value) { int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); - FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL : + &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; trace_fw_cfg_write(s, value); - if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback && - s->cur_offset < e->len) { + if (s->cur_entry & FW_CFG_WRITE_CHANNEL + && e != NULL + && e->callback + && s->cur_offset < e->len) { e->data[s->cur_offset++] = value; if (s->cur_offset == e->len) { e->callback(e->callback_opaque, e->data); @@ -245,7 +248,8 @@ static int fw_cfg_select(FWCfgState *s, static uint8_t fw_cfg_read(FWCfgState *s) { int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); - FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL : + &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; uint8_t ret; if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len) ++++++ CVE-2016-1981-qemut-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch ++++++ The start_xmit() and e1000_receive_iov() functions implement DMA transfers iterating over a set of descriptors that the guest's e1000 driver prepares: - the TDLEN and RDLEN registers store the total size of the descriptor area, - while the TDH and RDH registers store the offset (in whole tx / rx descriptors) into the area where the transfer is supposed to start. Each time a descriptor is processed, the TDH and RDH register is bumped (as appropriate for the transfer direction). QEMU already contains logic to deal with bogus transfers submitted by the guest: - Normally, the transmit case wants to increase TDH from its initial value to TDT. (TDT is allowed to be numerically smaller than the initial TDH value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe that QEMU currently has here is a check against reaching the original TDH value again -- a complete wraparound, which should never happen. - In the receive case RDH is increased from its initial value until "total_size" bytes have been received; preferably in a single step, or in "s->rxbuf_size" byte steps, if the latter is smaller. However, null RX descriptors are skipped without receiving data, while RDH is incremented just the same. QEMU tries to prevent an infinite loop (processing only null RX descriptors) by detecting whether RDH assumes its original value during the loop. (Again, wrapping from RDLEN to 0 is normal.) What both directions miss is that the guest could program TDLEN and RDLEN so low, and the initial TDH and RDH so high, that these registers will immediately be truncated to zero, and then never reassume their initial values in the loop -- a full wraparound will never occur. The condition that expresses this is: xdh_start >= s->mac_reg[XDLEN] / sizeof(desc) i.e., TDH or RDH start out after the last whole rx or tx descriptor that fits into the TDLEN or RDLEN sized area. This condition could be checked before we enter the loops, but pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for bogus DMA addresses, so we just extend the existing failsafes with the above condition. Cc: "Michael S. Tsirkin" <address@hidden> Cc: Petr Matousek <address@hidden> Cc: Stefano Stabellini <address@hidden> Cc: Prasad Pandit <address@hidden> Cc: Michael Roth <address@hidden> Cc: Jason Wang <address@hidden> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044 Signed-off-by: Laszlo Ersek <address@hidden> Reviewed-by: Jason Wang <address@hidden> --- Notes: Regarding the public posting: we made an honest effort to vet this vulnerability, and the impact seems low -- no host side reads/writes, "just" a DoS (infinite loop). We decided the patch could be posted publicly, for the usual review process. Jason and Prasad checked the patch in the internal discussion already, but comments, improvements etc. are clearly welcome. The CVE request is underway. Thanks. hw/net/e1000.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/e1000.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/hw/e1000.c +++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/hw/e1000.c @@ -537,7 +537,8 @@ start_xmit(E1000State *s) * bogus values to TDT/TDLEN. * there's nothing too intelligent we could do about this. */ - if (s->mac_reg[TDH] == tdh_start) { + if (s->mac_reg[TDH] == tdh_start || + tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) { DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n", tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]); break; @@ -727,7 +728,8 @@ e1000_receive(void *opaque, const uint8_ s->mac_reg[RDH] = 0; s->check_rxov = 1; /* see comment in start_xmit; same here */ - if (s->mac_reg[RDH] == rdh_start) { + if (s->mac_reg[RDH] == rdh_start || + rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) { DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n", rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]); set_ics(s, 0, E1000_ICS_RXO); ++++++ CVE-2016-1981-qemuu-e1000-eliminate-infinite-loops-on-out-of-bounds-transfer.patch ++++++ The start_xmit() and e1000_receive_iov() functions implement DMA transfers iterating over a set of descriptors that the guest's e1000 driver prepares: - the TDLEN and RDLEN registers store the total size of the descriptor area, - while the TDH and RDH registers store the offset (in whole tx / rx descriptors) into the area where the transfer is supposed to start. Each time a descriptor is processed, the TDH and RDH register is bumped (as appropriate for the transfer direction). QEMU already contains logic to deal with bogus transfers submitted by the guest: - Normally, the transmit case wants to increase TDH from its initial value to TDT. (TDT is allowed to be numerically smaller than the initial TDH value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe that QEMU currently has here is a check against reaching the original TDH value again -- a complete wraparound, which should never happen. - In the receive case RDH is increased from its initial value until "total_size" bytes have been received; preferably in a single step, or in "s->rxbuf_size" byte steps, if the latter is smaller. However, null RX descriptors are skipped without receiving data, while RDH is incremented just the same. QEMU tries to prevent an infinite loop (processing only null RX descriptors) by detecting whether RDH assumes its original value during the loop. (Again, wrapping from RDLEN to 0 is normal.) What both directions miss is that the guest could program TDLEN and RDLEN so low, and the initial TDH and RDH so high, that these registers will immediately be truncated to zero, and then never reassume their initial values in the loop -- a full wraparound will never occur. The condition that expresses this is: xdh_start >= s->mac_reg[XDLEN] / sizeof(desc) i.e., TDH or RDH start out after the last whole rx or tx descriptor that fits into the TDLEN or RDLEN sized area. This condition could be checked before we enter the loops, but pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for bogus DMA addresses, so we just extend the existing failsafes with the above condition. Cc: "Michael S. Tsirkin" <address@hidden> Cc: Petr Matousek <address@hidden> Cc: Stefano Stabellini <address@hidden> Cc: Prasad Pandit <address@hidden> Cc: Michael Roth <address@hidden> Cc: Jason Wang <address@hidden> RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044 Signed-off-by: Laszlo Ersek <address@hidden> Reviewed-by: Jason Wang <address@hidden> --- Notes: Regarding the public posting: we made an honest effort to vet this vulnerability, and the impact seems low -- no host side reads/writes, "just" a DoS (infinite loop). We decided the patch could be posted publicly, for the usual review process. Jason and Prasad checked the patch in the internal discussion already, but comments, improvements etc. are clearly welcome. The CVE request is underway. Thanks. hw/net/e1000.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) Index: xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/e1000.c =================================================================== --- xen-4.6.0-testing.orig/tools/qemu-xen-dir-remote/hw/net/e1000.c +++ xen-4.6.0-testing/tools/qemu-xen-dir-remote/hw/net/e1000.c @@ -815,7 +815,8 @@ start_xmit(E1000State *s) * bogus values to TDT/TDLEN. * there's nothing too intelligent we could do about this. */ - if (s->mac_reg[TDH] == tdh_start) { + if (s->mac_reg[TDH] == tdh_start || + tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) { DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n", tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]); break; @@ -1059,7 +1060,8 @@ e1000_receive_iov(NetClientState *nc, co if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) s->mac_reg[RDH] = 0; /* see comment in start_xmit; same here */ - if (s->mac_reg[RDH] == rdh_start) { + if (s->mac_reg[RDH] == rdh_start || + rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) { DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n", rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]); set_ics(s, 0, E1000_ICS_RXO); ++++++ ioemu-vnc-resize.patch ++++++ --- /var/tmp/diff_new_pack.XWbtk5/_old 2016-02-07 09:22:46.000000000 +0100 +++ /var/tmp/diff_new_pack.XWbtk5/_new 2016-02-07 09:22:46.000000000 +0100 @@ -1,8 +1,8 @@ -Index: xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c +Index: xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c =================================================================== ---- xen-4.2.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c -+++ xen-4.2.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c -@@ -1751,6 +1751,25 @@ static int protocol_client_msg(VncState +--- xen-4.6.0-testing.orig/tools/qemu-xen-traditional-dir-remote/vnc.c ++++ xen-4.6.0-testing/tools/qemu-xen-traditional-dir-remote/vnc.c +@@ -1761,6 +1761,25 @@ static int protocol_client_msg(VncState } set_encodings(vs, (int32_t *)(data + 4), limit); ++++++ xsa167.patch ++++++ x86/mm: PV superpage handling lacks sanity checks MMUEXT_{,UN}MARK_SUPER fail to check the input MFN for validity before dereferencing pointers into the superpage frame table. get_superpage() has a similar issue. This is XSA-167. Signed-off-by: Jan Beulich <[email protected]> Acked-by: Ian Campbell <[email protected]> Index: xen-4.6.0-testing/xen/arch/x86/mm.c =================================================================== --- xen-4.6.0-testing.orig/xen/arch/x86/mm.c +++ xen-4.6.0-testing/xen/arch/x86/mm.c @@ -2624,6 +2624,9 @@ int get_superpage(unsigned long mfn, str ASSERT(opt_allow_superpage); + if ( !mfn_valid(mfn | (L1_PAGETABLE_ENTRIES - 1)) ) + return -EINVAL; + spage = mfn_to_spage(mfn); y = spage->type_info; do { @@ -3401,42 +3404,26 @@ long do_mmuext_op( } case MMUEXT_MARK_SUPER: + case MMUEXT_UNMARK_SUPER: { unsigned long mfn = op.arg1.mfn; - if ( unlikely(d != pg_owner) ) - rc = -EPERM; - else if ( mfn & (L1_PAGETABLE_ENTRIES-1) ) - { - MEM_LOG("Unaligned superpage reference mfn %lx", mfn); - okay = 0; - } - else if ( !opt_allow_superpage ) + if ( !opt_allow_superpage ) { MEM_LOG("Superpages disallowed"); rc = -ENOSYS; } - else - rc = mark_superpage(mfn_to_spage(mfn), d); - break; - } - - case MMUEXT_UNMARK_SUPER: - { - unsigned long mfn = op.arg1.mfn; - - if ( unlikely(d != pg_owner) ) + else if ( unlikely(d != pg_owner) ) rc = -EPERM; - else if ( mfn & (L1_PAGETABLE_ENTRIES-1) ) + else if ( mfn & (L1_PAGETABLE_ENTRIES - 1) ) { MEM_LOG("Unaligned superpage reference mfn %lx", mfn); - okay = 0; - } - else if ( !opt_allow_superpage ) - { - MEM_LOG("Superpages disallowed"); - rc = -ENOSYS; + rc = -EINVAL; } + else if ( !mfn_valid(mfn | (L1_PAGETABLE_ENTRIES - 1)) ) + rc = -EINVAL; + else if ( op.cmd == MMUEXT_MARK_SUPER ) + rc = mark_superpage(mfn_to_spage(mfn), d); else rc = unmark_superpage(mfn_to_spage(mfn)); break; ++++++ xsa168.patch ++++++ x86/VMX: prevent INVVPID failure due to non-canonical guest address While INVLPG (and on SVM INVLPGA) don't fault on non-canonical addresses, INVVPID fails (in the "individual address" case) when passed such an address. Since such intercepted INVLPG are effectively no-ops anyway, don't fix this in vmx_invlpg_intercept(), but instead have paging_invlpg() never return true in such a case. This is XSA-168. Signed-off-by: Jan Beulich <[email protected]> Reviewed-by: Andrew Cooper <[email protected]> Acked-by: Ian Campbell <[email protected]> Index: xen-4.6.0-testing/xen/include/asm-x86/paging.h =================================================================== --- xen-4.6.0-testing.orig/xen/include/asm-x86/paging.h +++ xen-4.6.0-testing/xen/include/asm-x86/paging.h @@ -245,7 +245,7 @@ paging_fault(unsigned long va, struct cp * or 0 if it's safe not to do so. */ static inline int paging_invlpg(struct vcpu *v, unsigned long va) { - return paging_get_hostmode(v)->invlpg(v, va); + return is_canonical_address(va) && paging_get_hostmode(v)->invlpg(v, va); } /* Translate a guest virtual address to the frame number that the
