From 65105b4689f521f5a2069c0bcde58874d1a3d8c4 Mon Sep 17 00:00:00 2001 From: Benson Leung Date: Fri, 30 Nov 2012 15:26:49 -0800 Subject: [PATCH] CHROMIUM: Input: atmel_mxt_ts - Prevent null dereferences when in bootloader 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 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 Commit-Ready: Benson Leung Tested-by: Benson Leung --- drivers/input/touchscreen/atmel_mxt_ts.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 2412c48fb0dac..a0a563ed7978e 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -2700,7 +2700,8 @@ static int __devexit mxt_remove(struct i2c_client *client) 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); @@ -2764,6 +2765,9 @@ static int mxt_suspend(struct device *dev) u8 *power_config; int ret; + if (mxt_in_bootloader(data)) + return 0; + mutex_lock(&input_dev->mutex); /* Save 3 bytes T7 Power config */ @@ -2820,6 +2824,9 @@ static int mxt_resume(struct device *dev) 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) -- 2.39.5