Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jikos/hid

Pull HID fixes from Jiri Kosina:

 - fixes for potential memory corruption problems in magicmouse and
   picolcd drivers (the HW would have to be manufactured to be
   deliberately evil to trigger those) which were found by Steven
   Vittitoe

 - fix for false error message appearing in dmesg from logitech-dj
   driver, from Benjamin Tissoires

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: picolcd: sanity check report size in raw_event() callback
  HID: magicmouse: sanity check report size in raw_event() callback
  HID: logitech-dj: prevent false errors to be shown
  • Loading branch information
torvalds committed Aug 27, 2014
2 parents 1fb00cb + 844817e commit ff0c57a
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 18 deletions.
43 changes: 25 additions & 18 deletions drivers/hid/hid-logitech-dj.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,6 @@ static int logi_dj_raw_event(struct hid_device *hdev,
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
struct dj_report *dj_report = (struct dj_report *) data;
unsigned long flags;
bool report_processed = false;

dbg_hid("%s, size:%d\n", __func__, size);

Expand All @@ -683,34 +682,42 @@ static int logi_dj_raw_event(struct hid_device *hdev,
* device (via hid_input_report() ) and return 1 so hid-core does not do
* anything else with it.
*/

/* case 1) */
if (data[0] != REPORT_ID_DJ_SHORT)
return false;

if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
(dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
dev_err(&hdev->dev, "%s: invalid device index:%d\n",
/*
* Device index is wrong, bail out.
* This driver can ignore safely the receiver notifications,
* so ignore those reports too.
*/
if (dj_report->device_index != DJ_RECEIVER_INDEX)
dev_err(&hdev->dev, "%s: invalid device index:%d\n",
__func__, dj_report->device_index);
return false;
}

spin_lock_irqsave(&djrcv_dev->lock, flags);
if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
switch (dj_report->report_type) {
case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
logi_dj_recv_queue_notification(djrcv_dev, dj_report);
break;
case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
STATUS_LINKLOSS) {
logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
}
break;
default:
logi_dj_recv_forward_report(djrcv_dev, dj_report);
switch (dj_report->report_type) {
case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
logi_dj_recv_queue_notification(djrcv_dev, dj_report);
break;
case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
STATUS_LINKLOSS) {
logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
}
report_processed = true;
break;
default:
logi_dj_recv_forward_report(djrcv_dev, dj_report);
}
spin_unlock_irqrestore(&djrcv_dev->lock, flags);

return report_processed;
return true;
}

static int logi_dj_probe(struct hid_device *hdev,
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/hid-logitech-dj.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#define DJ_MAX_PAIRED_DEVICES 6
#define DJ_MAX_NUMBER_NOTIFICATIONS 8
#define DJ_RECEIVER_INDEX 0
#define DJ_DEVICE_INDEX_MIN 1
#define DJ_DEVICE_INDEX_MAX 6

Expand Down
10 changes: 10 additions & 0 deletions drivers/hid/hid-magicmouse.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ static int magicmouse_raw_event(struct hid_device *hdev,
if (size < 4 || ((size - 4) % 9) != 0)
return 0;
npoints = (size - 4) / 9;
if (npoints > 15) {
hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
size);
return 0;
}
msc->ntouches = 0;
for (ii = 0; ii < npoints; ii++)
magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
Expand All @@ -307,6 +312,11 @@ static int magicmouse_raw_event(struct hid_device *hdev,
if (size < 6 || ((size - 6) % 8) != 0)
return 0;
npoints = (size - 6) / 8;
if (npoints > 15) {
hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n",
size);
return 0;
}
msc->ntouches = 0;
for (ii = 0; ii < npoints; ii++)
magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
Expand Down
6 changes: 6 additions & 0 deletions drivers/hid/hid-picolcd_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,12 @@ static int picolcd_raw_event(struct hid_device *hdev,
if (!data)
return 1;

if (size > 64) {
hid_warn(hdev, "invalid size value (%d) for picolcd raw event\n",
size);
return 0;
}

if (report->id == REPORT_KEY_STATE) {
if (data->input_keys)
ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);
Expand Down

0 comments on commit ff0c57a

Please sign in to comment.