Skip to content

Commit 474a898

Browse files
jjuhlgregkh
authored andcommitted
staging: android: fix mem leaks in __persistent_ram_init()
If, in __persistent_ram_init(), the call to persistent_ram_buffer_init() fails or the call to persistent_ram_init_ecc() fails then we fail to free the memory we allocated to 'prz' with kzalloc() - thus leaking it. To prevent the leaks I consolidated all error exits from the function at a 'err:' label at the end and made all error cases jump to that label where we can then make sure we always free 'prz'. This is safe since all the situations where the code bails out happen before 'prz' has been stored anywhere and although we'll do a redundant kfree(NULL) call in the case of kzalloc() itself failing that's OK since kfree() deals gracefully with NULL pointers and I felt it was more important to keep all error exits at a single location than to avoid that one harmless/redundant kfree() on a error path. Signed-off-by: Jesper Juhl <[email protected]> Acked-by: Colin Cross <[email protected]> Cc: stable <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 17b7e1b commit 474a898

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

drivers/staging/android/persistent_ram.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -399,26 +399,26 @@ static __init
399399
struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
400400
{
401401
struct persistent_ram_zone *prz;
402-
int ret;
402+
int ret = -ENOMEM;
403403

404404
prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
405405
if (!prz) {
406406
pr_err("persistent_ram: failed to allocate persistent ram zone\n");
407-
return ERR_PTR(-ENOMEM);
407+
goto err;
408408
}
409409

410410
INIT_LIST_HEAD(&prz->node);
411411

412412
ret = persistent_ram_buffer_init(dev_name(dev), prz);
413413
if (ret) {
414414
pr_err("persistent_ram: failed to initialize buffer\n");
415-
return ERR_PTR(ret);
415+
goto err;
416416
}
417417

418418
prz->ecc = ecc;
419419
ret = persistent_ram_init_ecc(prz, prz->buffer_size);
420420
if (ret)
421-
return ERR_PTR(ret);
421+
goto err;
422422

423423
if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
424424
if (buffer_size(prz) > prz->buffer_size ||
@@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
442442
atomic_set(&prz->buffer->size, 0);
443443

444444
return prz;
445+
err:
446+
kfree(prz);
447+
return ERR_PTR(ret);
445448
}
446449

447450
struct persistent_ram_zone * __init

0 commit comments

Comments
 (0)