Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

HID: logitech-dj: prevent false errors to be shown

Commit "HID: logitech: perform bounds checking on device_id early
enough" unfortunately leaks some errors to dmesg which are not real
ones:
- if the report is not a DJ one, then there is not point in checking
the device_id
- the receiver (index 0) can also receive some notifications which
can be safely ignored given the current implementation

Move out the test regarding the report_id and also discards
printing errors when the receiver got notified.

Fixes: ad3e14d7c5268c2e24477c6ef54bbdf88add5d36

Cc: stable@vger.kernel.org
Reported-and-tested-by: Markus Trippelsdorf <markus@trippelsdorf.de>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

authored by

Benjamin Tissoires and committed by
Jiri Kosina
5abfe85c 4ab25786

+26 -18
+25 -18
drivers/hid/hid-logitech-dj.c
··· 656 656 struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); 657 657 struct dj_report *dj_report = (struct dj_report *) data; 658 658 unsigned long flags; 659 - bool report_processed = false; 660 659 661 660 dbg_hid("%s, size:%d\n", __func__, size); 662 661 ··· 682 683 * device (via hid_input_report() ) and return 1 so hid-core does not do 683 684 * anything else with it. 684 685 */ 686 + 687 + /* case 1) */ 688 + if (data[0] != REPORT_ID_DJ_SHORT) 689 + return false; 690 + 685 691 if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || 686 692 (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { 687 - dev_err(&hdev->dev, "%s: invalid device index:%d\n", 693 + /* 694 + * Device index is wrong, bail out. 695 + * This driver can ignore safely the receiver notifications, 696 + * so ignore those reports too. 697 + */ 698 + if (dj_report->device_index != DJ_RECEIVER_INDEX) 699 + dev_err(&hdev->dev, "%s: invalid device index:%d\n", 688 700 __func__, dj_report->device_index); 689 701 return false; 690 702 } 691 703 692 704 spin_lock_irqsave(&djrcv_dev->lock, flags); 693 - if (dj_report->report_id == REPORT_ID_DJ_SHORT) { 694 - switch (dj_report->report_type) { 695 - case REPORT_TYPE_NOTIF_DEVICE_PAIRED: 696 - case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: 697 - logi_dj_recv_queue_notification(djrcv_dev, dj_report); 698 - break; 699 - case REPORT_TYPE_NOTIF_CONNECTION_STATUS: 700 - if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] == 701 - STATUS_LINKLOSS) { 702 - logi_dj_recv_forward_null_report(djrcv_dev, dj_report); 703 - } 704 - break; 705 - default: 706 - logi_dj_recv_forward_report(djrcv_dev, dj_report); 705 + switch (dj_report->report_type) { 706 + case REPORT_TYPE_NOTIF_DEVICE_PAIRED: 707 + case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: 708 + logi_dj_recv_queue_notification(djrcv_dev, dj_report); 709 + break; 710 + case REPORT_TYPE_NOTIF_CONNECTION_STATUS: 711 + if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] == 712 + STATUS_LINKLOSS) { 713 + logi_dj_recv_forward_null_report(djrcv_dev, dj_report); 707 714 } 708 - report_processed = true; 715 + break; 716 + default: 717 + logi_dj_recv_forward_report(djrcv_dev, dj_report); 709 718 } 710 719 spin_unlock_irqrestore(&djrcv_dev->lock, flags); 711 720 712 - return report_processed; 721 + return true; 713 722 } 714 723 715 724 static int logi_dj_probe(struct hid_device *hdev,
+1
drivers/hid/hid-logitech-dj.h
··· 27 27 28 28 #define DJ_MAX_PAIRED_DEVICES 6 29 29 #define DJ_MAX_NUMBER_NOTIFICATIONS 8 30 + #define DJ_RECEIVER_INDEX 0 30 31 #define DJ_DEVICE_INDEX_MIN 1 31 32 #define DJ_DEVICE_INDEX_MAX 6 32 33