Pablo Greco e6a3ae
From 7dd9696a1b288746bac6fa0fe4f1d212be4f8f82 Mon Sep 17 00:00:00 2001
Pablo Greco e6a3ae
From: jmaloy <jmaloy@redhat.com>
Pablo Greco e6a3ae
Date: Wed, 29 Jan 2020 21:41:15 +0000
Pablo Greco e6a3ae
Subject: [PATCH 2/6] iscsi: Cap block count from GET LBA STATUS
Pablo Greco e6a3ae
 (CVE-2020-1711)
Pablo Greco e6a3ae
MIME-Version: 1.0
Pablo Greco e6a3ae
Content-Type: text/plain; charset=UTF-8
Pablo Greco e6a3ae
Content-Transfer-Encoding: 8bit
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: jmaloy <jmaloy@redhat.com>
Pablo Greco e6a3ae
Message-id: <20200129214115.19979-3-jmaloy@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 93585
Pablo Greco e6a3ae
O-Subject: [RHEL-8.2.0 qemu-kvm PATCH 2/2] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711)
Pablo Greco e6a3ae
Bugzilla: 1794501
Pablo Greco e6a3ae
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
From: Felipe Franciosi <felipe@nutanix.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
When querying an iSCSI server for the provisioning status of blocks (via
Pablo Greco e6a3ae
GET LBA STATUS), Qemu only validates that the response descriptor zero's
Pablo Greco e6a3ae
LBA matches the one requested. Given the SCSI spec allows servers to
Pablo Greco e6a3ae
respond with the status of blocks beyond the end of the LUN, Qemu may
Pablo Greco e6a3ae
have its heap corrupted by clearing/setting too many bits at the end of
Pablo Greco e6a3ae
its allocmap for the LUN.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
A malicious guest in control of the iSCSI server could carefully program
Pablo Greco e6a3ae
Qemu's heap (by selectively setting the bitmap) and then smash it.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
This limits the number of bits that iscsi_co_block_status() will try to
Pablo Greco e6a3ae
update in the allocmap so it can't overflow the bitmap.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Fixes: CVE-2020-1711
Pablo Greco e6a3ae
Cc: qemu-stable@nongnu.org
Pablo Greco e6a3ae
Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
Pablo Greco e6a3ae
Signed-off-by: Peter Turschmid <peter.turschm@nutanix.com>
Pablo Greco e6a3ae
Signed-off-by: Raphael Norwitz <raphael.norwitz@nutanix.com>
Pablo Greco e6a3ae
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
(cherry picked from commit 693fd2acdf14dd86c0bf852610f1c2cca80a74dc)
Pablo Greco e6a3ae
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
Pablo Greco e6a3ae
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
---
Pablo Greco e6a3ae
 block/iscsi.c | 5 +++--
Pablo Greco e6a3ae
 1 file changed, 3 insertions(+), 2 deletions(-)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/block/iscsi.c b/block/iscsi.c
Pablo Greco e6a3ae
index 336ce49..8ec97ab 100644
Pablo Greco e6a3ae
--- a/block/iscsi.c
Pablo Greco e6a3ae
+++ b/block/iscsi.c
Pablo Greco e6a3ae
@@ -671,7 +671,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
Pablo Greco e6a3ae
     struct scsi_get_lba_status *lbas = NULL;
Pablo Greco e6a3ae
     struct scsi_lba_status_descriptor *lbasd = NULL;
Pablo Greco e6a3ae
     struct IscsiTask iTask;
Pablo Greco e6a3ae
-    uint64_t lba;
Pablo Greco e6a3ae
+    uint64_t lba, max_bytes;
Pablo Greco e6a3ae
     int ret;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     iscsi_co_init_iscsitask(iscsilun, &iTask);
Pablo Greco e6a3ae
@@ -691,6 +691,7 @@ static int coroutine_fn iscsi_co_block_status(BlockDriverState *bs,
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     lba = offset / iscsilun->block_size;
Pablo Greco e6a3ae
+    max_bytes = (iscsilun->num_blocks - lba) * iscsilun->block_size;
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     qemu_mutex_lock(&iscsilun->mutex);
Pablo Greco e6a3ae
 retry:
Pablo Greco e6a3ae
@@ -734,7 +735,7 @@ retry:
Pablo Greco e6a3ae
         goto out_unlock;
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-    *pnum = (int64_t) lbasd->num_blocks * iscsilun->block_size;
Pablo Greco e6a3ae
+    *pnum = MIN((int64_t) lbasd->num_blocks * iscsilun->block_size, max_bytes);
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
     if (lbasd->provisioning == SCSI_PROVISIONING_TYPE_DEALLOCATED ||
Pablo Greco e6a3ae
         lbasd->provisioning == SCSI_PROVISIONING_TYPE_ANCHORED) {
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae