git: b8e33d1abeae - stable/13 - bhyve: Address uses of uninitialized variables in pci_nvme.c
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 29 Aug 2022 15:01:18 UTC
The branch stable/13 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=b8e33d1abeae18c0441583f912ff9dc85c628180
commit b8e33d1abeae18c0441583f912ff9dc85c628180
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-08-14 15:57:24 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-08-29 15:01: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
Sponsored by: The FreeBSD Foundation
(cherry picked from commit b6ecef28bfd7c1c267442fae1c8f2fe0f699f617)
---
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 6bed8ef8a731..98410b92039c 100644
--- a/usr.sbin/bhyve/pci_nvme.c
+++ b/usr.sbin/bhyve/pci_nvme.c
@@ -1386,9 +1386,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);
@@ -1396,10 +1394,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)) {
@@ -2460,6 +2461,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)",
@@ -2468,13 +2475,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;