Skip to content

Commit

Permalink
ipv6: sr: fix memleak in seg6_hmac_init_algo
Browse files Browse the repository at this point in the history
[ Upstream commit efb9f4f19f8e37fde43dfecebc80292d179f56c6 ]

seg6_hmac_init_algo returns without cleaning up the previous allocations
if one fails, so it's going to leak all that memory and the crypto tfms.

Update seg6_hmac_exit to only free the memory when allocated, so we can
reuse the code directly.

Fixes: bf355b8 ("ipv6: sr: add core files for SR HMAC support")
Reported-by: Sabrina Dubroca <[email protected]>
Closes: https://lore.kernel.org/netdev/Zj3bh-gE7eT6V6aH@hog/
Signed-off-by: Hangbin Liu <[email protected]>
Reviewed-by: Simon Horman <[email protected]>
Reviewed-by: Sabrina Dubroca <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Paolo Abeni <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
  • Loading branch information
liuhangbin authored and gregkh committed Jun 16, 2024
1 parent 406cfac commit afd5730
Showing 1 changed file with 28 additions and 14 deletions.
42 changes: 28 additions & 14 deletions net/ipv6/seg6_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ static int seg6_hmac_init_algo(void)
struct crypto_shash *tfm;
struct shash_desc *shash;
int i, alg_count, cpu;
int ret = -ENOMEM;

alg_count = ARRAY_SIZE(hmac_algos);

Expand All @@ -371,12 +372,14 @@ static int seg6_hmac_init_algo(void)
algo = &hmac_algos[i];
algo->tfms = alloc_percpu(struct crypto_shash *);
if (!algo->tfms)
return -ENOMEM;
goto error_out;

for_each_possible_cpu(cpu) {
tfm = crypto_alloc_shash(algo->name, 0, 0);
if (IS_ERR(tfm))
return PTR_ERR(tfm);
if (IS_ERR(tfm)) {
ret = PTR_ERR(tfm);
goto error_out;
}
p_tfm = per_cpu_ptr(algo->tfms, cpu);
*p_tfm = tfm;
}
Expand All @@ -388,18 +391,22 @@ static int seg6_hmac_init_algo(void)

algo->shashs = alloc_percpu(struct shash_desc *);
if (!algo->shashs)
return -ENOMEM;
goto error_out;

for_each_possible_cpu(cpu) {
shash = kzalloc_node(shsize, GFP_KERNEL,
cpu_to_node(cpu));
if (!shash)
return -ENOMEM;
goto error_out;
*per_cpu_ptr(algo->shashs, cpu) = shash;
}
}

return 0;

error_out:
seg6_hmac_exit();
return ret;
}

int __init seg6_hmac_init(void)
Expand All @@ -419,22 +426,29 @@ int __net_init seg6_hmac_net_init(struct net *net)
void seg6_hmac_exit(void)
{
struct seg6_hmac_algo *algo = NULL;
struct crypto_shash *tfm;
struct shash_desc *shash;
int i, alg_count, cpu;

alg_count = ARRAY_SIZE(hmac_algos);
for (i = 0; i < alg_count; i++) {
algo = &hmac_algos[i];
for_each_possible_cpu(cpu) {
struct crypto_shash *tfm;
struct shash_desc *shash;

shash = *per_cpu_ptr(algo->shashs, cpu);
kfree(shash);
tfm = *per_cpu_ptr(algo->tfms, cpu);
crypto_free_shash(tfm);
if (algo->shashs) {
for_each_possible_cpu(cpu) {
shash = *per_cpu_ptr(algo->shashs, cpu);
kfree(shash);
}
free_percpu(algo->shashs);
}

if (algo->tfms) {
for_each_possible_cpu(cpu) {
tfm = *per_cpu_ptr(algo->tfms, cpu);
crypto_free_shash(tfm);
}
free_percpu(algo->tfms);
}
free_percpu(algo->tfms);
free_percpu(algo->shashs);
}
}
EXPORT_SYMBOL(seg6_hmac_exit);
Expand Down

0 comments on commit afd5730

Please sign in to comment.