diff options
author | Dan Carpenter <error27@gmail.com> | 2011-02-15 05:10:08 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:32:36 -0400 |
commit | 07988007f8dd2827ba1eb39e6e3c5bbb29cfc30b (patch) | |
tree | 9ddac7f907a90e7ca9e433122c058ecf80c82c77 | |
parent | 57f05bfa2e90fe52fa36755f4cb91e6f495f8353 (diff) |
[media] stv090x: handle allocation failures
kmalloc() can fail so check whether state->internal is NULL.
append_internal() can return NULL on allocation failures so check that.
Also if we hit the error condition later in the function then there is
a memory leak and we need to call remove_dev() to fix it.
Also Oliver Endriss pointed out an additional leak that I missed in the
first version of this patch.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Acked-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/dvb/frontends/stv090x.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c index d3362d0407eb..41d0f0a6655d 100644 --- a/drivers/media/dvb/frontends/stv090x.c +++ b/drivers/media/dvb/frontends/stv090x.c | |||
@@ -4783,7 +4783,13 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | |||
4783 | } else { | 4783 | } else { |
4784 | state->internal = kmalloc(sizeof(struct stv090x_internal), | 4784 | state->internal = kmalloc(sizeof(struct stv090x_internal), |
4785 | GFP_KERNEL); | 4785 | GFP_KERNEL); |
4786 | if (!state->internal) | ||
4787 | goto error; | ||
4786 | temp_int = append_internal(state->internal); | 4788 | temp_int = append_internal(state->internal); |
4789 | if (!temp_int) { | ||
4790 | kfree(state->internal); | ||
4791 | goto error; | ||
4792 | } | ||
4787 | state->internal->num_used = 1; | 4793 | state->internal->num_used = 1; |
4788 | state->internal->mclk = 0; | 4794 | state->internal->mclk = 0; |
4789 | state->internal->dev_ver = 0; | 4795 | state->internal->dev_ver = 0; |
@@ -4796,7 +4802,7 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | |||
4796 | 4802 | ||
4797 | if (stv090x_setup(&state->frontend) < 0) { | 4803 | if (stv090x_setup(&state->frontend) < 0) { |
4798 | dprintk(FE_ERROR, 1, "Error setting up device"); | 4804 | dprintk(FE_ERROR, 1, "Error setting up device"); |
4799 | goto error; | 4805 | goto err_remove; |
4800 | } | 4806 | } |
4801 | } | 4807 | } |
4802 | 4808 | ||
@@ -4811,6 +4817,9 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, | |||
4811 | 4817 | ||
4812 | return &state->frontend; | 4818 | return &state->frontend; |
4813 | 4819 | ||
4820 | err_remove: | ||
4821 | remove_dev(state->internal); | ||
4822 | kfree(state->internal); | ||
4814 | error: | 4823 | error: |
4815 | kfree(state); | 4824 | kfree(state); |
4816 | return NULL; | 4825 | return NULL; |