git: c8f75686adc6 - stable/13 - bhyve/nvme: Fix out-of-bounds read in NVMe log page
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 11 Oct 2024 15:43:16 UTC
The branch stable/13 has been updated by emaste: URL: https://cgit.FreeBSD.org/src/commit/?id=c8f75686adc6bc2078ade279d838cbc5b1745e71 commit c8f75686adc6bc2078ade279d838cbc5b1745e71 Author: Chuck Tuffli <chuck@FreeBSD.org> AuthorDate: 2024-09-19 15:11:30 +0000 Commit: Ed Maste <emaste@FreeBSD.org> CommitDate: 2024-10-11 15:42:40 +0000 bhyve/nvme: Fix out-of-bounds read in NVMe log page The function nvme_opc_get_log_page in the file usr.sbin/bhyve/pci_nvme.c is vulnerable to buffer over-read. The value logoff is user controlled but never checked against the value of logsize. Thus the difference: logsize - logoff can underflow. Due to the sc structure layout, an attacker can dump internals fields of sc and the content of next heap allocation. Reported by: Synacktiv Reviewed by: emaste, jhb Security: HYP-07 Sponsored by: Alpha-Omega Project, The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46021 (cherry picked from commit b0a24be007d83f7929de5b3fc320a29e6868067d) (cherry picked from commit a5be19efbb7c6b07d574ef048b2ebade00440873) --- usr.sbin/bhyve/pci_nvme.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index 3db306a19119..cbe4d87b6f60 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -1454,7 +1454,7 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, logsize *= sizeof(uint32_t); logoff = ((uint64_t)(command->cdw13) << 32) | command->cdw12; - DPRINTF("%s log page %u len %u", __func__, logpage, logsize); + DPRINTF("%s log page %u offset %lu len %u", __func__, logpage, logoff, logsize); switch (logpage) { case NVME_LOG_ERROR: @@ -1466,7 +1466,7 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, command->prp2, (uint8_t *)&sc->err_log + logoff, - MIN(logsize - logoff, sizeof(sc->err_log)), + MIN(logsize, sizeof(sc->err_log) - logoff), NVME_COPY_TO_PRP); break; case NVME_LOG_HEALTH_INFORMATION: @@ -1489,7 +1489,7 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, command->prp2, (uint8_t *)&sc->health_log + logoff, - MIN(logsize - logoff, sizeof(sc->health_log)), + MIN(logsize, sizeof(sc->health_log) - logoff), NVME_COPY_TO_PRP); break; case NVME_LOG_FIRMWARE_SLOT: @@ -1501,7 +1501,7 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, command->prp2, (uint8_t *)&sc->fw_log + logoff, - MIN(logsize - logoff, sizeof(sc->fw_log)), + MIN(logsize, sizeof(sc->fw_log) - logoff), NVME_COPY_TO_PRP); break; case NVME_LOG_CHANGED_NAMESPACE: @@ -1513,7 +1513,7 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, nvme_prp_memcpy(sc->nsc_pi->pi_vmctx, command->prp1, command->prp2, (uint8_t *)&sc->ns_log + logoff, - MIN(logsize - logoff, sizeof(sc->ns_log)), + MIN(logsize, sizeof(sc->ns_log) - logoff), NVME_COPY_TO_PRP); memset(&sc->ns_log, 0, sizeof(sc->ns_log)); break;