dm-verity: fix a memory leak if some arguments are specified multiple times
commit 66be40a14e496689e1f0add50118408e22c96169 upstream. 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: Mikulas Patocka <mpatocka@redhat.com> Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
61850a1b26
commit
df4918c0bb
@@ -624,6 +624,10 @@ int verity_fec_parse_opt_args(struct dm_arg_set *as, struct dm_verity *v,
|
|||||||
(*argc)--;
|
(*argc)--;
|
||||||
|
|
||||||
if (!strcasecmp(arg_name, DM_VERITY_OPT_FEC_DEV)) {
|
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);
|
r = dm_get_device(ti, arg_value, BLK_OPEN_READ, &v->fec->dev);
|
||||||
if (r) {
|
if (r) {
|
||||||
ti->error = "FEC device lookup failed";
|
ti->error = "FEC device lookup failed";
|
||||||
|
@@ -1043,6 +1043,9 @@ static int verity_alloc_most_once(struct dm_verity *v)
|
|||||||
{
|
{
|
||||||
struct dm_target *ti = v->ti;
|
struct dm_target *ti = v->ti;
|
||||||
|
|
||||||
|
if (v->validated_blocks)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* the bitset can only handle INT_MAX blocks */
|
/* the bitset can only handle INT_MAX blocks */
|
||||||
if (v->data_blocks > INT_MAX) {
|
if (v->data_blocks > INT_MAX) {
|
||||||
ti->error = "device too large to use check_at_most_once";
|
ti->error = "device too large to use check_at_most_once";
|
||||||
@@ -1066,6 +1069,9 @@ static int verity_alloc_zero_digest(struct dm_verity *v)
|
|||||||
struct ahash_request *req;
|
struct ahash_request *req;
|
||||||
u8 *zero_data;
|
u8 *zero_data;
|
||||||
|
|
||||||
|
if (v->zero_digest)
|
||||||
|
return 0;
|
||||||
|
|
||||||
v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL);
|
v->zero_digest = kmalloc(v->digest_size, GFP_KERNEL);
|
||||||
|
|
||||||
if (!v->zero_digest)
|
if (!v->zero_digest)
|
||||||
@@ -1405,7 +1411,7 @@ static int verity_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
|||||||
goto bad;
|
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,
|
r = verity_verify_root_hash(root_hash_digest_to_validate,
|
||||||
strlen(root_hash_digest_to_validate),
|
strlen(root_hash_digest_to_validate),
|
||||||
verify_args.sig,
|
verify_args.sig,
|
||||||
|
@@ -71,9 +71,14 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
|
|||||||
const char *arg_name)
|
const char *arg_name)
|
||||||
{
|
{
|
||||||
struct dm_target *ti = v->ti;
|
struct dm_target *ti = v->ti;
|
||||||
int ret = 0;
|
int ret;
|
||||||
const char *sig_key = NULL;
|
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) {
|
if (!*argc) {
|
||||||
ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified");
|
ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@@ -83,14 +88,18 @@ int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
|
|||||||
(*argc)--;
|
(*argc)--;
|
||||||
|
|
||||||
ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
|
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");
|
ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
v->signature_key_desc = kstrdup(sig_key, GFP_KERNEL);
|
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 -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user