Unverified Commit 70d4c93a authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15680 scsi: ufs: core: Fix use-after free in init error and remove paths

parents 29f7045c 37b72085
Loading
Loading
Loading
Loading
+21 −10
Original line number Diff line number Diff line
@@ -10219,16 +10219,6 @@ int ufshcd_system_thaw(struct device *dev)
EXPORT_SYMBOL_GPL(ufshcd_system_thaw);
#endif /* CONFIG_PM_SLEEP  */

/**
 * ufshcd_dealloc_host - deallocate Host Bus Adapter (HBA)
 * @hba: pointer to Host Bus Adapter (HBA)
 */
void ufshcd_dealloc_host(struct ufs_hba *hba)
{
	scsi_host_put(hba->host);
}
EXPORT_SYMBOL_GPL(ufshcd_dealloc_host);

/**
 * ufshcd_set_dma_mask - Set dma mask based on the controller
 *			 addressing capability
@@ -10247,12 +10237,26 @@ static int ufshcd_set_dma_mask(struct ufs_hba *hba)
	return dma_set_mask_and_coherent(hba->dev, DMA_BIT_MASK(32));
}

/**
 * ufshcd_devres_release - devres cleanup handler, invoked during release of
 *			   hba->dev
 * @host: pointer to SCSI host
 */
static void ufshcd_devres_release(void *host)
{
	scsi_host_put(host);
}

/**
 * ufshcd_alloc_host - allocate Host Bus Adapter (HBA)
 * @dev: pointer to device handle
 * @hba_handle: driver private handle
 *
 * Return: 0 on success, non-zero value on failure.
 *
 * NOTE: There is no corresponding ufshcd_dealloc_host() because this function
 * keeps track of its allocations using devres and deallocates everything on
 * device removal automatically.
 */
int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
{
@@ -10274,6 +10278,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
		err = -ENOMEM;
		goto out_error;
	}

	err = devm_add_action_or_reset(dev, ufshcd_devres_release,
				       host);
	if (err)
		return dev_err_probe(dev, err,
				     "failed to add ufshcd dealloc action\n");

	host->nr_maps = HCTX_TYPE_POLL + 1;
	hba = shost_priv(host);
	hba->host = host;
+0 −2
Original line number Diff line number Diff line
@@ -516,7 +516,6 @@ static void ufshcd_pci_remove(struct pci_dev *pdev)
	pm_runtime_forbid(&pdev->dev);
	pm_runtime_get_noresume(&pdev->dev);
	ufshcd_remove(hba);
	ufshcd_dealloc_host(hba);
}

/**
@@ -561,7 +560,6 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
	err = ufshcd_init(hba, mmio_base, pdev->irq);
	if (err) {
		dev_err(&pdev->dev, "Initialization failed\n");
		ufshcd_dealloc_host(hba);
		return err;
	}

+8 −18
Original line number Diff line number Diff line
@@ -339,21 +339,17 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
	struct device *dev = &pdev->dev;

	mmio_base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(mmio_base)) {
		err = PTR_ERR(mmio_base);
		goto out;
	}
	if (IS_ERR(mmio_base))
		return PTR_ERR(mmio_base);

	irq = platform_get_irq(pdev, 0);
	if (irq < 0) {
		err = irq;
		goto out;
	}
	if (irq < 0)
		return irq;

	err = ufshcd_alloc_host(dev, &hba);
	if (err) {
		dev_err(dev, "Allocation failed\n");
		goto out;
		return err;
	}

	hba->vops = vops;
@@ -362,13 +358,13 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
	if (err) {
		dev_err(dev, "%s: clock parse failed %d\n",
				__func__, err);
		goto dealloc_host;
		return err;
	}
	err = ufshcd_parse_regulator_info(hba);
	if (err) {
		dev_err(dev, "%s: regulator init failed %d\n",
				__func__, err);
		goto dealloc_host;
		return err;
	}

	ufshcd_init_lanes_per_dir(hba);
@@ -377,18 +373,13 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
	if (err) {
		dev_err_probe(dev, err, "Initialization failed with error %d\n",
			      err);
		goto dealloc_host;
		return err;
	}

	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	return 0;

dealloc_host:
	ufshcd_dealloc_host(hba);
out:
	return err;
}
EXPORT_SYMBOL_GPL(ufshcd_pltfrm_init);

@@ -402,7 +393,6 @@ void ufshcd_pltfrm_remove(struct platform_device *pdev)

	pm_runtime_get_sync(&pdev->dev);
	ufshcd_remove(hba);
	ufshcd_dealloc_host(hba);
	pm_runtime_disable(&pdev->dev);
	pm_runtime_put_noidle(&pdev->dev);
}
+0 −1
Original line number Diff line number Diff line
@@ -1235,7 +1235,6 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg)
}

int ufshcd_alloc_host(struct device *, struct ufs_hba **);
void ufshcd_dealloc_host(struct ufs_hba *);
int ufshcd_hba_enable(struct ufs_hba *hba);
int ufshcd_init(struct ufs_hba *, void __iomem *, unsigned int);
int ufshcd_link_recovery(struct ufs_hba *hba);