bnxt_mgmt: missing bounds check on DMA offset in bnxt_mgmt_process_hwrm()

Stanislav Fort <[email protected]>
Newsgroups gmane.os.freebsd.devel.net
Message-ID <CA+uRpKSJZ-zRLgY25tCfED6BppPzPq4zKoMrkaKk0e95Aqz9Uw@mail.gmail.com>
Hi there,

In sys/dev/bnxt/bnxt_en/bnxt_mgmt.c, bnxt_mgmt_process_hwrm() uses
msg->dma[0].offset to index into the req buffer without checking that the
offset falls within the allocation:

    dma_ptr = (void *) ((uint64_t) req + msg->dma[0].offset);
    dmap = dma_ptr;
    *dmap = htole64(dma_data.idi_paddr);

The offset is a uint16_t from userspace (up to 65535) but req is allocated
with msg_temp.len_req bytes (at most 128). I think a simple bounds check
could be missing?

Not a high severity security issue since the device node is
0600/root:wheel, but seems worth fixing for correctness. Patch below:

--- a/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c
+++ b/sys/dev/bnxt/bnxt_en/bnxt_mgmt.c
@@ -256,6 +256,13 @@ bnxt_mgmt_process_hwrm(struct cdev *dev, u_long cmd,
caddr_t data,
  }
  }
+
+ if (msg->dma[0].offset + sizeof(uint64_t) > msg_temp.len_req) {
+ device_printf(softc->dev, "%s:%d Invalid DMA offset\n",
+      __FUNCTION__, __LINE__);
+ ret = -EINVAL;
+ goto end;
+ }
+
  dma_ptr = (void *) ((uint64_t) req + msg->dma[0].offset);
  dmap = dma_ptr;
  *dmap = htole64(dma_data.idi_paddr);

Cheers,
Stanislav Fort
Aisle Research
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.