Commit a18404fc authored by Pietro Borrello's avatar Pietro Borrello Committed by Xiangwei Li
Browse files

HID: betop: check shape of output reports

stable inclusion
from stable-v4.19.272
commit 7317326f685824c7c29bd80841fd18041af6bb73
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBWVXF
CVE: CVE-2023-53015

Reference: https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7317326f685824c7c29bd80841fd18041af6bb73



--------------------------------

[ Upstream commit 3782c0d6 ]

betopff_init() only checks the total sum of the report counts for each
report field to be at least 4, but hid_betopff_play() expects 4 report
fields.
A device advertising an output report with one field and 4 report counts
would pass the check but crash the kernel with a NULL pointer dereference
in hid_betopff_play().

Fixes: 52cd7785 ("HID: betop: add drivers/hid/hid-betopff.c")
Signed-off-by: default avatarPietro Borrello <borrello@diag.uniroma1.it>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarXiangwei Li <liwei728@huawei.com>
parent 74c40b7b
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -63,7 +63,6 @@ static int betopff_init(struct hid_device *hid)
	struct list_head *report_list =
			&hid->report_enum[HID_OUTPUT_REPORT].report_list;
	struct input_dev *dev;
	int field_count = 0;
	int error;
	int i, j;

@@ -89,19 +88,21 @@ static int betopff_init(struct hid_device *hid)
	 * -----------------------------------------
	 * Do init them with default value.
	 */
	if (report->maxfield < 4) {
		hid_err(hid, "not enough fields in the report: %d\n",
				report->maxfield);
		return -ENODEV;
	}
	for (i = 0; i < report->maxfield; i++) {
		if (report->field[i]->report_count < 1) {
			hid_err(hid, "no values in the field\n");
			return -ENODEV;
		}
		for (j = 0; j < report->field[i]->report_count; j++) {
			report->field[i]->value[j] = 0x00;
			field_count++;
		}
	}

	if (field_count < 4) {
		hid_err(hid, "not enough fields in the report: %d\n",
				field_count);
		return -ENODEV;
	}

	betopff = kzalloc(sizeof(*betopff), GFP_KERNEL);
	if (!betopff)
		return -ENOMEM;