git: 541ff74584e1 - stable/13 - bhyve nvme: Fix LBA out-of-range calculation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 21 Feb 2022 21:58:02 UTC
The branch stable/13 has been updated by chuck: URL: https://cgit.FreeBSD.org/src/commit/?id=541ff74584e13c4543bb096915a3a39b57834b24 commit 541ff74584e13c4543bb096915a3a39b57834b24 Author: Chuck Tuffli <chuck@FreeBSD.org> AuthorDate: 2022-01-30 07:09:57 +0000 Commit: Chuck Tuffli <chuck@FreeBSD.org> CommitDate: 2022-02-22 03:27:47 +0000 bhyve nvme: Fix LBA out-of-range calculation The function which checks for a valid LBA range mistakenly named an input value as NLB ("Number of Logical Blocks") instead of "number of blocks". The NVMe specification defines NLB as a zero-based value (i.e. NLB=0x0 represents 1 block, 0x1 is 2 blocks, etc.), but the passed parameter is a 1's-based value. Fix is to rename the variable to avoid future confusion. While in the neighborhood, also check that the starting LBA is less than the size of the backing storage to avoid an integer overflow. (cherry picked from commit 9d8cd04694d47d48cc4003f8322739ba10fa8108) --- usr.sbin/bhyve/pci_nvme.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/usr.sbin/bhyve/pci_nvme.c b/usr.sbin/bhyve/pci_nvme.c index aff881bd5056..66ca3dcdf38e 100644 --- a/usr.sbin/bhyve/pci_nvme.c +++ b/usr.sbin/bhyve/pci_nvme.c @@ -2103,8 +2103,8 @@ pci_nvme_stats_write_read_update(struct pci_nvme_softc *sc, uint8_t opc, } /* - * Check if the combination of Starting LBA (slba) and Number of Logical - * Blocks (nlb) exceeds the range of the underlying storage. + * Check if the combination of Starting LBA (slba) and number of blocks + * exceeds the range of the underlying storage. * * Because NVMe specifies the SLBA in blocks as a uint64_t and blockif stores * the capacity in bytes as a uint64_t, care must be taken to avoid integer @@ -2112,7 +2112,7 @@ pci_nvme_stats_write_read_update(struct pci_nvme_softc *sc, uint8_t opc, */ static bool pci_nvme_out_of_range(struct pci_nvme_blockstore *nvstore, uint64_t slba, - uint32_t nlb) + uint32_t nblocks) { size_t offset, bytes; @@ -2121,10 +2121,10 @@ pci_nvme_out_of_range(struct pci_nvme_blockstore *nvstore, uint64_t slba, return (true); offset = slba << nvstore->sectsz_bits; - bytes = nlb << nvstore->sectsz_bits; + bytes = nblocks << nvstore->sectsz_bits; /* Overflow check of Number of Logical Blocks */ - if ((nvstore->size - offset) < bytes) + if ((nvstore->size <= offset) || ((nvstore->size - offset) < bytes)) return (true); return (false); @@ -2433,7 +2433,8 @@ nvme_opc_write_read(struct pci_nvme_softc *sc, nblocks = (cmd->cdw12 & 0xFFFF) + 1; if (pci_nvme_out_of_range(nvstore, lba, nblocks)) { - WPRINTF("%s command would exceed LBA range", __func__); + WPRINTF("%s command would exceed LBA range(slba=%#lx nblocks=%#lx)", + __func__, lba, nblocks); pci_nvme_status_genc(status, NVME_SC_LBA_OUT_OF_RANGE); goto out; }