Commit 1cde501b authored by Bruno Prémont's avatar Bruno Prémont Committed by Jiri Kosina

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: default avatarBruno Prémont <bonbons@linux-vserver.org>
Cc: stable@kernel.org
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 9e0bf92c
...@@ -145,6 +145,7 @@ void picolcd_exit_cir(struct picolcd_data *data) ...@@ -145,6 +145,7 @@ void picolcd_exit_cir(struct picolcd_data *data)
struct rc_dev *rdev = data->rc_dev; struct rc_dev *rdev = data->rc_dev;
data->rc_dev = NULL; data->rc_dev = NULL;
rc_unregister_device(rdev); if (rdev)
rc_unregister_device(rdev);
} }
...@@ -593,10 +593,14 @@ int picolcd_init_framebuffer(struct picolcd_data *data) ...@@ -593,10 +593,14 @@ int picolcd_init_framebuffer(struct picolcd_data *data)
void picolcd_exit_framebuffer(struct picolcd_data *data) void picolcd_exit_framebuffer(struct picolcd_data *data)
{ {
struct fb_info *info = data->fb_info; struct fb_info *info = data->fb_info;
struct picolcd_fb_data *fbdata = info->par; struct picolcd_fb_data *fbdata;
unsigned long flags; unsigned long flags;
if (!info)
return;
device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate); device_remove_file(&data->hdev->dev, &dev_attr_fb_update_rate);
fbdata = info->par;
/* disconnect framebuffer from HID dev */ /* disconnect framebuffer from HID dev */
spin_lock_irqsave(&fbdata->lock, flags); spin_lock_irqsave(&fbdata->lock, flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment