diff options
author | Stephen Warren <swarren@wwwdotorg.org> | 2014-09-10 13:01:10 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-09-10 13:27:31 -0400 |
commit | 58e4aeee39917c75da8e5dca0f1c42be8dc29f9e (patch) | |
tree | 1fa7d72e71f1abdb0cc563212ffe6767bf9dbdc5 /drivers/input | |
parent | 5715fc764f7753d464dbe094b5ef9cffa6e479a4 (diff) |
Input: atmel_mxt_ts - fix double free of input device
[Nick Dyer: reworked to move free of input device into separate function
and only call in paths that require it.]
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index d954b81243fe..aaacf8bfa61f 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -1379,11 +1379,16 @@ static int mxt_get_info(struct mxt_data *data) | |||
1379 | return 0; | 1379 | return 0; |
1380 | } | 1380 | } |
1381 | 1381 | ||
1382 | static void mxt_free_object_table(struct mxt_data *data) | 1382 | static void mxt_free_input_device(struct mxt_data *data) |
1383 | { | 1383 | { |
1384 | input_unregister_device(data->input_dev); | 1384 | if (data->input_dev) { |
1385 | data->input_dev = NULL; | 1385 | input_unregister_device(data->input_dev); |
1386 | data->input_dev = NULL; | ||
1387 | } | ||
1388 | } | ||
1386 | 1389 | ||
1390 | static void mxt_free_object_table(struct mxt_data *data) | ||
1391 | { | ||
1387 | kfree(data->object_table); | 1392 | kfree(data->object_table); |
1388 | data->object_table = NULL; | 1393 | data->object_table = NULL; |
1389 | kfree(data->msg_buf); | 1394 | kfree(data->msg_buf); |
@@ -1962,11 +1967,13 @@ static int mxt_load_fw(struct device *dev, const char *fn) | |||
1962 | ret = mxt_lookup_bootloader_address(data, 0); | 1967 | ret = mxt_lookup_bootloader_address(data, 0); |
1963 | if (ret) | 1968 | if (ret) |
1964 | goto release_firmware; | 1969 | goto release_firmware; |
1970 | |||
1971 | mxt_free_input_device(data); | ||
1972 | mxt_free_object_table(data); | ||
1965 | } else { | 1973 | } else { |
1966 | enable_irq(data->irq); | 1974 | enable_irq(data->irq); |
1967 | } | 1975 | } |
1968 | 1976 | ||
1969 | mxt_free_object_table(data); | ||
1970 | reinit_completion(&data->bl_completion); | 1977 | reinit_completion(&data->bl_completion); |
1971 | 1978 | ||
1972 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); | 1979 | ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false); |
@@ -2215,6 +2222,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
2215 | return 0; | 2222 | return 0; |
2216 | 2223 | ||
2217 | err_free_object: | 2224 | err_free_object: |
2225 | mxt_free_input_device(data); | ||
2218 | mxt_free_object_table(data); | 2226 | mxt_free_object_table(data); |
2219 | err_free_irq: | 2227 | err_free_irq: |
2220 | free_irq(client->irq, data); | 2228 | free_irq(client->irq, data); |
@@ -2229,7 +2237,7 @@ static int mxt_remove(struct i2c_client *client) | |||
2229 | 2237 | ||
2230 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); | 2238 | sysfs_remove_group(&client->dev.kobj, &mxt_attr_group); |
2231 | free_irq(data->irq, data); | 2239 | free_irq(data->irq, data); |
2232 | input_unregister_device(data->input_dev); | 2240 | mxt_free_input_device(data); |
2233 | mxt_free_object_table(data); | 2241 | mxt_free_object_table(data); |
2234 | kfree(data); | 2242 | kfree(data); |
2235 | 2243 | ||