aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Franciosi <felipe@nutanix.com>2020-01-23 12:44:59 +0000
committerMichael Roth <mdroth@linux.vnet.ibm.com>2020-06-22 12:14:48 -0500
commit4e98c388d6b07a7b8b760491b07bcfd887c35e23 (patch)
tree2de4c7f408cdd3e031f495b152cc009be4f4f67b
parent54bcaf08d66f9675e5662e061f5c4c0d8f3a2506 (diff)
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. 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> (cherry picked from commit 693fd2acdf14dd86c0bf852610f1c2cca80a74dc) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r--block/iscsi.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/block/iscsi.c b/block/iscsi.c
index 2aea7e3f13..cbd57294ab 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) {