Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad3e14d7 authored by Jiri Kosina's avatar Jiri Kosina
Browse files

HID: logitech: perform bounds checking on device_id early enough



device_index is a char type and the size of paired_dj_deivces is 7
elements, therefore proper bounds checking has to be applied to
device_index before it is used.

We are currently performing the bounds checking in
logi_dj_recv_add_djhid_device(), which is too late, as malicious device
could send REPORT_TYPE_NOTIF_DEVICE_UNPAIRED early enough and trigger the
problem in one of the report forwarding functions called from
logi_dj_raw_event().

Fix this by performing the check at the earliest possible ocasion in
logi_dj_raw_event().

Cc: stable@vger.kernel.org
Reported-by: default avatarBen Hawkes <hawkes@google.com>
Reviewed-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 51217e69
Loading
Loading
Loading
Loading
+6 −7
Original line number Original line Diff line number Diff line
@@ -238,13 +238,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
		return;
		return;
	}
	}


	if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
	    (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
		dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n",
			__func__, dj_report->device_index);
		return;
	}

	if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
	if (djrcv_dev->paired_dj_devices[dj_report->device_index]) {
		/* The device is already known. No need to reallocate it. */
		/* The device is already known. No need to reallocate it. */
		dbg_hid("%s: device is already known\n", __func__);
		dbg_hid("%s: device is already known\n", __func__);
@@ -690,6 +683,12 @@ static int logi_dj_raw_event(struct hid_device *hdev,
	 * device (via hid_input_report() ) and return 1 so hid-core does not do
	 * device (via hid_input_report() ) and return 1 so hid-core does not do
	 * anything else with it.
	 * anything else with it.
	 */
	 */
	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",
				__func__, dj_report->device_index);
		return false;
	}


	spin_lock_irqsave(&djrcv_dev->lock, flags);
	spin_lock_irqsave(&djrcv_dev->lock, flags);
	if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
	if (dj_report->report_id == REPORT_ID_DJ_SHORT) {