[PATCH] pegasus ethernet over USB driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch against 2.6.13.2 addresses some small bugs in the pegasus
ethernet-over-USB driver. Specifically, malformed long packets from the
adapter could cause a kernel panic; the interrupt interval calculation was
inappropriate for high-speed devices; the return code from read_mii_word was
tested incorrectly; and failure to unlink outstanding URBs before freeing
them could lead to kernel panics when unloading the driver.

Signed-off-by: Kevin Vigor <[email protected]>


--- drivers/usb/net/pegasus.c-pristine	2005-07-27 14:48:54.000000000 -0600
+++ drivers/usb/net/pegasus.c	2005-09-20 15:45:42.000000000 -0600
@@ -648,6 +648,12 @@ static void read_bulk_callback(struct ur
 		pkt_len -= 8;
 	}

+    /* If packet is unreasonably long, quietly drop it
+     * rather than kernel panicing by calling skb_put.
+     */
+	if (pkt_len > PEGASUS_MTU)
+ goto goon; +
 	/*
 	 * at this point we are sure pegasus->rx_skb != NULL
 	 * so we go ahead and pass up the packet.
@@ -888,15 +894,17 @@ static inline void get_interrupt_interva
 	__u8 data[2];

 	read_eprom_word(pegasus, 4, (__u16 *) data);
-	if (data[1] < 0x80) {
-		if (netif_msg_timer(pegasus))
-			dev_info(&pegasus->intf->dev,
-				"intr interval changed from %ums to %ums\n",
-				data[1], 0x80);
-		data[1] = 0x80;
+    if (pegasus->usb->speed != USB_SPEED_HIGH) {
+		if (data[1] < 0x80) {
+			if (netif_msg_timer(pegasus))
+				dev_info(&pegasus->intf->dev,
+						"intr interval changed from %ums to %ums\n",
+						data[1], 0x80);
+			data[1] = 0x80;
 #ifdef	PEGASUS_WRITE_EEPROM
-		write_eprom_word(pegasus, 4, *(__u16 *) data);
+			write_eprom_word(pegasus, 4, *(__u16 *) data);
 #endif
+		}
 	}
 	pegasus->intr_interval = data[1];
 }
@@ -906,8 +914,9 @@ static void set_carrier(struct net_devic
 	pegasus_t *pegasus = netdev_priv(net);
 	u16 tmp;

-	if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
+	if (!read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))
 		return;
+
 	if (tmp & BMSR_LSTATUS)
 		netif_carrier_on(net);
 	else
@@ -1357,6 +1366,7 @@ static void pegasus_disconnect(struct us
 	cancel_delayed_work(&pegasus->carrier_check);
 	unregister_netdev(pegasus->net);
 	usb_put_dev(interface_to_usbdev(intf));
+	unlink_all_urbs(pegasus);
 	free_all_urbs(pegasus);
 	free_skb_pool(pegasus);
 	if (pegasus->rx_skb)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux