]> xenbits.xensource.com Git - people/aperard/linux-chromebook.git/commitdiff
CHROMIUM: Input: atmel_mxt_ts - Prevent null dereferences when in bootloader
authorBenson Leung <bleung@chromium.org>
Fri, 30 Nov 2012 23:26:49 +0000 (15:26 -0800)
committerGerrit <chrome-bot@google.com>
Sat, 1 Dec 2012 22:45:31 +0000 (14:45 -0800)
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>
drivers/input/touchscreen/atmel_mxt_ts.c

index 2412c48fb0dacb5592cbdf2e2588feae5852757c..a0a563ed7978e0bae57a6252fc022ba044485d61 100644 (file)
@@ -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)