diff options
author | Bruno Prémont <bonbons@linux-vserver.org> | 2013-08-31 08:07:48 -0400 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2013-09-02 07:36:50 -0400 |
commit | 1cde501bb4655e98fb832194beb88ac73be5a05d (patch) | |
tree | 86cc70fe2cc7c5e4fa875a5ada657a3825056428 /drivers/hid/hid-picolcd_fb.c | |
parent | 9e0bf92c223dabe0789714f8f85f6e26f8f9cda4 (diff) |
HID: picolcd: Prevent NULL pointer dereference on _remove()
When picolcd is switched into bootloader mode (for FW flashing) make
sure not to try to dereference NULL-pointers of feature-devices during
unplug/unbind.
This fixes following BUG:
BUG: unable to handle kernel NULL pointer dereference at 00000298
IP: [<f811f56b>] picolcd_exit_framebuffer+0x1b/0x80 [hid_picolcd]
*pde = 00000000
Oops: 0000 [#1]
Modules linked in: hid_picolcd syscopyarea sysfillrect sysimgblt fb_sys_fops
CPU: 0 PID: 15 Comm: khubd Not tainted 3.11.0-rc7-00002-g50d62d4 #2
EIP: 0060:[<f811f56b>] EFLAGS: 00010292 CPU: 0
EIP is at picolcd_exit_framebuffer+0x1b/0x80 [hid_picolcd]
Call Trace:
[<f811d1ab>] picolcd_remove+0xcb/0x120 [hid_picolcd]
[<c1469b09>] hid_device_remove+0x59/0xc0
[<c13464ca>] __device_release_driver+0x5a/0xb0
[<c134653f>] device_release_driver+0x1f/0x30
[<c134603d>] bus_remove_device+0x9d/0xd0
[<c13439a5>] device_del+0xd5/0x150
[<c14696a4>] hid_destroy_device+0x24/0x60
[<c1474cbb>] usbhid_disconnect+0x1b/0x40
...
Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org>
Cc: stable@kernel.org
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/hid-picolcd_fb.c')
-rw-r--r-- | drivers/hid/hid-picolcd_fb.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/drivers/hid/hid-picolcd_fb.c b/drivers/hid/hid-picolcd_fb.c index 591f6b22aa94..c930ab8554ea 100644 --- a/drivers/hid/hid-picolcd_fb.c +++ b/drivers/hid/hid-picolcd_fb.c | |||
@@ -593,10 +593,14 @@ err_nomem: | |||
593 | void picolcd_exit_framebuffer(struct picolcd_data *data) | 593 | void picolcd_exit_framebuffer(struct picolcd_data *data) |
594 | { | 594 | { |
595 | struct fb_info *info = data->fb_info; | 595 | struct fb_info *info = data->fb_info; |
596 | struct picolcd_fb_data *fbdata = info->par; | 596 | struct picolcd_fb_data *fbdata; |
597 | unsigned long flags; | 597 | unsigned long flags; |
598 | 598 | ||
599 | if (!info) | ||
600 | return; | ||
601 | |||
599 | device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); | 602 | device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); |
603 | fbdata = info->par; | ||
600 | 604 | ||
601 | /* disconnect framebuffer from HID dev */ | 605 | /* disconnect framebuffer from HID dev */ |
602 | spin_lock_irqsave(&fbdata->lock, flags); | 606 | spin_lock_irqsave(&fbdata->lock, flags); |