diff options
author | Dan Carpenter <error27@gmail.com> | 2010-12-22 16:07:33 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-01-20 15:01:23 -0500 |
commit | f32b8453e5a5587ae112ba478ae0bbad74e83d22 (patch) | |
tree | 068439c3b12599a5ad9ec0ab08db88683ea0d0ad /drivers/staging/ste_rmi4 | |
parent | 64911e4b133ff633563d6dd2b021fa1ca0608992 (diff) |
Staging: ste_rmi4: use after input_unregister_device()
The original code called input_free_device(rmi4_data->input_dev) after
input_unregister_device(rmi4_data->input_dev) and that's a double free.
This is described in the comments to input_unregister_device().
The normal way to handle this is to make input_register_device() the
last function in the probe which can fail. That way you can avoid the
call to input_unregister_device() entirely.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/ste_rmi4')
-rw-r--r-- | drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index e8f047e86a3..80183a7e662 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | |||
@@ -986,12 +986,6 @@ static int __devinit synaptics_rmi4_probe | |||
986 | input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0, | 986 | input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0, |
987 | MAX_TOUCH_MAJOR, 0, 0); | 987 | MAX_TOUCH_MAJOR, 0, 0); |
988 | 988 | ||
989 | retval = input_register_device(rmi4_data->input_dev); | ||
990 | if (retval) { | ||
991 | dev_err(&client->dev, "%s:input register failed\n", __func__); | ||
992 | goto err_input_register; | ||
993 | } | ||
994 | |||
995 | /* Clear interrupts */ | 989 | /* Clear interrupts */ |
996 | synaptics_rmi4_i2c_block_read(rmi4_data, | 990 | synaptics_rmi4_i2c_block_read(rmi4_data, |
997 | rmi4_data->fn01_data_base_addr + 1, intr_status, | 991 | rmi4_data->fn01_data_base_addr + 1, intr_status, |
@@ -1003,15 +997,20 @@ static int __devinit synaptics_rmi4_probe | |||
1003 | if (retval) { | 997 | if (retval) { |
1004 | dev_err(&client->dev, "%s:Unable to get attn irq %d\n", | 998 | dev_err(&client->dev, "%s:Unable to get attn irq %d\n", |
1005 | __func__, platformdata->irq_number); | 999 | __func__, platformdata->irq_number); |
1006 | goto err_request_irq; | 1000 | goto err_unset_clientdata; |
1001 | } | ||
1002 | |||
1003 | retval = input_register_device(rmi4_data->input_dev); | ||
1004 | if (retval) { | ||
1005 | dev_err(&client->dev, "%s:input register failed\n", __func__); | ||
1006 | goto err_free_irq; | ||
1007 | } | 1007 | } |
1008 | 1008 | ||
1009 | return retval; | 1009 | return retval; |
1010 | 1010 | ||
1011 | err_request_irq: | 1011 | err_free_irq: |
1012 | free_irq(platformdata->irq_number, rmi4_data); | 1012 | free_irq(platformdata->irq_number, rmi4_data); |
1013 | input_unregister_device(rmi4_data->input_dev); | 1013 | err_unset_clientdata: |
1014 | err_input_register: | ||
1015 | i2c_set_clientdata(client, NULL); | 1014 | i2c_set_clientdata(client, NULL); |
1016 | err_query_dev: | 1015 | err_query_dev: |
1017 | if (platformdata->regulator_en) { | 1016 | if (platformdata->regulator_en) { |