Skip to content

Commit ff0c57a

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/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
2 parents 1fb00cb + 844817e commit ff0c57a

File tree

4 files changed

+42
-18
lines changed

4 files changed

+42
-18
lines changed

drivers/hid/hid-logitech-dj.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -656,7 +656,6 @@ static int logi_dj_raw_event(struct hid_device *hdev,
656656
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
657657
struct dj_report *dj_report = (struct dj_report *) data;
658658
unsigned long flags;
659-
bool report_processed = false;
660659

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

@@ -683,34 +682,42 @@ static int logi_dj_raw_event(struct hid_device *hdev,
683682
* device (via hid_input_report() ) and return 1 so hid-core does not do
684683
* anything else with it.
685684
*/
685+
686+
/* case 1) */
687+
if (data[0] != REPORT_ID_DJ_SHORT)
688+
return false;
689+
686690
if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
687691
(dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
688-
dev_err(&hdev->dev, "%s: invalid device index:%d\n",
692+
/*
693+
* Device index is wrong, bail out.
694+
* This driver can ignore safely the receiver notifications,
695+
* so ignore those reports too.
696+
*/
697+
if (dj_report->device_index != DJ_RECEIVER_INDEX)
698+
dev_err(&hdev->dev, "%s: invalid device index:%d\n",
689699
__func__, dj_report->device_index);
690700
return false;
691701
}
692702

693703
spin_lock_irqsave(&djrcv_dev->lock, flags);
694-
if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
695-
switch (dj_report->report_type) {
696-
case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
697-
case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
698-
logi_dj_recv_queue_notification(djrcv_dev, dj_report);
699-
break;
700-
case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
701-
if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
702-
STATUS_LINKLOSS) {
703-
logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
704-
}
705-
break;
706-
default:
707-
logi_dj_recv_forward_report(djrcv_dev, dj_report);
704+
switch (dj_report->report_type) {
705+
case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
706+
case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
707+
logi_dj_recv_queue_notification(djrcv_dev, dj_report);
708+
break;
709+
case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
710+
if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
711+
STATUS_LINKLOSS) {
712+
logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
708713
}
709-
report_processed = true;
714+
break;
715+
default:
716+
logi_dj_recv_forward_report(djrcv_dev, dj_report);
710717
}
711718
spin_unlock_irqrestore(&djrcv_dev->lock, flags);
712719

713-
return report_processed;
720+
return true;
714721
}
715722

716723
static int logi_dj_probe(struct hid_device *hdev,

drivers/hid/hid-logitech-dj.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#define DJ_MAX_PAIRED_DEVICES 6
2929
#define DJ_MAX_NUMBER_NOTIFICATIONS 8
30+
#define DJ_RECEIVER_INDEX 0
3031
#define DJ_DEVICE_INDEX_MIN 1
3132
#define DJ_DEVICE_INDEX_MAX 6
3233

drivers/hid/hid-magicmouse.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,11 @@ static int magicmouse_raw_event(struct hid_device *hdev,
290290
if (size < 4 || ((size - 4) % 9) != 0)
291291
return 0;
292292
npoints = (size - 4) / 9;
293+
if (npoints > 15) {
294+
hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
295+
size);
296+
return 0;
297+
}
293298
msc->ntouches = 0;
294299
for (ii = 0; ii < npoints; ii++)
295300
magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
@@ -307,6 +312,11 @@ static int magicmouse_raw_event(struct hid_device *hdev,
307312
if (size < 6 || ((size - 6) % 8) != 0)
308313
return 0;
309314
npoints = (size - 6) / 8;
315+
if (npoints > 15) {
316+
hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n",
317+
size);
318+
return 0;
319+
}
310320
msc->ntouches = 0;
311321
for (ii = 0; ii < npoints; ii++)
312322
magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);

drivers/hid/hid-picolcd_core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,12 @@ static int picolcd_raw_event(struct hid_device *hdev,
350350
if (!data)
351351
return 1;
352352

353+
if (size > 64) {
354+
hid_warn(hdev, "invalid size value (%d) for picolcd raw event\n",
355+
size);
356+
return 0;
357+
}
358+
353359
if (report->id == REPORT_KEY_STATE) {
354360
if (data->input_keys)
355361
ret = picolcd_raw_keypad(data, report, raw_data+1, size-1);

0 commit comments

Comments
 (0)