[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: |
Peter Maydell |
Subject: |
Re: [Qemu-devel] [PATCH PULL v2 08/10] hw/rdma: PVRDMA commands and data-path ops |
Date: |
Fri, 27 Apr 2018 15:43:44 +0100 |
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.
thanks
-- PMM