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



reply via email to

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