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

Commit e4d77590 authored by Bao D. Nguyen's avatar Bao D. Nguyen
Browse files

scsi: ufs: Fix potential memory leak



The function ufs_read_device_desc_data() allocates some memory
for use in reading the device descriptor, but it fails to free
the memory when done. Add kfree() to fix the potential memory leak.
In addition, this change replaces the kstrdup() with devm_kzalloc()
so that the allocated memory is freed when the driver is unloaded.

Change-Id: Ib5daa516fcd8e93a2f8cfbe7058c97b673d4f133
Signed-off-by: default avatarBao D. Nguyen <nguyenb@codeaurora.org>
parent 679dfb32
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)
	struct ufs_clk_info *clki;
	int len = 0;
	size_t sz = 0;
	char *str = NULL;

	if (!np)
		goto out;
@@ -131,7 +132,15 @@ static int ufshcd_parse_clock_info(struct ufs_hba *hba)

		clki->min_freq = clkfreq[i];
		clki->max_freq = clkfreq[i+1];
		clki->name = kstrdup(name, GFP_KERNEL);
		str = devm_kzalloc(dev, strlen(name) + 1, GFP_KERNEL);
		if (!str) {
			ret = -ENOMEM;
			goto out;
		}

		memcpy(str, name, strlen(name) + 1);
		clki->name = str;

		dev_dbg(dev, "%s: min %u max %u name %s\n", "freq-table-hz",
				clki->min_freq, clki->max_freq, clki->name);
		list_add_tail(&clki->list, &hba->clk_list_head);
@@ -149,6 +158,7 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
	struct ufs_vreg *vreg = NULL;
	struct device_node *np = dev->of_node;
	const __be32 *prop;
	char *str = NULL;

	if (!np) {
		dev_err(dev, "%s: non DT initialization\n", __func__);
@@ -166,7 +176,11 @@ static int ufshcd_populate_vreg(struct device *dev, const char *name,
	if (!vreg)
		return -ENOMEM;

	vreg->name = kstrdup(name, GFP_KERNEL);
	str = devm_kzalloc(dev, strlen(name) + 1, GFP_KERNEL);
	if (!str)
		return -ENOMEM;
	memcpy(str, name, strlen(name) + 1);
	vreg->name = str;

	/* if fixed regulator no need further initialization */
	snprintf(prop_name, MAX_PROP_SIZE, "%s-fixed-regulator", name);
+7 −9
Original line number Diff line number Diff line
@@ -8279,10 +8279,8 @@ static int ufs_get_device_desc(struct ufs_hba *hba,
	buff_len = max_t(size_t, hba->desc_size.dev_desc,
			 QUERY_DESC_MAX_SIZE + 1);
	desc_buf = kmalloc(buff_len, GFP_KERNEL);
	if (!desc_buf) {
		err = -ENOMEM;
		goto out;
	}
	if (!desc_buf)
		return -ENOMEM;

	err = ufshcd_read_device_desc(hba, desc_buf, hba->desc_size.dev_desc);
	if (err) {
@@ -8685,15 +8683,14 @@ static int ufs_read_device_desc_data(struct ufs_hba *hba)
	if (hba->desc_size.dev_desc) {
		desc_buf = kmalloc(hba->desc_size.dev_desc, GFP_KERNEL);
		if (!desc_buf) {
			err = -ENOMEM;
			dev_err(hba->dev,
				"%s: Failed to allocate desc_buf\n", __func__);
			return err;
			return -ENOMEM;
		}
	}
	err = ufshcd_read_device_desc(hba, desc_buf, hba->desc_size.dev_desc);
	if (err)
		return err;
		goto out;

	/*
	 * getting vendor (manufacturerID) and Bank Index in big endian
@@ -8708,8 +8705,9 @@ static int ufs_read_device_desc_data(struct ufs_hba *hba)
	hba->dev_info.w_spec_version =
		desc_buf[DEVICE_DESC_PARAM_SPEC_VER] << 8 |
		desc_buf[DEVICE_DESC_PARAM_SPEC_VER + 1];

	return 0;
out:
	kfree(desc_buf);
	return err;
}

static inline bool ufshcd_needs_reinit(struct ufs_hba *hba)