add CVE fixes

CVE-2017-7539:
   qemu-nbd crashes due to undefined I/O coroutine
 CVE-2017-11434:
   slirp: out-of-bounds read while parsing dhcp options
 CVE-2017-11334:
   exec: oob access during dma operation
 CVE-2017-10806:
   usb-redirect: stack buffer overflow in debug logging
 CVE-2017-10664:
   qemu-nbd: server breaks with SIGPIPE upon client abort
 CVE-2017-9524:
   nbd: segmentation fault due to client non-negotiation
 CVE-2017-9503:
   scsi: null pointer dereference while processing megasas command
master
Wolfgang Bumiller 2017-08-07 10:31:59 +02:00
parent 67af0fa481
commit e74c0f316d
24 changed files with 733 additions and 32 deletions

View File

@ -1,7 +1,7 @@
From 12949af5b296e6a5717df5189647559cc35677a4 Mon Sep 17 00:00:00 2001 From 3949cb837593d29db5c06cef51f405ee3250c4c1 Mon Sep 17 00:00:00 2001
From: Wolfgang Bumiller <w.bumiller@proxmox.com> From: Wolfgang Bumiller <w.bumiller@proxmox.com>
Date: Mon, 4 Jul 2016 15:02:26 +0200 Date: Mon, 4 Jul 2016 15:02:26 +0200
Subject: [PATCH 01/15] Revert "target-i386: disable LINT0 after reset" Subject: [PATCH 01/23] Revert "target-i386: disable LINT0 after reset"
This reverts commit b8eb5512fd8a115f164edbbe897cdf8884920ccb. This reverts commit b8eb5512fd8a115f164edbbe897cdf8884920ccb.
--- ---

View File

@ -1,7 +1,7 @@
From 40bb673c38565bb8660f15f088a85bb0fd12ab82 Mon Sep 17 00:00:00 2001 From e340d6c3321d3eb4e6f7854550cfdc94aa1c8143 Mon Sep 17 00:00:00 2001
From: Anton Nefedov <anton.nefedov@virtuozzo.com> From: Anton Nefedov <anton.nefedov@virtuozzo.com>
Date: Wed, 26 Apr 2017 11:33:15 +0300 Date: Wed, 26 Apr 2017 11:33:15 +0300
Subject: [PATCH 02/15] qemu-img: wait for convert coroutines to complete Subject: [PATCH 02/23] qemu-img: wait for convert coroutines to complete
On error path (like i/o error in one of the coroutines), it's required to On error path (like i/o error in one of the coroutines), it's required to
- wait for coroutines completion before cleaning the common structures - wait for coroutines completion before cleaning the common structures
@ -18,7 +18,7 @@ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1 file changed, 11 insertions(+), 15 deletions(-) 1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c diff --git a/qemu-img.c b/qemu-img.c
index 4f7f458dd2..cf9885b75b 100644 index b9d1ef7bb8..59f4f7f22a 100644
--- a/qemu-img.c --- a/qemu-img.c
+++ b/qemu-img.c +++ b/qemu-img.c
@@ -1761,13 +1761,13 @@ static void coroutine_fn convert_co_do_copy(void *opaque) @@ -1761,13 +1761,13 @@ static void coroutine_fn convert_co_do_copy(void *opaque)

View File

@ -1,7 +1,7 @@
From 7abd8d3ceb29140469c3662fb53de6a4dfe4623e Mon Sep 17 00:00:00 2001 From 80a3ed331899e4710b33c4b2a88f1b7b888d6497 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com> From: Max Reitz <mreitz@redhat.com>
Date: Thu, 13 Apr 2017 17:43:34 +0200 Date: Thu, 13 Apr 2017 17:43:34 +0200
Subject: [PATCH 03/15] block: Do not unref bs->file on error in BD's open Subject: [PATCH 03/23] block: Do not unref bs->file on error in BD's open
The block layer takes care of removing the bs->file child if the block The block layer takes care of removing the bs->file child if the block
driver's bdrv_open()/bdrv_file_open() implementation fails. The block driver's bdrv_open()/bdrv_file_open() implementation fails. The block

View File

