Unverified Commit c3820641 authored by Richard Fitzgerald's avatar Richard Fitzgerald Committed by Mark Brown
Browse files

regmap: kunit: Fix memory leaks in gen_regmap() and gen_raw_regmap()



- Use kunit_kcalloc() to allocate the defaults table so that it will be
  freed when the test case ends.
- kfree() the buf and *data buffers on the error paths.
- Use kunit_add_action_or_reset() instead of kunit_add_action() so that
  if it fails it will call regmap_exit().

Signed-off-by: default avatarRichard Fitzgerald <rf@opensource.cirrus.com>
Link: https://msgid.link/r/20240411103724.54063-1-rf@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1613e604
Loading
Loading
Loading
Loading
+45 −27
Original line number Diff line number Diff line
@@ -145,9 +145,9 @@ static struct regmap *gen_regmap(struct kunit *test,
	const struct regmap_test_param *param = test->param_value;
	struct regmap_test_priv *priv = test->priv;
	unsigned int *buf;
	struct regmap *ret;
	struct regmap *ret = ERR_PTR(-ENOMEM);
	size_t size;
	int i;
	int i, error;
	struct reg_default *defaults;

	config->cache_type = param->cache;
@@ -172,15 +172,17 @@ static struct regmap *gen_regmap(struct kunit *test,

	*data = kzalloc(sizeof(**data), GFP_KERNEL);
	if (!(*data))
		return ERR_PTR(-ENOMEM);
		goto out_free;
	(*data)->vals = buf;

	if (config->num_reg_defaults) {
		defaults = kcalloc(config->num_reg_defaults,
		defaults = kunit_kcalloc(test,
					 config->num_reg_defaults,
					 sizeof(struct reg_default),
					 GFP_KERNEL);
		if (!defaults)
			return ERR_PTR(-ENOMEM);
			goto out_free;

		config->reg_defaults = defaults;

		for (i = 0; i < config->num_reg_defaults; i++) {
@@ -190,12 +192,19 @@ static struct regmap *gen_regmap(struct kunit *test,
	}

	ret = regmap_init_ram(priv->dev, config, *data);
	if (IS_ERR(ret)) {
	if (IS_ERR(ret))
		goto out_free;

	/* This calls regmap_exit() on failure, which frees buf and *data */
	error = kunit_add_action_or_reset(test, regmap_exit_action, ret);
	if (error)
		ret = ERR_PTR(error);

	return ret;

out_free:
	kfree(buf);
	kfree(*data);
	} else {
		kunit_add_action(test, regmap_exit_action, ret);
	}

	return ret;
}
@@ -1497,9 +1506,9 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
	struct regmap_test_priv *priv = test->priv;
	const struct regmap_test_param *param = test->param_value;
	u16 *buf;
	struct regmap *ret;
	struct regmap *ret = ERR_PTR(-ENOMEM);
	size_t size = (config->max_register + 1) * config->reg_bits / 8;
	int i;
	int i, error;
	struct reg_default *defaults;

	config->cache_type = param->cache;
@@ -1515,15 +1524,16 @@ static struct regmap *gen_raw_regmap(struct kunit *test,

	*data = kzalloc(sizeof(**data), GFP_KERNEL);
	if (!(*data))
		return ERR_PTR(-ENOMEM);
		goto out_free;
	(*data)->vals = (void *)buf;

	config->num_reg_defaults = config->max_register + 1;
	defaults = kcalloc(config->num_reg_defaults,
	defaults = kunit_kcalloc(test,
				 config->num_reg_defaults,
				 sizeof(struct reg_default),
				 GFP_KERNEL);
	if (!defaults)
		return ERR_PTR(-ENOMEM);
		goto out_free;
	config->reg_defaults = defaults;

	for (i = 0; i < config->num_reg_defaults; i++) {
@@ -1536,7 +1546,8 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
			defaults[i].def = be16_to_cpu(buf[i]);
			break;
		default:
			return ERR_PTR(-EINVAL);
			ret = ERR_PTR(-EINVAL);
			goto out_free;
		}
	}

@@ -1548,12 +1559,19 @@ static struct regmap *gen_raw_regmap(struct kunit *test,
		config->num_reg_defaults = 0;

	ret = regmap_init_raw_ram(priv->dev, config, *data);
	if (IS_ERR(ret)) {
	if (IS_ERR(ret))
		goto out_free;

	/* This calls regmap_exit() on failure, which frees buf and *data */
	error = kunit_add_action_or_reset(test, regmap_exit_action, ret);
	if (error)
		ret = ERR_PTR(error);

	return ret;

out_free:
	kfree(buf);
	kfree(*data);
	} else {
		kunit_add_action(test, regmap_exit_action, ret);
	}

	return ret;
}