Commit 90cc0e1a authored by Oliver Neukum's avatar Oliver Neukum Committed by Greg Kroah-Hartman

[PATCH] fixes for races in kaweth probe

using init_etherdev(0, 0) in probe is a race. The struct net_device must be
allocate and filled before init_etherdev is called, or there's a race which
creates a network interface that isn't usable.
The patch for kaweth for 2.5 fixes it.
parent b4f93012
...@@ -854,6 +854,7 @@ static void *kaweth_probe( ...@@ -854,6 +854,7 @@ static void *kaweth_probe(
) )
{ {
struct kaweth_device *kaweth; struct kaweth_device *kaweth;
struct net_device *netdev;
const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; const eth_addr_t bcast_addr = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
int result = 0; int result = 0;
...@@ -869,10 +870,8 @@ static void *kaweth_probe( ...@@ -869,10 +870,8 @@ static void *kaweth_probe(
(int)dev->descriptor.bLength, (int)dev->descriptor.bLength,
(int)dev->descriptor.bDescriptorType); (int)dev->descriptor.bDescriptorType);
if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL))) { if(!(kaweth = kmalloc(sizeof(struct kaweth_device), GFP_KERNEL)))
kaweth_dbg("out of memory allocating device structure\n");
return NULL; return NULL;
}
memset(kaweth, 0, sizeof(struct kaweth_device)); memset(kaweth, 0, sizeof(struct kaweth_device));
...@@ -998,11 +997,17 @@ static void *kaweth_probe( ...@@ -998,11 +997,17 @@ static void *kaweth_probe(
if(result < 0) { if(result < 0) {
kaweth_err("Error setting receive filter"); kaweth_err("Error setting receive filter");
return kaweth; kfree(kaweth);
return NULL;
} }
kaweth_dbg("Initializing net device."); kaweth_dbg("Initializing net device.");
if(!(netdev = kmalloc(sizeof(struct net_device), GFP_KERNEL))) {
kfree(kaweth);
return NULL;
}
kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!kaweth->tx_urb) if (!kaweth->tx_urb)
goto err_no_urb; goto err_no_urb;
...@@ -1013,12 +1018,7 @@ static void *kaweth_probe( ...@@ -1013,12 +1018,7 @@ static void *kaweth_probe(
if (!kaweth->irq_urb) if (!kaweth->irq_urb)
goto err_tx_and_rx; goto err_tx_and_rx;
kaweth->net = init_etherdev(0, 0); kaweth->net = netdev;
if (!kaweth->net) {
kaweth_err("Error calling init_etherdev.");
return kaweth;
}
memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr)); memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr));
memcpy(kaweth->net->dev_addr, memcpy(kaweth->net->dev_addr,
&kaweth->configuration.hw_addr, &kaweth->configuration.hw_addr,
...@@ -1038,6 +1038,13 @@ static void *kaweth_probe( ...@@ -1038,6 +1038,13 @@ static void *kaweth_probe(
kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size); kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size);
memset(&kaweth->stats, 0, sizeof(kaweth->stats)); memset(&kaweth->stats, 0, sizeof(kaweth->stats));
SET_MODULE_OWNER(netdev);
if (!init_etherdev(netdev, 0)) {
kaweth_err("Error calling init_etherdev.");
goto err_tx_and_rx;
}
kaweth_info("kaweth interface created at %s", kaweth->net->name); kaweth_info("kaweth interface created at %s", kaweth->net->name);
...@@ -1051,6 +1058,7 @@ static void *kaweth_probe( ...@@ -1051,6 +1058,7 @@ static void *kaweth_probe(
usb_free_urb(kaweth->tx_urb); usb_free_urb(kaweth->tx_urb);
err_no_urb: err_no_urb:
kfree(kaweth); kfree(kaweth);
kfree(netdev);
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment