Commit 66be40a1 authored by Mikulas Patocka's avatar Mikulas Patocka
Browse files

dm-verity: fix a memory leak if some arguments are specified multiple times



If some of the arguments "check_at_most_once", "ignore_zero_blocks",
"use_fec_from_device", "root_hash_sig_key_desc" were specified more than
once on the target line, a memory leak would happen.

This commit fixes the memory leak. It also fixes error handling in
verity_verify_sig_parse_opt_args.

Signed-off-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
parent 829451be
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -593,6 +593,10 @@ int verity_fec_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
	(*argc)--;

	if (!strcasecmp(arg_name, DM_VERITY_OPT_FEC_DEV)) {
		if (v->fec->dev) {
			ti->error = "FEC device already specified";
			return -EINVAL;
		}
		r = dm_get_device(ti, arg_value, BLK_OPEN_READ, &v->fec->dev);
		if (r) {
			ti->error = "FEC device lookup failed";
+7 −1
Original line number Diff line number Diff line
@@ -1123,6 +1123,9 @@ static int verity_alloc_most_once(struct dm_verity *v)
{
	struct dm_target *ti = v->ti;

	if (v->validated_blocks)
		return 0;

	/* the bitset can only handle INT_MAX blocks */
	if (v->data_blocks > INT_MAX) {
		ti->error = "device too large to use check_at_most_once";
@@ -1146,6 +1149,9 @@ static int verity_alloc_zero_digest(struct dm_verity *v)
	struct dm_verity_io *io;
	u8 *zero_data;

	if (v->zero_digest)
		return 0;

	v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL);

	if (!v->zero_digest)
@@ -1580,7 +1586,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
			goto bad;
	}

	/* Root hash signature is  a optional parameter*/
	/* Root hash signature is an optional parameter */
	r = verity_verify_root_hash(root_hash_digest_to_validate,
				    strlen(root_hash_digest_to_validate),
				    verify_args.sig,
+13 −4
Original line number Diff line number Diff line
@@ -71,9 +71,14 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
				     const char *arg_name)
{
	struct dm_target *ti = v->ti;
	int ret = 0;
	int ret;
	const char *sig_key = NULL;

	if (v->signature_key_desc) {
		ti->error = DM_VERITY_VERIFY_ERR("root_hash_sig_key_desc already specified");
		return -EINVAL;
	}

	if (!*argc) {
		ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified");
		return -EINVAL;
@@ -83,14 +88,18 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
	(*argc)--;

	ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
	if (ret < 0)
	if (ret < 0) {
		ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");
		return ret;
	}

	v->signature_key_desc = kstrdup(sig_key, GFP_KERNEL);
	if (!v->signature_key_desc)
	if (!v->signature_key_desc) {
		ti->error = DM_VERITY_VERIFY_ERR("Could not allocate memory for signature key");
		return -ENOMEM;
	}

	return ret;
	return 0;
}

/*