git: b6ecef28bfd7 - main - bhyve: Address uses of uninitialized variables in pci_nvme.c
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 14 Aug 2022 16:07:26 UTC
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=b6ecef28bfd7c1c267442fae1c8f2fe0f699f617 commit b6ecef28bfd7c1c267442fae1c8f2fe0f699f617 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2022-08-14 15:57:24 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2022-08-14 15:59:01 +0000 bhyve: Address uses of uninitialized variables in pci_nvme.c The debug print in nvme_opc_get_log_page() would print an uninitialized local variable. In nvme_opc_write_read(), a failed LBA bounds check would cause pci_nvme_stats_write_read_update() to be called with an uninitialized variable as a parameter. Although the parameter is unused when the check fails (and so status != 0), LLVM 14 emits some bogus machine code in this path, which happens to result in a segfault when it gets executed. PR: 265749 Reviewed by: chuck, emaste MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D36119 --- usr.sbin/bhyve/pci_nvme.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index b832caa6f05d..38102beb0152 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -1418,9 +1418,7 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, { uint64_t logoff; uint32_t logsize; - uint8_t logpage = command->cdw10 & 0xFF; - - DPRINTF("%s log page %u len %u", __func__, logpage, logsize); + uint8_t logpage; pci_nvme_status_genc(&compl->status, NVME_SC_SUCCESS); @@ -1428,10 +1426,13 @@ nvme_opc_get_log_page(struct pci_nvme_softc* sc, struct nvme_command* command, * Command specifies the number of dwords to return in fields NUMDU * and NUMDL. This is a zero-based value. */ + logpage = command->cdw10 & 0xFF; logsize = ((command->cdw11 << 16) | (command->cdw10 >> 16)) + 1; logsize *= sizeof(uint32_t); logoff = ((uint64_t)(command->cdw13) << 32) | command->cdw12; + DPRINTF("%s log page %u len %u", __func__, logpage, logsize); + switch (logpage) { case NVME_LOG_ERROR: if (logoff >= sizeof(sc->err_log)) { @@ -2507,6 +2508,12 @@ nvme_opc_write_read(struct pci_nvme_softc *sc, lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10; nblocks = (cmd->cdw12 & 0xFFFF) + 1; + bytes = nblocks << nvstore->sectsz_bits; + if (bytes > NVME_MAX_DATA_SIZE) { + WPRINTF("%s command would exceed MDTS", __func__); + pci_nvme_status_genc(status, NVME_SC_INVALID_FIELD); + goto out; + } if (pci_nvme_out_of_range(nvstore, lba, nblocks)) { WPRINTF("%s command would exceed LBA range(slba=%#lx nblocks=%#lx)", @@ -2515,13 +2522,6 @@ nvme_opc_write_read(struct pci_nvme_softc *sc, goto out; } - bytes = nblocks << nvstore->sectsz_bits; - if (bytes > NVME_MAX_DATA_SIZE) { - WPRINTF("%s command would exceed MDTS", __func__); - pci_nvme_status_genc(status, NVME_SC_INVALID_FIELD); - goto out; - } - offset = lba << nvstore->sectsz_bits; req->bytes = bytes;