@ -1,7 +1,7 @@
From 575b9657b84e7c35d4a378448cdb43939fb5e730 Mon Sep 17 00:00:00 2001 From 952bdc64b03ffc3bdf3529b22f291ad26ef94d1b Mon Sep 17 00:00:00 2001
From: Greg Kurz <groug@kaod.org> From: Greg Kurz <groug@kaod.org>
Date: Thu, 25 May 2017 10:30:13 +0200 Date: Thu, 25 May 2017 10:30:13 +0200
Subject: [PATCH 04/15] 9pfs: local: fix unlink of alien files in mapped-file Subject: [PATCH 04/23] 9pfs: local: fix unlink of alien files in mapped-file
mode mode
When trying to remove a file from a directory, both created in non-mapped When trying to remove a file from a directory, both created in non-mapped

View File

@ -1,7 +1,7 @@
From a2486a266d8df715349ec0e325d0bedc0bdc0557 Mon Sep 17 00:00:00 2001 From 0720bbba9f7ebac6f4f0ae7a65cd687ac6f3c452 Mon Sep 17 00:00:00 2001
From: John Snow <jsnow@redhat.com> From: John Snow <jsnow@redhat.com>
Date: Wed, 10 May 2017 13:39:45 -0400 Date: Wed, 10 May 2017 13:39:45 -0400
Subject: [PATCH 05/15] blockdev: use drained_begin/end for qmp_block_resize Subject: [PATCH 05/23] blockdev: use drained_begin/end for qmp_block_resize
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1447551 Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1447551
@ -23,7 +23,7 @@ Signed-off-by: Kevin Wolf <kwolf@redhat.com>
1 file changed, 2 insertions(+), 3 deletions(-) 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/blockdev.c b/blockdev.c diff --git a/blockdev.c b/blockdev.c
index 43818dade1..d8ff508eff 100644 index 1eeffb0571..1dca232781 100644
--- a/blockdev.c --- a/blockdev.c
+++ b/blockdev.c +++ b/blockdev.c
@@ -2929,10 +2929,9 @@ void qmp_block_resize(bool has_device, const char *device, @@ -2929,10 +2929,9 @@ void qmp_block_resize(bool has_device, const char *device,

View File

@ -1,7 +1,7 @@
From c9d7fd0fd5736afd1f6c508f2b5f1ae0608847bd Mon Sep 17 00:00:00 2001 From 28a204390093e5dfa0b4a2e94c06e807fe777c5f Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com> From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Mon, 8 May 2017 14:07:05 -0400 Date: Mon, 8 May 2017 14:07:05 -0400
Subject: [PATCH 06/15] aio: add missing aio_notify() to aio_enable_external() Subject: [PATCH 06/23] aio: add missing aio_notify() to aio_enable_external()
The main loop uses aio_disable_external()/aio_enable_external() to The main loop uses aio_disable_external()/aio_enable_external() to
temporarily disable processing of external AioContext clients like temporarily disable processing of external AioContext clients like

View File

@ -1,7 +1,7 @@
From 48c670e522857fa54207794d3dfc014b4809079c Mon Sep 17 00:00:00 2001 From 691689ab216143f5fefd8e229ffd91086b9a261e Mon Sep 17 00:00:00 2001
From: Ladi Prosek <lprosek@redhat.com> From: Ladi Prosek <lprosek@redhat.com>
Date: Tue, 30 May 2017 10:59:43 +0200 Date: Tue, 30 May 2017 10:59:43 +0200
Subject: [PATCH 07/15] virtio-serial-bus: Unset hotplug handler when unrealize Subject: [PATCH 07/23] virtio-serial-bus: Unset hotplug handler when unrealize
Virtio serial device controls the lifetime of virtio-serial-bus and Virtio serial device controls the lifetime of virtio-serial-bus and
virtio-serial-bus links back to the device via its hotplug-handler virtio-serial-bus links back to the device via its hotplug-handler

View File

@ -1,7 +1,7 @@
From 129083526210432c2233874be45e47a61c405db0 Mon Sep 17 00:00:00 2001 From 1b7f7a21084578b528c6a3faac29f46c5dbd6408 Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com> From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 2 Jun 2017 10:54:24 +0100 Date: Fri, 2 Jun 2017 10:54:24 +0100
Subject: [PATCH 08/15] virtio-serial: fix segfault on disconnect Subject: [PATCH 08/23] virtio-serial: fix segfault on disconnect
Since commit d4c19cdeeb2f1e474bc426a6da261f1d7346eb5b ("virtio-serial: Since commit d4c19cdeeb2f1e474bc426a6da261f1d7346eb5b ("virtio-serial:
add missing virtio_detach_element() call") the following commands may add missing virtio_detach_element() call") the following commands may

View File

@ -1,7 +1,7 @@
From 1b050be441ffab9c4babec630bbdd14f14c95022 Mon Sep 17 00:00:00 2001 From 02b34affd75f205f50445217ad28ef28002e0bf0 Mon Sep 17 00:00:00 2001
From: Sameeh Jubran <sameeh@daynix.com> From: Sameeh Jubran <sameeh@daynix.com>
Date: Mon, 22 May 2017 14:26:22 +0300 Date: Mon, 22 May 2017 14:26:22 +0300
Subject: [PATCH 09/15] e1000e: Fix ICR "Other" causes clear logic Subject: [PATCH 09/23] e1000e: Fix ICR "Other" causes clear logic
This commit fixes a bug which causes the guest to hang. The bug was This commit fixes a bug which causes the guest to hang. The bug was
observed upon a "receive overrun" (bit #6 of the ICR register) observed upon a "receive overrun" (bit #6 of the ICR register)

View File

@ -1,7 +1,7 @@
From 95166cdeaeaa9d00330483988b818abfcc473efe Mon Sep 17 00:00:00 2001 From 9c4164d74133304aaf7d77001e5ac8a22150df44 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com> From: Kevin Wolf <kwolf@redhat.com>
Date: Mon, 29 May 2017 14:08:32 +0200 Date: Mon, 29 May 2017 14:08:32 +0200
Subject: [PATCH 10/15] mirror: Drop permissions on s->target on completion Subject: [PATCH 10/23] mirror: Drop permissions on s->target on completion
This fixes an assertion failure that was triggered by qemu-iotests 129 This fixes an assertion failure that was triggered by qemu-iotests 129
on some CI host, while the same test case didn't seem to fail on other on some CI host, while the same test case didn't seem to fail on other

View File

@ -1,7 +1,7 @@
From d2eb933639fa12bfa36238c72b1c5a8fb59bdfcd Mon Sep 17 00:00:00 2001 From 1e709e6e073c7907676ea9263a1f92b1bd5fc9ac Mon Sep 17 00:00:00 2001
From: P J P <ppandit@redhat.com> From: P J P <ppandit@redhat.com>
Date: Tue, 25 Apr 2017 18:36:23 +0530 Date: Tue, 25 Apr 2017 18:36:23 +0530
Subject: [PATCH 11/15] vmw_pvscsi: check message ring page count at Subject: [PATCH 11/23] vmw_pvscsi: check message ring page count at
initialisation initialisation
A guest could set the message ring page count to zero, resulting in A guest could set the message ring page count to zero, resulting in

View File

@ -1,7 +1,7 @@
From 56ca431e96a6aadffdccecb882600dc780f13ad9 Mon Sep 17 00:00:00 2001 From 74f9fd9420fadd64a42ee8de780dc6de61864ea8 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com> From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 28 Apr 2017 09:56:12 +0200 Date: Fri, 28 Apr 2017 09:56:12 +0200
Subject: [PATCH 12/15] audio: release capture buffers Subject: [PATCH 12/23] audio: release capture buffers
AUD_add_capture() allocates two buffers which are never released. AUD_add_capture() allocates two buffers which are never released.
Add the missing calls to AUD_del_capture(). Add the missing calls to AUD_del_capture().

View File

@ -1,7 +1,7 @@
From e4f39e928710d19db0a0669b66520236197352aa Mon Sep 17 00:00:00 2001 From e96b198df364a2918896c41a9759b38aaebcf211 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com> From: Gerd Hoffmann <kraxel@redhat.com>
Date: Fri, 28 Apr 2017 10:42:37 +0200 Date: Fri, 28 Apr 2017 10:42:37 +0200
Subject: [PATCH 13/15] input: limit kbd queue depth Subject: [PATCH 13/23] input: limit kbd queue depth
Apply a limit to the number of items we accept into the keyboard queue. Apply a limit to the number of items we accept into the keyboard queue.

View File

@ -1,7 +1,7 @@
From 3bf1e29359a1e22a2ecdffb50f124db275abf5bd Mon Sep 17 00:00:00 2001 From c442fb4a11d8dc527c90bf90a1fd1b15646f4c57 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org> From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Mon, 24 Apr 2017 17:36:34 +0530 Date: Mon, 24 Apr 2017 17:36:34 +0530
Subject: [PATCH 14/15] scsi: avoid an off-by-one error in megasas_mmio_write Subject: [PATCH 14/23] scsi: avoid an off-by-one error in megasas_mmio_write
While reading magic sequence(MFI_SEQ) in megasas_mmio_write, While reading magic sequence(MFI_SEQ) in megasas_mmio_write,
an off-by-one error could occur as 's->adp_reset' index is not an off-by-one error could occur as 's->adp_reset' index is not

View File

@ -1,7 +1,7 @@
From 6364ef68ee01ec566617ffa6982a8d551cec0f75 Mon Sep 17 00:00:00 2001 From 209fb3054000bd3a45da63e3758b9c220fba0a25 Mon Sep 17 00:00:00 2001
From: Greg Kurz <groug@kaod.org> From: Greg Kurz <groug@kaod.org>
Date: Fri, 5 May 2017 14:48:08 +0200 Date: Fri, 5 May 2017 14:48:08 +0200
Subject: [PATCH 15/15] 9pfs: local: forbid client access to metadata Subject: [PATCH 15/23] 9pfs: local: forbid client access to metadata
(CVE-2017-7493) (CVE-2017-7493)
When using the mapped-file security mode, we shouldn't let the client mess When using the mapped-file security mode, we shouldn't let the client mess

View File

@ -0,0 +1,115 @@
From 95a82526f2bfd3e9f0ac65a1f2ed505b2429d9de Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 1 Jun 2017 17:18:23 +0200
Subject: [PATCH 16/23] megasas: do not read DCMD opcode more than once from
frame
Avoid TOC-TOU bugs by storing the DCMD opcode in the MegasasCmd
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/megasas.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 804122ab05..887958481b 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -63,6 +63,7 @@ typedef struct MegasasCmd {
hwaddr pa;
hwaddr pa_size;
+ uint32_t dcmd_opcode;
union mfi_frame *frame;
SCSIRequest *req;
QEMUSGList qsg;
@@ -511,6 +512,7 @@ static MegasasCmd *megasas_enqueue_frame(MegasasState *s,
cmd->context &= (uint64_t)0xFFFFFFFF;
}
cmd->count = count;
+ cmd->dcmd_opcode = -1;
s->busy++;
if (s->consumer_pa) {
@@ -1559,22 +1561,21 @@ static const struct dcmd_cmd_tbl_t {
static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
{
- int opcode;
int retval = 0;
size_t len;
const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
- trace_megasas_handle_dcmd(cmd->index, opcode);
+ cmd->dcmd_opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+ trace_megasas_handle_dcmd(cmd->index, cmd->dcmd_opcode);
if (megasas_map_dcmd(s, cmd) < 0) {
return MFI_STAT_MEMORY_NOT_AVAILABLE;
}
- while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
+ while (cmdptr->opcode != -1 && cmdptr->opcode != cmd->dcmd_opcode) {
cmdptr++;
}
len = cmd->iov_size;
if (cmdptr->opcode == -1) {
- trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
+ trace_megasas_dcmd_unhandled(cmd->index, cmd->dcmd_opcode, len);
retval = megasas_dcmd_dummy(s, cmd);
} else {
trace_megasas_dcmd_enter(cmd->index, cmdptr->desc, len);
@@ -1589,13 +1590,11 @@ static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
SCSIRequest *req)
{
- int opcode;
int retval = MFI_STAT_OK;
int lun = req->lun;
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
- trace_megasas_dcmd_internal_finish(cmd->index, opcode, lun);
- switch (opcode) {
+ trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun);
+ switch (cmd->dcmd_opcode) {
case MFI_DCMD_PD_GET_INFO:
retval = megasas_pd_get_info_submit(req->dev, lun, cmd);
break;
@@ -1603,7 +1602,7 @@ static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
retval = megasas_ld_get_info_submit(req->dev, lun, cmd);
break;
default:
- trace_megasas_dcmd_internal_invalid(cmd->index, opcode);
+ trace_megasas_dcmd_internal_invalid(cmd->index, cmd->dcmd_opcode);
retval = MFI_STAT_INVALID_DCMD;
break;
}
@@ -1824,7 +1823,6 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
{
MegasasCmd *cmd = req->hba_private;
uint8_t *buf;
- uint32_t opcode;
trace_megasas_io_complete(cmd->index, len);
@@ -1834,8 +1832,7 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
}
buf = scsi_req_get_buf(req);
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
- if (opcode == MFI_DCMD_PD_GET_INFO && cmd->iov_buf) {
+ if (cmd->dcmd_opcode == MFI_DCMD_PD_GET_INFO && cmd->iov_buf) {
struct mfi_pd_info *info = cmd->iov_buf;
if (info->inquiry_data[0] == 0x7f) {
@@ -1846,7 +1843,7 @@ static void megasas_xfer_complete(SCSIRequest *req, uint32_t len)
memcpy(info->vpd_page83, buf, len);
}
scsi_req_continue(req);
- } else if (opcode == MFI_DCMD_LD_GET_INFO) {
+ } else if (cmd->dcmd_opcode == MFI_DCMD_LD_GET_INFO) {
struct mfi_ld_info *info = cmd->iov_buf;
if (cmd->iov_buf) {
--
2.11.0

View File

@ -0,0 +1,125 @@
From d312b31b5c5e8e36c6e283bdb04b4784dd2e023b Mon Sep 17 00:00:00 2001
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Thu, 1 Jun 2017 17:26:14 +0200
Subject: [PATCH 17/23] megasas: always store SCSIRequest* into MegasasCmd
This ensures that the request is unref'ed properly, and avoids a
segmentation fault in the new qtest testcase that is added.
This is CVE-2017-9503.
Reported-by: Zhangyanyu <zyy4013@stu.ouc.edu.cn>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/megasas.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index 887958481b..a0cafe3010 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -607,6 +607,9 @@ static void megasas_reset_frames(MegasasState *s)
static void megasas_abort_command(MegasasCmd *cmd)
{
/* Never abort internal commands. */
+ if (cmd->dcmd_opcode != -1) {
+ return;
+ }
if (cmd->req != NULL) {
scsi_req_cancel(cmd->req);
}
@@ -1014,7 +1017,6 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
uint64_t pd_size;
uint16_t pd_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
uint8_t cmdbuf[6];
- SCSIRequest *req;
size_t len, resid;
if (!cmd->iov_buf) {
@@ -1023,8 +1025,8 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
info->inquiry_data[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */
info->vpd_page83[0] = 0x7f;
megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data));
- req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
- if (!req) {
+ cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
+ if (!cmd->req) {
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"PD get info std inquiry");
g_free(cmd->iov_buf);
@@ -1033,26 +1035,26 @@ static int megasas_pd_get_info_submit(SCSIDevice *sdev, int lun,
}
trace_megasas_dcmd_internal_submit(cmd->index,
"PD get info std inquiry", lun);
- len = scsi_req_enqueue(req);
+ len = scsi_req_enqueue(cmd->req);
if (len > 0) {
cmd->iov_size = len;
- scsi_req_continue(req);
+ scsi_req_continue(cmd->req);
}
return MFI_STAT_INVALID_STATUS;
} else if (info->inquiry_data[0] != 0x7f && info->vpd_page83[0] == 0x7f) {
megasas_setup_inquiry(cmdbuf, 0x83, sizeof(info->vpd_page83));
- req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
- if (!req) {
+ cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
+ if (!cmd->req) {
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"PD get info vpd inquiry");
return MFI_STAT_FLASH_ALLOC_FAIL;
}
trace_megasas_dcmd_internal_submit(cmd->index,
"PD get info vpd inquiry", lun);
- len = scsi_req_enqueue(req);
+ len = scsi_req_enqueue(cmd->req);
if (len > 0) {
cmd->iov_size = len;
- scsi_req_continue(req);
+ scsi_req_continue(cmd->req);
}
return MFI_STAT_INVALID_STATUS;
}
@@ -1214,7 +1216,6 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
struct mfi_ld_info *info = cmd->iov_buf;
size_t dcmd_size = sizeof(struct mfi_ld_info);
uint8_t cdb[6];
- SCSIRequest *req;
ssize_t len, resid;
uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
uint64_t ld_size;
@@ -1223,8 +1224,8 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
cmd->iov_buf = g_malloc0(dcmd_size);
info = cmd->iov_buf;
megasas_setup_inquiry(cdb, 0x83, sizeof(info->vpd_page83));
- req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd);
- if (!req) {
+ cmd->req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd);
+ if (!cmd->req) {
trace_megasas_dcmd_req_alloc_failed(cmd->index,
"LD get info vpd inquiry");
g_free(cmd->iov_buf);
@@ -1233,10 +1234,10 @@ static int megasas_ld_get_info_submit(SCSIDevice *sdev, int lun,
}
trace_megasas_dcmd_internal_submit(cmd->index,
"LD get info vpd inquiry", lun);
- len = scsi_req_enqueue(req);
+ len = scsi_req_enqueue(cmd->req);
if (len > 0) {
cmd->iov_size = len;
- scsi_req_continue(req);
+ scsi_req_continue(cmd->req);
}
return MFI_STAT_INVALID_STATUS;
}
@@ -1865,7 +1866,7 @@ static void megasas_command_complete(SCSIRequest *req, uint32_t status,
return;
}
- if (cmd->req == NULL) {
+ if (cmd->dcmd_opcode != -1) {
/*
* Internal command complete
*/
--
2.11.0

View File

@ -0,0 +1,81 @@
From 4dbc47f9d71b8a17b174ffed314988aa99dc4775 Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Fri, 26 May 2017 22:04:21 -0500
Subject: [PATCH 18/23] nbd: Fully initialize client in case of failed
negotiation
If a non-NBD client connects to qemu-nbd, we would end up with
a SIGSEGV in nbd_client_put() because we were trying to
unregister the client's association to the export, even though
we skipped inserting the client into that list. Easy trigger
in two terminals:
$ qemu-nbd -p 30001 --format=raw file
$ nmap 127.0.0.1 -p 30001
nmap claims that it thinks it connected to a pago-services1
server (which probably means nmap could be updated to learn the
NBD protocol and give a more accurate diagnosis of the open
port - but that's not our problem), then terminates immediately,
so our call to nbd_negotiate() fails. The fix is to reorder
nbd_co_client_start() to ensure that all initialization occurs
before we ever try talking to a client in nbd_negotiate(), so
that the teardown sequence on negotiation failure doesn't fault
while dereferencing a half-initialized object.
While debugging this, I also noticed that nbd_update_server_watch()
called by nbd_client_closed() was still adding a channel to accept
the next client, even when the state was no longer RUNNING. That
is fixed by making nbd_can_accept() pay attention to the current
state.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170527030421.28366-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
nbd/server.c | 8 +++-----
qemu-nbd.c | 2 +-
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/nbd/server.c b/nbd/server.c
index 924a1fe2db..edfda84d43 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1376,16 +1376,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
if (exp) {
nbd_export_get(exp);
+ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
}
+ qemu_co_mutex_init(&client->send_lock);
+
if (nbd_negotiate(data)) {
client_close(client);
goto out;
}
- qemu_co_mutex_init(&client->send_lock);
-
- if (exp) {
- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
- }
nbd_client_receive_next_request(client);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e080fb7c75..b44764eb87 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -324,7 +324,7 @@ out:
static int nbd_can_accept(void)
{
- return nb_fds < shared;
+ return state == RUNNING && nb_fds < shared;
}
static void nbd_export_closed(NBDExport *exp)
--
2.11.0

View File

@ -0,0 +1,197 @@
From 97c7e46a9f8ae03e24df1d18d3b5e9df420f39ce Mon Sep 17 00:00:00 2001
From: Eric Blake <eblake@redhat.com>
Date: Thu, 8 Jun 2017 17:26:17 -0500
Subject: [PATCH 19/23] nbd: Fix regression on resiliency to port scan
Back in qemu 2.5, qemu-nbd was immune to port probes (a transient
server would not quit, regardless of how many probe connections
came and went, until a connection actually negotiated). But we
broke that in commit ee7d7aa when removing the return value to
nbd_client_new(), although that patch also introduced a bug causing
an assertion failure on a client that fails negotiation. We then
made it worse during refactoring in commit 1a6245a (a segfault
before we could even assert); the (masked) assertion was cleaned
up in d3780c2 (still in 2.6), and just recently we finally fixed
the segfault ("nbd: Fully intialize client in case of failed
negotiation"). But that still means that ever since we added
TLS support to qemu-nbd, we have been vulnerable to an ill-timed
port-scan being able to cause a denial of service by taking down
qemu-nbd before a real client has a chance to connect.
Since negotiation is now handled asynchronously via coroutines,
we no longer have a synchronous point of return by re-adding a
return value to nbd_client_new(). So this patch instead wires
things up to pass the negotiation status through the close_fn
callback function.
Simple test across two terminals:
$ qemu-nbd -f raw -p 30001 file
$ nmap 127.0.0.1 -p 30001 && \
qemu-io -c 'r 0 512' -f raw nbd://localhost:30001
Note that this patch does not change what constitutes successful
negotiation (thus, a client must enter transmission phase before
that client can be considered as a reason to terminate the server
when the connection ends). Perhaps we may want to tweak things
in a later patch to also treat a client that uses NBD_OPT_ABORT
as being a 'successful' negotiation (the client correctly talked
the NBD protocol, and informed us it was not going to use our
export after all), but that's a discussion for another day.
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <20170608222617.20376-1-eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
blockdev-nbd.c | 6 +++++-
include/block/nbd.h | 2 +-
nbd/server.c | 24 +++++++++++++++---------
qemu-nbd.c | 4 ++--
4 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 8a11807df3..8d7284ac56 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -27,6 +27,10 @@ typedef struct NBDServerData {
static NBDServerData *nbd_server;
+static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
+{
+ nbd_client_put(client);
+}
static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
gpointer opaque)
@@ -46,7 +50,7 @@ static gboolean nbd_accept(QIOChannel *ioc, GIOCondition condition,
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
nbd_client_new(NULL, cioc,
nbd_server->tlscreds, NULL,
- nbd_client_put);
+ nbd_blockdev_client_closed);
object_unref(OBJECT(cioc));
return TRUE;
}
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 3e373f0498..b69c30d063 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -160,7 +160,7 @@ void nbd_client_new(NBDExport *exp,
QIOChannelSocket *sioc,
QCryptoTLSCreds *tlscreds,
const char *tlsaclname,
- void (*close)(NBDClient *));
+ void (*close_fn)(NBDClient *, bool));
void nbd_client_get(NBDClient *client);
void nbd_client_put(NBDClient *client);
diff --git a/nbd/server.c b/nbd/server.c
index edfda84d43..a98bb21a0a 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -81,7 +81,7 @@ static QTAILQ_HEAD(, NBDExport) exports = QTAILQ_HEAD_INITIALIZER(exports);
struct NBDClient {
int refcount;
- void (*close)(NBDClient *client);
+ void (*close_fn)(NBDClient *client, bool negotiated);
bool no_zeroes;
NBDExport *exp;
@@ -796,7 +796,7 @@ void nbd_client_put(NBDClient *client)
}
}
-static void client_close(NBDClient *client)
+static void client_close(NBDClient *client, bool negotiated)
{
if (client->closing) {
return;
@@ -811,8 +811,8 @@ static void client_close(NBDClient *client)
NULL);
/* Also tell the client, so that they release their reference. */
- if (client->close) {
- client->close(client);
+ if (client->close_fn) {
+ client->close_fn(client, negotiated);
}
}
@@ -993,7 +993,7 @@ void nbd_export_close(NBDExport *exp)
nbd_export_get(exp);
QTAILQ_FOREACH_SAFE(client, &exp->clients, next, next) {
- client_close(client);
+ client_close(client, true);
}
nbd_export_set_name(exp, NULL);
nbd_export_set_description(exp, NULL);
@@ -1355,7 +1355,7 @@ done:
out:
nbd_request_put(req);
- client_close(client);
+ client_close(client, true);
nbd_client_put(client);
}
@@ -1381,7 +1381,7 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
qemu_co_mutex_init(&client->send_lock);
if (nbd_negotiate(data)) {
- client_close(client);
+ client_close(client, false);
goto out;
}
@@ -1391,11 +1391,17 @@ out:
g_free(data);
}
+/*
+ * Create a new client listener on the given export @exp, using the
+ * given channel @sioc. Begin servicing it in a coroutine. When the
+ * connection closes, call @close_fn with an indication of whether the
+ * client completed negotiation.
+ */
void nbd_client_new(NBDExport *exp,
QIOChannelSocket *sioc,
QCryptoTLSCreds *tlscreds,
const char *tlsaclname,
- void (*close_fn)(NBDClient *))
+ void (*close_fn)(NBDClient *, bool))
{
NBDClient *client;
NBDClientNewData *data = g_new(NBDClientNewData, 1);
@@ -1412,7 +1418,7 @@ void nbd_client_new(NBDExport *exp,
object_ref(OBJECT(client->sioc));
client->ioc = QIO_CHANNEL(sioc);
object_ref(OBJECT(client->ioc));
- client->close = close_fn;
+ client->close_fn = close_fn;
data->client = client;
data->co = qemu_coroutine_create(nbd_co_client_start, data);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index b44764eb87..483dd77a77 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -335,10 +335,10 @@ static void nbd_export_closed(NBDExport *exp)
static void nbd_update_server_watch(void);
-static void nbd_client_closed(NBDClient *client)
+static void nbd_client_closed(NBDClient *client, bool negotiated)
{
nb_fds--;
- if (nb_fds == 0 && !persistent && state == RUNNING) {
+ if (negotiated && nb_fds == 0 && !persistent && state == RUNNING) {
state = TERMINATE;
}
nbd_update_server_watch();
--
2.11.0

View File

@ -0,0 +1,47 @@
From 36d48727155c4a440ee23c703778533f87002964 Mon Sep 17 00:00:00 2001
From: Max Reitz <mreitz@redhat.com>
Date: Sun, 11 Jun 2017 14:37:14 +0200
Subject: [PATCH 20/23] 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 483dd77a77..5deb37e03e 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.11.0

View File

@ -0,0 +1,50 @@
From ce2b5a53421794394fc81d155837b1c8ac79ea15 Mon Sep 17 00:00:00 2001
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Tue, 9 May 2017 13:01:28 +0200
Subject: [PATCH 21/23] 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 0efe62f725..eb70dc7218 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.11.0

View File

@ -0,0 +1,43 @@
From d587bf95f1099fd253e6a7b768bf73d4e25de07c Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 12 Jul 2017 18:08:40 +0530
Subject: [PATCH 22/23] exec: use qemu_ram_ptr_length to access guest ram
When accessing guest's ram block during DMA operation, use
'qemu_ram_ptr_length' to get ram block pointer. It ensures
that DMA operation of given length is possible; And avoids
any OOB memory access situations.
Reported-by: Alex <broscutamaker@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <20170712123840.29328-1-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
exec.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/exec.c b/exec.c
index c97ef4a8da..72d636a4fb 100644
--- a/exec.c
+++ b/exec.c
@@ -2765,7 +2765,7 @@ static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
memcpy(ptr, buf, l);
invalidate_and_set_dirty(mr, addr1, l);
}
@@ -2856,7 +2856,7 @@ MemTxResult address_space_read_continue(AddressSpace *as, hwaddr addr,
}
} else {
/* RAM case */
- ptr = qemu_map_ram_ptr(mr->ram_block, addr1);
+ ptr = qemu_ram_ptr_length(mr->ram_block, addr1, &l);
memcpy(buf, ptr, l);
}
--
2.11.0

View File

@ -0,0 +1,35 @@
From f3b5bdea7ea51404bbf88bea6fc8887586a423b2 Mon Sep 17 00:00:00 2001
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Mon, 17 Jul 2017 17:33:26 +0530
Subject: [PATCH 23/23] slirp: check len against dhcp options array end
While parsing dhcp options string in 'dhcp_decode', if an options'
length 'len' appeared towards the end of 'bp_vend' array, ensuing
read could lead to an OOB memory access issue. Add check to avoid it.
This is CVE-2017-11434.
Reported-by: Reno Robert <renorobert@gmail.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
slirp/bootp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 5a4646c182..5dd1a415b5 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -123,6 +123,9 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
if (p >= p_end)
break;
len = *p++;
+ if (p + len > p_end) {
+ break;
+ }
DPRINTF("dhcp: tag=%d len=%d\n", tag, len);
switch(tag) {
--
2.11.0

View File

@ -41,3 +41,11 @@ extra/0012-audio-release-capture-buffers.patch
extra/0013-input-limit-kbd-queue-depth.patch extra/0013-input-limit-kbd-queue-depth.patch
extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch
extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch
extra/0016-megasas-do-not-read-DCMD-opcode-more-than-once-from-.patch
extra/0017-megasas-always-store-SCSIRequest-into-MegasasCmd.patch
extra/0018-nbd-Fully-initialize-client-in-case-of-failed-negoti.patch
extra/0019-nbd-Fix-regression-on-resiliency-to-port-scan.patch
extra/0020-qemu-nbd-Ignore-SIGPIPE.patch
extra/0021-usb-redir-fix-stack-overflow-in-usbredir_log_data.patch
extra/0022-exec-use-qemu_ram_ptr_length-to-access-guest-ram.patch
extra/0023-slirp-check-len-against-dhcp-options-array-end.patch