Commit 474a8988 authored by Jesper Juhl's avatar Jesper Juhl Committed by Greg Kroah-Hartman

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: default avatarJesper Juhl <jj@chaosbits.net>
Acked-by: default avatarColin Cross <ccross@android.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 17b7e1ba
...@@ -399,12 +399,12 @@ static __init ...@@ -399,12 +399,12 @@ static __init
struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
{ {
struct persistent_ram_zone *prz; struct persistent_ram_zone *prz;
int ret; int ret = -ENOMEM;
prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL); prz = kzalloc(sizeof(struct persistent_ram_zone), GFP_KERNEL);
if (!prz) { if (!prz) {
pr_err("persistent_ram: failed to allocate persistent ram zone\n"); pr_err("persistent_ram: failed to allocate persistent ram zone\n");
return ERR_PTR(-ENOMEM); goto err;
} }
INIT_LIST_HEAD(&prz->node); INIT_LIST_HEAD(&prz->node);
...@@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) ...@@ -412,13 +412,13 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
ret = persistent_ram_buffer_init(dev_name(dev), prz); ret = persistent_ram_buffer_init(dev_name(dev), prz);
if (ret) { if (ret) {
pr_err("persistent_ram: failed to initialize buffer\n"); pr_err("persistent_ram: failed to initialize buffer\n");
return ERR_PTR(ret); goto err;
} }
prz->ecc = ecc; prz->ecc = ecc;
ret = persistent_ram_init_ecc(prz, prz->buffer_size); ret = persistent_ram_init_ecc(prz, prz->buffer_size);
if (ret) if (ret)
return ERR_PTR(ret); goto err;
if (prz->buffer->sig == PERSISTENT_RAM_SIG) { if (prz->buffer->sig == PERSISTENT_RAM_SIG) {
if (buffer_size(prz) > prz->buffer_size || if (buffer_size(prz) > prz->buffer_size ||
...@@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc) ...@@ -442,6 +442,9 @@ struct persistent_ram_zone *__persistent_ram_init(struct device *dev, bool ecc)
atomic_set(&prz->buffer->size, 0); atomic_set(&prz->buffer->size, 0);
return prz; return prz;
err:
kfree(prz);
return ERR_PTR(ret);
} }
struct persistent_ram_zone * __init struct persistent_ram_zone * __init
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment