]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
udev-builtin-usb_id: guard against overflow when reading descriptor data 11852/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 28 Feb 2019 10:57:51 +0000 (11:57 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 28 Feb 2019 10:57:51 +0000 (11:57 +0100)
CID#996458. Coverity warns that we trust desc->bLength as read in
the input data to adjust our position in the buffer. This value could
be anything, leading to overflow. It's unlikely that the kernel feeds
us invalid data, but let's me more careful.

If any error is encountered, more logs are given.

src/udev/udev-builtin-usb_id.c

index 489b232814f4f7f123131dffb33b02ae77cab0d4..7bdf6cfbb59613936cc3b9d60d5b2c245e992a89 100644 (file)
@@ -167,8 +167,10 @@ static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) {
                 return log_device_debug_errno(dev, errno, "Failed to open \"%s\": %m", filename);
 
         size = read(fd, buf, sizeof(buf));
-        if (size < 18 || (size_t) size >= sizeof(buf))
-                return -EIO;
+        if (size < 18)
+                return log_device_warning_errno(dev, SYNTHETIC_ERRNO(EIO),
+                                                "Short read from \"%s\"", filename);
+        assert((size_t) size <= sizeof buf);
 
         ifs_str[0] = '\0';
         while (pos + sizeof(struct usb_interface_descriptor) < (size_t) size &&
@@ -177,9 +179,12 @@ static int dev_if_packed_info(sd_device *dev, char *ifs_str, size_t len) {
                 struct usb_interface_descriptor *desc;
                 char if_str[8];
 
-                desc = (struct usb_interface_descriptor *) &buf[pos];
+                desc = (struct usb_interface_descriptor *) (buf + pos);
                 if (desc->bLength < 3)
                         break;
+                if (desc->bLength > size - sizeof(struct usb_interface_descriptor))
+                        return log_device_debug_errno(dev, SYNTHETIC_ERRNO(EIO),
+                                                      "Corrupt data read from \"%s\"", filename);
                 pos += desc->bLength;
 
                 if (desc->bDescriptorType != USB_DT_INTERFACE)