diff options
author | Jesper Juhl <jj@chaosbits.net> | 2010-11-20 22:36:49 +0100 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2010-11-20 22:38:18 +0100 |
commit | 39de52104dd92bc0548a20201350111dc9317df9 (patch) | |
tree | 610c60dac072dc641be26dc912926b8877363846 /drivers/input/serio/hil_mlc.c | |
parent | Input: add support for keyboards on ST SPEAr platform (diff) | |
download | linux-39de52104dd92bc0548a20201350111dc9317df9.tar.xz linux-39de52104dd92bc0548a20201350111dc9317df9.zip |
Input: serio HIL MLC - don't deref null, don't leak and return proper error
While reviewing various users of kernel memory allocation functions I came
across drivers/input/serio/hil_mlc.c::hil_mlc_register() and noticed that:
- it calls kzalloc() but fails to check for a NULL return before use.
- it makes several allocations and if one fails it doesn't free the
previous ones.
- It doesn't return -ENOMEM in the failed memory allocation case (it just
crashes).
This patch corrects all of the above and also reworks the only caller of
this function that I could find
(drivers/input/serio/hp_sdc_mlc.c::hp_sdc_mlc_out()) so that it now checks
the return value of hil_mlc_register() and properly propagates it on
failure and I also restructured the code to remove some labels and goto's
to make it, IMHO nicer to read.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Tested-by: Helge Deller <deller@gmx.de>
Acked-by: Helge Deller <deller@gmx.de>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/serio/hil_mlc.c')
-rw-r--r-- | drivers/input/serio/hil_mlc.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/input/serio/hil_mlc.c b/drivers/input/serio/hil_mlc.c index e5624d8f1709..bfd3865d886b 100644 --- a/drivers/input/serio/hil_mlc.c +++ b/drivers/input/serio/hil_mlc.c @@ -932,6 +932,11 @@ int hil_mlc_register(hil_mlc *mlc) hil_mlc_copy_di_scratch(mlc, i); mlc_serio = kzalloc(sizeof(*mlc_serio), GFP_KERNEL); mlc->serio[i] = mlc_serio; + if (!mlc->serio[i]) { + for (; i >= 0; i--) + kfree(mlc->serio[i]); + return -ENOMEM; + } snprintf(mlc_serio->name, sizeof(mlc_serio->name)-1, "HIL_SERIO%d", i); snprintf(mlc_serio->phys, sizeof(mlc_serio->phys)-1, "HIL%d", i); mlc_serio->id = hil_mlc_serio_id; |