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