Commit 895452ae authored by Thomas Zimmermann's avatar Thomas Zimmermann
Browse files

drm/udl: Handle errors from usb_get_descriptor()



Reading the vendor descriptor from the udl device can fail with
an error, which the current code fails to capture. Store the return
value in an integer and test for the error. Abort parsing on errors
or treat the value as length on success.

Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarPatrik Jakobsson <patrik.r.jakobsson@gmail.com>
Link: https://lore.kernel.org/r/20250410105948.25463-6-tzimmermann@suse.de
parent 89323678
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -31,28 +31,32 @@ static int udl_parse_vendor_descriptor(struct udl_device *udl)
	char *desc;
	char *buf;
	char *desc_end;

	u8 total_len = 0;
	int ret;
	unsigned int len;

	buf = kzalloc(MAX_VENDOR_DESCRIPTOR_SIZE, GFP_KERNEL);
	if (!buf)
		return false;
	desc = buf;

	total_len = usb_get_descriptor(udev, 0x5f, /* vendor specific */
	ret = usb_get_descriptor(udev, 0x5f, /* vendor specific */
				 0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
	if (total_len > 5) {
		DRM_INFO("vendor descriptor length:%x data:%11ph\n",
			total_len, desc);
	if (ret < 0)
		goto unrecognized;
	len = ret;

	if (len > 5) {
		DRM_INFO("vendor descriptor length: %u data:%11ph\n",
			 len, desc);

		if ((desc[0] != total_len) || /* descriptor length */
		if ((desc[0] != len) ||    /* descriptor length */
		    (desc[1] != 0x5f) ||   /* vendor descriptor type */
		    (desc[2] != 0x01) ||   /* version (2 bytes) */
		    (desc[3] != 0x00) ||
		    (desc[4] != total_len - 2)) /* length after type */
		    (desc[4] != len - 2))  /* length after type */
			goto unrecognized;

		desc_end = desc + total_len;
		desc_end = desc + len;
		desc += 5; /* the fixed header we've already parsed */

		while (desc < desc_end) {