drm/udl: Handle errors from usb_get_descriptor()
authorThomas Zimmermann <tzimmermann@suse.de>
Thu, 10 Apr 2025 10:59:02 +0000 (12:59 +0200)
committerThomas Zimmermann <tzimmermann@suse.de>
Mon, 14 Apr 2025 08:19:19 +0000 (10:19 +0200)
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: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Link: https://lore.kernel.org/r/20250410105948.25463-6-tzimmermann@suse.de
drivers/gpu/drm/udl/udl_main.c

index 47fb6c34bfde3afa593f9f033a3cf2d63a1a55de..4291ddb7158c4def7075c68eea9b8c1f0b9c0d1d 100644 (file)
@@ -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 */
-                                   0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
-       if (total_len > 5) {
-               DRM_INFO("vendor descriptor length:%x data:%11ph\n",
-                       total_len, desc);
+       ret = usb_get_descriptor(udev, 0x5f, /* vendor specific */
+                                0, desc, MAX_VENDOR_DESCRIPTOR_SIZE);
+       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) {