| From 693fd2acdf14dd86c0bf852610f1c2cca80a74dc Mon Sep 17 00:00:00 2001 |
| From: Felipe Franciosi <felipe@nutanix.com> |
| Date: Thu, 23 Jan 2020 12:44:59 +0000 |
| Subject: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711) |
| |
| When querying an iSCSI server for the provisioning status of blocks (via |
| GET LBA STATUS), Qemu only validates that the response descriptor zero's |
| LBA matches the one requested. Given the SCSI spec allows servers to |
| respond with the status of blocks beyond the end of the LUN, Qemu may |
| have its heap corrupted by clearing/setting too many bits at the end of |
| its allocmap for the LUN. |
| |
| A malicious guest in control of the iSCSI server could carefully program |
| Qemu's heap (by selectively setting the bitmap) and then smash it. |
| |
| This limits the number of bits that iscsi_co_block_status() will try to |
| update in the allocmap so it can't overflow the bitmap. |
| |
| Upstream-Status: Backport [https://git.qemu.org/?p=qemu.git;a=patch;h=693fd2acdf14dd86c0bf852610f1c2cca80a74dc] |
| CVE: CVE-2020-1711 |
| |
| Fixes: CVE-2020-1711 |
| Cc: qemu-stable@nongnu.org |
| Signed-off-by: Felipe Franciosi <felipe@nutanix.com> |
| Signed-off-by: Peter Turschmid <peter.turschm@nutanix.com> |
| Signed-off-by: Raphael Norwitz <raphael.norwitz@nutanix.com> |
| Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
| Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com> |
| --- |
| block/iscsi.c | 5 +++-- |
| 1 file changed, 3 insertions(+), 2 deletions(-) |
| |
| diff --git a/block/iscsi.c b/block/iscsi.c |
| index 2aea7e3..cbd5729 100644 |
| --- a/block/iscsi.c |
| +++ b/block/iscsi.c |
| @@ -701,7 +701,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs, |
| struct scsi_get_lba_status *lbas = NULL; |
| struct scsi_lba_status_descriptor *lbasd = NULL; |
| struct IscsiTask iTask; |
| - uint64_t lba; |
| + uint64_t lba, max_bytes; |
| int ret; |
| |
| iscsi_co_init_iscsitask(iscsilun, &iTask); |
| @@ -721,6 +721,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs, |
| } |
| |
| lba = offset / iscsilun->block_size; |
| + max_bytes = (iscsilun->num_blocks - lba) * iscsilun->block_size; |
| |
| qemu_mutex_lock(&iscsilun->mutex); |
| retry: |
| @@ -764,7 +765,7 @@ retry: |
| goto out_unlock; |
| } |
| |
| - *pnum = (int64_t) lbasd->num_blocks * iscsilun->block_size; |
| + *pnum = MIN((int64_t) lbasd->num_blocks * iscsilun->block_size, max_bytes); |
| |
| if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED || |
| lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) { |
| -- |
| 1.8.3.1 |