[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711)
From: |
Peter Lieven |
Subject: |
Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711) |
Date: |
Thu, 23 Jan 2020 23:58:35 +0100 |
> Am 23.01.2020 um 22:29 schrieb Felipe Franciosi <address@hidden>:
>
> Hi,
>
>> On Jan 23, 2020, at 5:46 PM, Philippe Mathieu-Daudé <address@hidden> wrote:
>>
>>> On 1/23/20 1:44 PM, Felipe Franciosi wrote:
>>> 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.
>>
>> Please add:
>>
>> Fixes: CVE-2020-1711 (title of CVE if possible)
>
> I wasn't sure we had one yet. Kevin: can you do the needful in your branch?
>
>> Cc: address@hidden
>
> Yeah, that's there.
>
>>
>>> Signed-off-by: Felipe Franciosi <address@hidden>
>>> Signed-off-by: Peter Turschmid <address@hidden>
>>> Signed-off-by: Raphael Norwitz <address@hidden>
>>> ---
>>> block/iscsi.c | 5 +++--
>>> 1 file 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) {
>>
>> What about this?
>>
>> -- >8 --
>> diff --git a/block/iscsi.c b/block/iscsi.c
>> index 2aea7e3f13..25598accbb 100644
>> --- a/block/iscsi.c
>> +++ b/block/iscsi.c
>> @@ -506,6 +506,11 @@ iscsi_allocmap_update(IscsiLun *iscsilun, int64_t
>> offset,
>> /* shrink to touch only completely contained clusters */
>> cl_num_shrunk = DIV_ROUND_UP(offset, iscsilun->cluster_size);
>> nb_cls_shrunk = (offset + bytes) / iscsilun->cluster_size - cl_num_shrunk;
>> + if (nb_cls_expanded >= iscsilun->allocmap_size
>> + || nb_cls_shrunk >= iscsilun->allocmap_size) {
>> + error_report("iSCSI invalid request: ..." /* TODO */);
>> + return;
>> + }
>> if (allocated) {
>> bitmap_set(iscsilun->allocmap, cl_num_expanded, nb_cls_expanded);
>> } else {
>> ---
>
> I'm not sure the above is correct because (if I read this right)
> nb_cls_* represents the number of clusters, not the last cluster.
>
> Personally, I would have the checks (or "trim"s) closer to where they
> were issued (to fail sooner) and assert()s closer to bitmap (as no oob
> accesses should be happening at this point). There were also
> discussions about using safer (higher level) bitmaps for this. I'm
> always in favour of adding all reasonable checks. :)
I would add assertions that cl_num + nb_cls <= allocmap_size before every set
and clear.
Peter
- [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Felipe Franciosi, 2020/01/23
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Kevin Wolf, 2020/01/23
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Philippe Mathieu-Daudé, 2020/01/23
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Felipe Franciosi, 2020/01/23
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711),
Peter Lieven <=
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Philippe Mathieu-Daudé, 2020/01/24
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Felipe Franciosi, 2020/01/24
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Kevin Wolf, 2020/01/24
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Philippe Mathieu-Daudé, 2020/01/24
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Kevin Wolf, 2020/01/24
- Re: [PATCH] iscsi: Cap block count from GET LBA STATUS (CVE-2020-1711), Philippe Mathieu-Daudé, 2020/01/24