git: 9d8cd04694d4 - main - bhyve nvme: Fix LBA out-of-range calculation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 29 Jan 2022 23:15:47 UTC
The branch main has been updated by chuck: URL: https://cgit.FreeBSD.org/src/commit/?id=9d8cd04694d47d48cc4003f8322739ba10fa8108 commit 9d8cd04694d47d48cc4003f8322739ba10fa8108 Author: Chuck Tuffli <chuck@FreeBSD.org> AuthorDate: 2022-01-30 07:09:57 +0000 Commit: Chuck Tuffli <chuck@FreeBSD.org> CommitDate: 2022-01-30 07:09:57 +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. Reviewed by: imp, allanjude, jhb Tested by: jason@tubnor.net MFC after: 1 month Differential Revision: https://reviews.freebsd.org/D33575 --- 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 ea3503bdbfc0..5ad7a0a59d65 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; }