Commit e7c01987 authored by Nick Connolly's avatar Nick Connolly Committed by Tomasz Zawadzki
Browse files

module/bdev/nvme: improve portability



In nvme_bdev_ctrlr_create, calloc will be called with a zero size
allocation request if the number of namespaces is zero. The behaviour
is implementation defined if the size of the space requested is zero -
calloc will either return a pointer that mustn't be dereferenced, or
NULL. If NULL is returned, the nvme_bdev_ctrlr_create will fail.

Only call calloc if there are a non-zero number of namespaces.
Otherwise, leave the namespaces pointer with a NULL value. All
references to namespaces[] are either known to be safe, or occur
in the context of looping through the namespaces which will be
skipped if the count is zero. The exception to this is in
vbdev_opal_create, where an assert has been added to match
equivalent code in bdev_ocssd_create_bdev.

Tested by running unit tests on a system that returns a null pointer
for a zero size allocation.

Signed-off-by: default avatarNick Connolly <nick.connolly@mayadata.io>
Change-Id: I058b0683fd9b3a20bf90e54db93ca48b9bb4e40e
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6551


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarsunshihao <sunshihao@huawei.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@mellanox.com>
parent d5cd0b13
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -1529,12 +1529,14 @@ nvme_bdev_ctrlr_create(struct spdk_nvme_ctrlr *ctrlr,

	TAILQ_INIT(&nvme_bdev_ctrlr->trids);
	nvme_bdev_ctrlr->num_ns = spdk_nvme_ctrlr_get_num_ns(ctrlr);
	if (nvme_bdev_ctrlr->num_ns != 0) {
		nvme_bdev_ctrlr->namespaces = calloc(nvme_bdev_ctrlr->num_ns, sizeof(struct nvme_bdev_ns *));
		if (!nvme_bdev_ctrlr->namespaces) {
			SPDK_ERRLOG("Failed to allocate block namespaces pointer\n");
			rc = -ENOMEM;
			goto err_alloc_namespaces;
		}
	}

	trid_entry = calloc(1, sizeof(*trid_entry));
	if (trid_entry == NULL) {
+1 −0
Original line number Diff line number Diff line
@@ -356,6 +356,7 @@ vbdev_opal_create(const char *nvme_ctrlr_name, uint32_t nsid, uint8_t locking_ra
	opal_bdev->nvme_ctrlr = nvme_ctrlr;
	opal_bdev->opal_dev = nvme_ctrlr->opal_dev;

	assert(nsid <= nvme_ctrlr->num_ns);
	nvme_bdev = nvme_bdev_ns_to_bdev(nvme_ctrlr->namespaces[nsid - 1]);
	assert(nvme_bdev != NULL);
	base_bdev_name = nvme_bdev->disk.name;