Skip to content

Commit 1a44fb3

Browse files
hayesorzdavem330
authored andcommitted
r8152: check the informaton of the device
Verify some fields of the USB descriptor to make sure the driver could be used by the device. Besides, remove the check of endpoint number in rtl8152_probe(). usb_find_common_endpoints() includes it. BugLink: https://syzkaller.appspot.com/bug?id=912c9c373656996801b4de61f1e3cb326fe940aa Reported-by: [email protected] Fixes: c219894 ("r8152: search the configuration of vendor mode") Signed-off-by: Hayes Wang <[email protected]> Reviewed-by: Johan Hovold <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 9b76ead commit 1a44fb3

File tree

1 file changed

+37
-5
lines changed

1 file changed

+37
-5
lines changed

drivers/net/usb/r8152.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8107,6 +8107,37 @@ static void r8156b_init(struct r8152 *tp)
81078107
tp->coalesce = 15000; /* 15 us */
81088108
}
81098109

8110+
static bool rtl_check_vendor_ok(struct usb_interface *intf)
8111+
{
8112+
struct usb_host_interface *alt = intf->cur_altsetting;
8113+
struct usb_endpoint_descriptor *in, *out, *intr;
8114+
8115+
if (usb_find_common_endpoints(alt, &in, &out, &intr, NULL) < 0) {
8116+
dev_err(&intf->dev, "Expected endpoints are not found\n");
8117+
return false;
8118+
}
8119+
8120+
/* Check Rx endpoint address */
8121+
if (usb_endpoint_num(in) != 1) {
8122+
dev_err(&intf->dev, "Invalid Rx endpoint address\n");
8123+
return false;
8124+
}
8125+
8126+
/* Check Tx endpoint address */
8127+
if (usb_endpoint_num(out) != 2) {
8128+
dev_err(&intf->dev, "Invalid Tx endpoint address\n");
8129+
return false;
8130+
}
8131+
8132+
/* Check interrupt endpoint address */
8133+
if (usb_endpoint_num(intr) != 3) {
8134+
dev_err(&intf->dev, "Invalid interrupt endpoint address\n");
8135+
return false;
8136+
}
8137+
8138+
return true;
8139+
}
8140+
81108141
static bool rtl_vendor_mode(struct usb_interface *intf)
81118142
{
81128143
struct usb_host_interface *alt = intf->cur_altsetting;
@@ -8115,12 +8146,15 @@ static bool rtl_vendor_mode(struct usb_interface *intf)
81158146
int i, num_configs;
81168147

81178148
if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC)
8118-
return true;
8149+
return rtl_check_vendor_ok(intf);
81198150

81208151
/* The vendor mode is not always config #1, so to find it out. */
81218152
udev = interface_to_usbdev(intf);
81228153
c = udev->config;
81238154
num_configs = udev->descriptor.bNumConfigurations;
8155+
if (num_configs < 2)
8156+
return false;
8157+
81248158
for (i = 0; i < num_configs; (i++, c++)) {
81258159
struct usb_interface_descriptor *desc = NULL;
81268160

@@ -8135,7 +8169,8 @@ static bool rtl_vendor_mode(struct usb_interface *intf)
81358169
}
81368170
}
81378171

8138-
WARN_ON_ONCE(i == num_configs);
8172+
if (i == num_configs)
8173+
dev_err(&intf->dev, "Unexpected Device\n");
81398174

81408175
return false;
81418176
}
@@ -9381,9 +9416,6 @@ static int rtl8152_probe(struct usb_interface *intf,
93819416
if (!rtl_vendor_mode(intf))
93829417
return -ENODEV;
93839418

9384-
if (intf->cur_altsetting->desc.bNumEndpoints < 3)
9385-
return -ENODEV;
9386-
93879419
usb_reset_device(udev);
93889420
netdev = alloc_etherdev(sizeof(struct r8152));
93899421
if (!netdev) {

0 commit comments

Comments
 (0)