When we are in bootloader mode, the input_dev is not valid, and neither is
the object table. Several paths may result in something trying to dereference
these. This patch addresses the following :
1) mxt_resume calls input_unregister_device on input_dev.
2) mxt_suspend/resume reads and writes from the object table.
Signed-off-by: Benson Leung <bleung@chromium.org>
BUG=chrome-os-partner:16507
TEST=First, get the touch device into a bad state by doing the following:
1. Modify chromeos/config/base.config and set CONFIG_TOUCHSCREEN_ATMEL_MXT=m
2. Build, boot this kernel, and make sure that the touch device works.
3. /opt/google/touch/firmware/chromeos-touch-firmwareupdate.sh \
-d atmel_mxt_ts -n maxtouch-ts.fw -f
4. Before it can finish, CTRL-C to interrupt the firmware update.
This will ensure that the touch device is stuck in bootloader mode.
Now, test that mxt_remove is not vulnerable:
1. rmmod atmel_mxt_ts
2. check that the system does not reboot.
3. modprobe chromeos_mxt_ts
Test that suspend/resume does is not vulnerable:
1. Close the lid to suspend the system.
2. Open the lid to suspend the system.
3. Check that the system did not reboot.
Change-Id: I83e517d21738cb75d0c2b0ab8bf16398044e52f3
Reviewed-on: https://gerrit.chromium.org/gerrit/39022
Reviewed-by: Yufeng Shen <miletus@chromium.org>
Commit-Ready: Benson Leung <bleung@chromium.org>
Tested-by: Benson Leung <bleung@chromium.org>
sysfs_unmerge_group(&client->dev.kobj, &mxt_power_attr_group);
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
free_irq(data->irq, data);
- input_unregister_device(data->input_dev);
+ if (data->input_dev)
+ input_unregister_device(data->input_dev);
kfree(data->object_table);
kfree(data->fw_file);
kfree(data->config_file);
u8 *power_config;
int ret;
+ if (mxt_in_bootloader(data))
+ return 0;
+
mutex_lock(&input_dev->mutex);
/* Save 3 bytes T7 Power config */
struct input_dev *input_dev = data->input_dev;
int ret;
+ if (mxt_in_bootloader(data))
+ return 0;
+
/* Process any pending message so that CHG line can be de-asserted */
ret = mxt_handle_messages(data, false);
if (ret)