mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2024-12-29 17:23:36 +00:00
ipv6: sr: fix memleak in seg6_hmac_init_algo
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: bf355b8d2c
("ipv6: sr: add core files for SR HMAC support")
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
Closes: https://lore.kernel.org/netdev/Zj3bh-gE7eT6V6aH@hog/
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://lore.kernel.org/r/20240517005435.2600277-1-liuhangbin@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
9841991a44
commit
efb9f4f19f
@ -356,6 +356,7 @@ static int seg6_hmac_init_algo(void)
|
|||||||
struct crypto_shash *tfm;
|
struct crypto_shash *tfm;
|
||||||
struct shash_desc *shash;
|
struct shash_desc *shash;
|
||||||
int i, alg_count, cpu;
|
int i, alg_count, cpu;
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
alg_count = ARRAY_SIZE(hmac_algos);
|
alg_count = ARRAY_SIZE(hmac_algos);
|
||||||
|
|
||||||
@ -366,12 +367,14 @@ static int seg6_hmac_init_algo(void)
|
|||||||
algo = &hmac_algos[i];
|
algo = &hmac_algos[i];
|
||||||
algo->tfms = alloc_percpu(struct crypto_shash *);
|
algo->tfms = alloc_percpu(struct crypto_shash *);
|
||||||
if (!algo->tfms)
|
if (!algo->tfms)
|
||||||
return -ENOMEM;
|
goto error_out;
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
tfm = crypto_alloc_shash(algo->name, 0, 0);
|
tfm = crypto_alloc_shash(algo->name, 0, 0);
|
||||||
if (IS_ERR(tfm))
|
if (IS_ERR(tfm)) {
|
||||||
return PTR_ERR(tfm);
|
ret = PTR_ERR(tfm);
|
||||||
|
goto error_out;
|
||||||
|
}
|
||||||
p_tfm = per_cpu_ptr(algo->tfms, cpu);
|
p_tfm = per_cpu_ptr(algo->tfms, cpu);
|
||||||
*p_tfm = tfm;
|
*p_tfm = tfm;
|
||||||
}
|
}
|
||||||
@ -383,18 +386,22 @@ static int seg6_hmac_init_algo(void)
|
|||||||
|
|
||||||
algo->shashs = alloc_percpu(struct shash_desc *);
|
algo->shashs = alloc_percpu(struct shash_desc *);
|
||||||
if (!algo->shashs)
|
if (!algo->shashs)
|
||||||
return -ENOMEM;
|
goto error_out;
|
||||||
|
|
||||||
for_each_possible_cpu(cpu) {
|
for_each_possible_cpu(cpu) {
|
||||||
shash = kzalloc_node(shsize, GFP_KERNEL,
|
shash = kzalloc_node(shsize, GFP_KERNEL,
|
||||||
cpu_to_node(cpu));
|
cpu_to_node(cpu));
|
||||||
if (!shash)
|
if (!shash)
|
||||||
return -ENOMEM;
|
goto error_out;
|
||||||
*per_cpu_ptr(algo->shashs, cpu) = shash;
|
*per_cpu_ptr(algo->shashs, cpu) = shash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
error_out:
|
||||||
|
seg6_hmac_exit();
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __init seg6_hmac_init(void)
|
int __init seg6_hmac_init(void)
|
||||||
@ -412,22 +419,29 @@ int __net_init seg6_hmac_net_init(struct net *net)
|
|||||||
void seg6_hmac_exit(void)
|
void seg6_hmac_exit(void)
|
||||||
{
|
{
|
||||||
struct seg6_hmac_algo *algo = NULL;
|
struct seg6_hmac_algo *algo = NULL;
|
||||||
|
struct crypto_shash *tfm;
|
||||||
|
struct shash_desc *shash;
|
||||||
int i, alg_count, cpu;
|
int i, alg_count, cpu;
|
||||||
|
|
||||||
alg_count = ARRAY_SIZE(hmac_algos);
|
alg_count = ARRAY_SIZE(hmac_algos);
|
||||||
for (i = 0; i < alg_count; i++) {
|
for (i = 0; i < alg_count; i++) {
|
||||||
algo = &hmac_algos[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);
|
if (algo->shashs) {
|
||||||
kfree(shash);
|
for_each_possible_cpu(cpu) {
|
||||||
tfm = *per_cpu_ptr(algo->tfms, cpu);
|
shash = *per_cpu_ptr(algo->shashs, cpu);
|
||||||
crypto_free_shash(tfm);
|
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);
|
EXPORT_SYMBOL(seg6_hmac_exit);
|
||||||
|
Loading…
Reference in New Issue
Block a user