Skip to content

Commit efb9f4f

Browse files
liuhangbinPaolo Abeni
authored andcommitted
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: 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]>
1 parent 9841991 commit efb9f4f

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

net/ipv6/seg6_hmac.c

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ static int seg6_hmac_init_algo(void)
356356
struct crypto_shash *tfm;
357357
struct shash_desc *shash;
358358
int i, alg_count, cpu;
359+
int ret = -ENOMEM;
359360

360361
alg_count = ARRAY_SIZE(hmac_algos);
361362

@@ -366,12 +367,14 @@ static int seg6_hmac_init_algo(void)
366367
algo = &hmac_algos[i];
367368
algo->tfms = alloc_percpu(struct crypto_shash *);
368369
if (!algo->tfms)
369-
return -ENOMEM;
370+
goto error_out;
370371

371372
for_each_possible_cpu(cpu) {
372373
tfm = crypto_alloc_shash(algo->name, 0, 0);
373-
if (IS_ERR(tfm))
374-
return PTR_ERR(tfm);
374+
if (IS_ERR(tfm)) {
375+
ret = PTR_ERR(tfm);
376+
goto error_out;
377+
}
375378
p_tfm = per_cpu_ptr(algo->tfms, cpu);
376379
*p_tfm = tfm;
377380
}
@@ -383,18 +386,22 @@ static int seg6_hmac_init_algo(void)
383386

384387
algo->shashs = alloc_percpu(struct shash_desc *);
385388
if (!algo->shashs)
386-
return -ENOMEM;
389+
goto error_out;
387390

388391
for_each_possible_cpu(cpu) {
389392
shash = kzalloc_node(shsize, GFP_KERNEL,
390393
cpu_to_node(cpu));
391394
if (!shash)
392-
return -ENOMEM;
395+
goto error_out;
393396
*per_cpu_ptr(algo->shashs, cpu) = shash;
394397
}
395398
}
396399

397400
return 0;
401+
402+
error_out:
403+
seg6_hmac_exit();
404+
return ret;
398405
}
399406

400407
int __init seg6_hmac_init(void)
@@ -412,22 +419,29 @@ int __net_init seg6_hmac_net_init(struct net *net)
412419
void seg6_hmac_exit(void)
413420
{
414421
struct seg6_hmac_algo *algo = NULL;
422+
struct crypto_shash *tfm;
423+
struct shash_desc *shash;
415424
int i, alg_count, cpu;
416425

417426
alg_count = ARRAY_SIZE(hmac_algos);
418427
for (i = 0; i < alg_count; i++) {
419428
algo = &hmac_algos[i];
420-
for_each_possible_cpu(cpu) {
421-
struct crypto_shash *tfm;
422-
struct shash_desc *shash;
423429

424-
shash = *per_cpu_ptr(algo->shashs, cpu);
425-
kfree(shash);
426-
tfm = *per_cpu_ptr(algo->tfms, cpu);
427-
crypto_free_shash(tfm);
430+
if (algo->shashs) {
431+
for_each_possible_cpu(cpu) {
432+
shash = *per_cpu_ptr(algo->shashs, cpu);
433+
kfree(shash);
434+
}
435+
free_percpu(algo->shashs);
436+
}
437+
438+
if (algo->tfms) {
439+
for_each_possible_cpu(cpu) {
440+
tfm = *per_cpu_ptr(algo->tfms, cpu);
441+
crypto_free_shash(tfm);
442+
}
443+
free_percpu(algo->tfms);
428444
}
429-
free_percpu(algo->tfms);
430-
free_percpu(algo->shashs);
431445
}
432446
}
433447
EXPORT_SYMBOL(seg6_hmac_exit);

0 commit comments

Comments
 (0)