qemu-devel
[Top][All Lists]
Advanced

[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
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]