aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesper Juhl <jj@chaosbits.net>2012-04-11 16:10:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-12 17:34:32 -0400
commit474a89885f77953b12bce9f23660c31ef5c2630e (patch)
tree2da1f0498aa3f93ffb91b2a7305169286976f6cd
parent17b7e1ba1e2ecc9a09f5e154e555accd2a2eaedf (diff)
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 <jj@chaosbits.net> Acked-by: Colin Cross <ccross@android.com> Cc: stable <stable@vger.kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/android/persistent_ram.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/staging/android/persistent_ram.c b/drivers/staging/android/persistent_ram.c
index e08f2574e30a..8d8c1e33e0ff 100644
--- a/drivers/staging/android/persistent_ram.c
+++ b/drivers/staging/android/persistent_ram.c
@@ -399,12 +399,12 @@ static __init
399struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) 399struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
400{ 400{
401 struct persistent_ram_zone *prz; 401 struct persistent_ram_zone *prz;
402 int ret; 402 int ret = -ENOMEM;
403 403
404 prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); 404 prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
405 if (!prz) { 405 if (!prz) {
406 pr_err("persistent_ram: failed to allocate persistent ram zone\n"); 406 pr_err("persistent_ram: failed to allocate persistent ram zone\n");
407 return ERR_PTR(-ENOMEM); 407 goto err;
408 } 408 }
409 409
410 INIT_LIST_HEAD(&prz->node); 410 INIT_LIST_HEAD(&prz->node);
@@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
412 ret = persistent_ram_buffer_init(dev_name(dev), prz); 412 ret = persistent_ram_buffer_init(dev_name(dev), prz);
413 if (ret) { 413 if (ret) {
414 pr_err("persistent_ram: failed to initialize buffer\n"); 414 pr_err("persistent_ram: failed to initialize buffer\n");
415 return ERR_PTR(ret); 415 goto err;
416 } 416 }
417 417
418 prz->ecc = ecc; 418 prz->ecc = ecc;
419 ret = persistent_ram_init_ecc(prz, prz->buffer_size); 419 ret = persistent_ram_init_ecc(prz, prz->buffer_size);
420 if (ret) 420 if (ret)
421 return ERR_PTR(ret); 421 goto err;
422 422
423 if (prz->buffer->sig == PERSISTENT_RAM_SIG) { 423 if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
424 if (buffer_size(prz) > prz->buffer_size || 424 if (buffer_size(prz) > prz->buffer_size ||
@@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
442 atomic_set(&prz->buffer->size, 0); 442 atomic_set(&prz->buffer->size, 0);
443 443
444 return prz; 444 return prz;
445err:
446 kfree(prz);
447 return ERR_PTR(ret);
445} 448}
446 449
447struct persistent_ram_zone * __init 450struct persistent_ram_zone * __init