Blame SOURCES/kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch

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