summaryrefslogtreecommitdiff
path: root/src/udev/udev-builtin-usb_id.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-02-28 11:57:51 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-02-28 11:57:51 +0100
commit760034bebed2c4cfc8a6b114a207f817b2e61db3 (patch)
tree958385f0ba50107855213a8a352e87cd080eae76 /src/udev/udev-builtin-usb_id.c
parent8bdca77c407d100b8c81e2108aba47a8810ead88 (diff)
downloadsystemd-760034bebed2c4cfc8a6b114a207f817b2e61db3.tar.gz
udev-builtin-usb_id: guard against overflow when reading descriptor data
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.
Diffstat (limited to 'src/udev/udev-builtin-usb_id.c')
-rw-r--r--src/udev/udev-builtin-usb_id.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index 489b232814..7bdf6cfbb5 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -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)