[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH PULL v2 08/10] hw/rdma: PVRDMA commands and data
From: |
Marcel Apfelbaum |
Subject: |
Re: [Qemu-devel] [PATCH PULL v2 08/10] hw/rdma: PVRDMA commands and data-path ops |
Date: |
Fri, 27 Apr 2018 21:22:20 +0300 |
User-agent: |
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.7.0 |
On 27/04/2018 17:43, Peter Maydell wrote:
> On 19 February 2018 at 11:43, Marcel Apfelbaum <address@hidden> wrote:
>> From: Yuval Shaia <address@hidden>
>>
>> First PVRDMA sub-module - implementation of the PVRDMA device.
>> - PVRDMA commands such as create CQ and create MR.
>> - Data path QP operations - post_send and post_recv.
>> - Completion handler.
>
> Coverity (CID1390589, CID1390608) points out more array
> bounds overruns here:
>
>> +
>> +typedef struct PVRDMADev {
>> + PCIDevice parent_obj;
>> + MemoryRegion msix;
>> + MemoryRegion regs;
>> + uint32_t regs_data[RDMA_BAR1_REGS_SIZE];
>
> regs_data is an array of size RDMA_BAR1_REGS_SIZE...
>
>> + MemoryRegion uar;
>> + uint32_t uar_data[RDMA_BAR2_UAR_SIZE];
>> + DSRInfo dsr_info;
>> + int interrupt_mask;
>> + struct ibv_device_attr dev_attr;
>> + uint64_t node_guid;
>> + char *backend_device_name;
>> + uint8_t backend_gid_idx;
>> + uint8_t backend_port_num;
>> + RdmaBackendDev backend_dev;
>> + RdmaDeviceResources rdma_dev_res;
>> +} PVRDMADev;
>> +#define PVRDMA_DEV(dev) OBJECT_CHECK(PVRDMADev, (dev), PVRDMA_HW_NAME)
>> +
>> +static inline int get_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t *val)
>> +{
>> + int idx = addr >> 2;
>> +
>> + if (idx > RDMA_BAR1_REGS_SIZE) {
>> + return -EINVAL;
>> + }
>
> ...but the bounds check here is ">" rather than ">="
> and allows idx == RDMA_BAR1_REGS_SIZE through...
>
>> +
>> + *val = dev->regs_data[idx];
>
> ...and this will overrun the array.
>
>> +
>> + return 0;
>> +}
>> +
>> +static inline int set_reg_val(PVRDMADev *dev, hwaddr addr, uint32_t val)
>> +{
>> + int idx = addr >> 2;
>> +
>> + if (idx > RDMA_BAR1_REGS_SIZE) {
>> + return -EINVAL;
>> + }
>> +
>> + dev->regs_data[idx] = val;
>
> Similarly here, where this is a write access.
>
> Luckily this isn't an exploitable guest escape, because the only
> call to set_reg_val() with a guest-controlled addr value is from
> the read function of an MMIO MemoryRegion which is created with
> a size of RDMA_BAR1_REGS_SIZE, so the guest can't get out of
> range values into here.
>
> Three times is a pattern -- you might like to check your
> other bounds checks for off-by-one errors. Coverity doesn't
> necessarily catch all of them.
>
Agreed, I'll go over the code again.
Thanks,
Marcel
> thanks
> -- PMM
>