Skip to content

Commit ea060b3

Browse files
jhovolddavem330
authored andcommitted
net: lan78xx: replace bogus endpoint lookup
Drop the bogus endpoint-lookup helper which could end up accepting interfaces based on endpoints belonging to unrelated altsettings. Note that the returned bulk pipes and interrupt endpoint descriptor were never actually used. Instead the bulk-endpoint numbers are hardcoded to 1 and 2 (matching the specification), while the interrupt- endpoint descriptor was assumed to be the third descriptor created by USB core. Try to bring some order to this by dropping the bogus lookup helper and adding the missing endpoint sanity checks while keeping the interrupt- descriptor assumption for now. Signed-off-by: Johan Hovold <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 63634aa commit ea060b3

File tree

1 file changed

+30
-87
lines changed

1 file changed

+30
-87
lines changed

drivers/net/usb/lan78xx.c

Lines changed: 30 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -377,10 +377,6 @@ struct lan78xx_net {
377377
struct tasklet_struct bh;
378378
struct delayed_work wq;
379379

380-
struct usb_host_endpoint *ep_blkin;
381-
struct usb_host_endpoint *ep_blkout;
382-
struct usb_host_endpoint *ep_intr;
383-
384380
int msg_enable;
385381

386382
struct urb *urb_intr;
@@ -2860,78 +2856,12 @@ lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net)
28602856
return NETDEV_TX_OK;
28612857
}
28622858

2863-
static int
2864-
lan78xx_get_endpoints(struct lan78xx_net *dev, struct usb_interface *intf)
2865-
{
2866-
int tmp;
2867-
struct usb_host_interface *alt = NULL;
2868-
struct usb_host_endpoint *in = NULL, *out = NULL;
2869-
struct usb_host_endpoint *status = NULL;
2870-
2871-
for (tmp = 0; tmp < intf->num_altsetting; tmp++) {
2872-
unsigned ep;
2873-
2874-
in = NULL;
2875-
out = NULL;
2876-
status = NULL;
2877-
alt = intf->altsetting + tmp;
2878-
2879-
for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
2880-
struct usb_host_endpoint *e;
2881-
int intr = 0;
2882-
2883-
e = alt->endpoint + ep;
2884-
switch (e->desc.bmAttributes) {
2885-
case USB_ENDPOINT_XFER_INT:
2886-
if (!usb_endpoint_dir_in(&e->desc))
2887-
continue;
2888-
intr = 1;
2889-
/* FALLTHROUGH */
2890-
case USB_ENDPOINT_XFER_BULK:
2891-
break;
2892-
default:
2893-
continue;
2894-
}
2895-
if (usb_endpoint_dir_in(&e->desc)) {
2896-
if (!intr && !in)
2897-
in = e;
2898-
else if (intr && !status)
2899-
status = e;
2900-
} else {
2901-
if (!out)
2902-
out = e;
2903-
}
2904-
}
2905-
if (in && out)
2906-
break;
2907-
}
2908-
if (!alt || !in || !out)
2909-
return -EINVAL;
2910-
2911-
dev->pipe_in = usb_rcvbulkpipe(dev->udev,
2912-
in->desc.bEndpointAddress &
2913-
USB_ENDPOINT_NUMBER_MASK);
2914-
dev->pipe_out = usb_sndbulkpipe(dev->udev,
2915-
out->desc.bEndpointAddress &
2916-
USB_ENDPOINT_NUMBER_MASK);
2917-
dev->ep_intr = status;
2918-
2919-
return 0;
2920-
}
2921-
29222859
static int lan78xx_bind(struct lan78xx_net *dev, struct usb_interface *intf)
29232860
{
29242861
struct lan78xx_priv *pdata = NULL;
29252862
int ret;
29262863
int i;
29272864

2928-
ret = lan78xx_get_endpoints(dev, intf);
2929-
if (ret) {
2930-
netdev_warn(dev->net, "lan78xx_get_endpoints failed: %d\n",
2931-
ret);
2932-
return ret;
2933-
}
2934-
29352865
dev->data[0] = (unsigned long)kzalloc(sizeof(*pdata), GFP_KERNEL);
29362866

29372867
pdata = (struct lan78xx_priv *)(dev->data[0]);
@@ -3700,6 +3630,7 @@ static void lan78xx_stat_monitor(struct timer_list *t)
37003630
static int lan78xx_probe(struct usb_interface *intf,
37013631
const struct usb_device_id *id)
37023632
{
3633+
struct usb_host_endpoint *ep_blkin, *ep_blkout, *ep_intr;
37033634
struct lan78xx_net *dev;
37043635
struct net_device *netdev;
37053636
struct usb_device *udev;
@@ -3748,6 +3679,34 @@ static int lan78xx_probe(struct usb_interface *intf,
37483679

37493680
mutex_init(&dev->stats.access_lock);
37503681

3682+
if (intf->cur_altsetting->desc.bNumEndpoints < 3) {
3683+
ret = -ENODEV;
3684+
goto out2;
3685+
}
3686+
3687+
dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE);
3688+
ep_blkin = usb_pipe_endpoint(udev, dev->pipe_in);
3689+
if (!ep_blkin || !usb_endpoint_is_bulk_in(&ep_blkin->desc)) {
3690+
ret = -ENODEV;
3691+
goto out2;
3692+
}
3693+
3694+
dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE);
3695+
ep_blkout = usb_pipe_endpoint(udev, dev->pipe_out);
3696+
if (!ep_blkout || !usb_endpoint_is_bulk_out(&ep_blkout->desc)) {
3697+
ret = -ENODEV;
3698+
goto out2;
3699+
}
3700+
3701+
ep_intr = &intf->cur_altsetting->endpoint[2];
3702+
if (!usb_endpoint_is_int_in(&ep_intr->desc)) {
3703+
ret = -ENODEV;
3704+
goto out2;
3705+
}
3706+
3707+
dev->pipe_intr = usb_rcvintpipe(dev->udev,
3708+
usb_endpoint_num(&ep_intr->desc));
3709+
37513710
ret = lan78xx_bind(dev, intf);
37523711
if (ret < 0)
37533712
goto out2;
@@ -3759,23 +3718,7 @@ static int lan78xx_probe(struct usb_interface *intf,
37593718
netdev->max_mtu = MAX_SINGLE_PACKET_SIZE;
37603719
netif_set_gso_max_size(netdev, MAX_SINGLE_PACKET_SIZE - MAX_HEADER);
37613720

3762-
if (intf->cur_altsetting->desc.bNumEndpoints < 3) {
3763-
ret = -ENODEV;
3764-
goto out3;
3765-
}
3766-
3767-
dev->ep_blkin = (intf->cur_altsetting)->endpoint + 0;
3768-
dev->ep_blkout = (intf->cur_altsetting)->endpoint + 1;
3769-
dev->ep_intr = (intf->cur_altsetting)->endpoint + 2;
3770-
3771-
dev->pipe_in = usb_rcvbulkpipe(udev, BULK_IN_PIPE);
3772-
dev->pipe_out = usb_sndbulkpipe(udev, BULK_OUT_PIPE);
3773-
3774-
dev->pipe_intr = usb_rcvintpipe(dev->udev,
3775-
dev->ep_intr->desc.bEndpointAddress &
3776-
USB_ENDPOINT_NUMBER_MASK);
3777-
period = dev->ep_intr->desc.bInterval;
3778-
3721+
period = ep_intr->desc.bInterval;
37793722
maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0);
37803723
buf = kmalloc(maxp, GFP_KERNEL);
37813724
if (buf) {

0 commit comments

Comments
 (0)