Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7168d914 authored by Dan Carpenter's avatar Dan Carpenter Committed by Ohad Ben-Cohen
Browse files

remoteproc: fix a potential NULL-dereference on cleanup



We only need to allocate mapping if there is an IOMMU domain.

Otherwise, when the mappings are released, the assumption that
an IOMMU domain is there will crash and burn.

CC: stable@vger.kernel.org
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
[ohad: revise commit log]
Signed-off-by: default avatarOhad Ben-Cohen <ohad@wizery.com>
parent 2ed6d29c
Loading
Loading
Loading
Loading
+11 −11
Original line number Original line Diff line number Diff line
@@ -573,17 +573,10 @@ static int rproc_handle_carveout(struct rproc *rproc,
	dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
	dev_dbg(dev, "carveout rsc: da %x, pa %x, len %x, flags %x\n",
			rsc->da, rsc->pa, rsc->len, rsc->flags);
			rsc->da, rsc->pa, rsc->len, rsc->flags);


	mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
	if (!mapping) {
		dev_err(dev, "kzalloc mapping failed\n");
		return -ENOMEM;
	}

	carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
	carveout = kzalloc(sizeof(*carveout), GFP_KERNEL);
	if (!carveout) {
	if (!carveout) {
		dev_err(dev, "kzalloc carveout failed\n");
		dev_err(dev, "kzalloc carveout failed\n");
		ret = -ENOMEM;
		return -ENOMEM;
		goto free_mapping;
	}
	}


	va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
	va = dma_alloc_coherent(dev->parent, rsc->len, &dma, GFP_KERNEL);
@@ -613,11 +606,18 @@ static int rproc_handle_carveout(struct rproc *rproc,
	 * physical address in this case.
	 * physical address in this case.
	 */
	 */
	if (rproc->domain) {
	if (rproc->domain) {
		mapping = kzalloc(sizeof(*mapping), GFP_KERNEL);
		if (!mapping) {
			dev_err(dev, "kzalloc mapping failed\n");
			ret = -ENOMEM;
			goto dma_free;
		}

		ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
		ret = iommu_map(rproc->domain, rsc->da, dma, rsc->len,
								rsc->flags);
								rsc->flags);
		if (ret) {
		if (ret) {
			dev_err(dev, "iommu_map failed: %d\n", ret);
			dev_err(dev, "iommu_map failed: %d\n", ret);
			goto dma_free;
			goto free_mapping;
		}
		}


		/*
		/*
@@ -662,12 +662,12 @@ static int rproc_handle_carveout(struct rproc *rproc,


	return 0;
	return 0;


free_mapping:
	kfree(mapping);
dma_free:
dma_free:
	dma_free_coherent(dev->parent, rsc->len, va, dma);
	dma_free_coherent(dev->parent, rsc->len, va, dma);
free_carv:
free_carv:
	kfree(carveout);
	kfree(carveout);
free_mapping:
	kfree(mapping);
	return ret;
	return ret;
}
}