Commit 0063fc3d authored by David S. Miller's avatar David S. Miller

Merge branch 'misc-bug-fixes-for-the-hso-driver'

Oliver Neukum says:

====================
misc bug fixes for the hso driver

1. Code reuse led to an unregistration of a net driver that has not been
registered
2. The kernel complains generically if kmalloc with GFP_KERNEL fails
3. A race that can lead to an URB that is in use being reused or
a use after free
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8ed54f16 abaf00ff
...@@ -831,8 +831,7 @@ static void hso_net_tx_timeout(struct net_device *net, unsigned int txqueue) ...@@ -831,8 +831,7 @@ static void hso_net_tx_timeout(struct net_device *net, unsigned int txqueue)
dev_warn(&net->dev, "Tx timed out.\n"); dev_warn(&net->dev, "Tx timed out.\n");
/* Tear the waiting frame off the list */ /* Tear the waiting frame off the list */
if (odev->mux_bulk_tx_urb && if (odev->mux_bulk_tx_urb)
(odev->mux_bulk_tx_urb->status == -EINPROGRESS))
usb_unlink_urb(odev->mux_bulk_tx_urb); usb_unlink_urb(odev->mux_bulk_tx_urb);
/* Update statistics */ /* Update statistics */
...@@ -2357,7 +2356,7 @@ static int remove_net_device(struct hso_device *hso_dev) ...@@ -2357,7 +2356,7 @@ static int remove_net_device(struct hso_device *hso_dev)
} }
/* Frees our network device */ /* Frees our network device */
static void hso_free_net_device(struct hso_device *hso_dev) static void hso_free_net_device(struct hso_device *hso_dev, bool bailout)
{ {
int i; int i;
struct hso_net *hso_net = dev2net(hso_dev); struct hso_net *hso_net = dev2net(hso_dev);
...@@ -2380,7 +2379,7 @@ static void hso_free_net_device(struct hso_device *hso_dev) ...@@ -2380,7 +2379,7 @@ static void hso_free_net_device(struct hso_device *hso_dev)
kfree(hso_net->mux_bulk_tx_buf); kfree(hso_net->mux_bulk_tx_buf);
hso_net->mux_bulk_tx_buf = NULL; hso_net->mux_bulk_tx_buf = NULL;
if (hso_net->net) if (hso_net->net && !bailout)
free_netdev(hso_net->net); free_netdev(hso_net->net);
kfree(hso_dev); kfree(hso_dev);
...@@ -2465,10 +2464,9 @@ static void hso_create_rfkill(struct hso_device *hso_dev, ...@@ -2465,10 +2464,9 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
&interface_to_usbdev(interface)->dev, &interface_to_usbdev(interface)->dev,
RFKILL_TYPE_WWAN, RFKILL_TYPE_WWAN,
&hso_rfkill_ops, hso_dev); &hso_rfkill_ops, hso_dev);
if (!hso_net->rfkill) { if (!hso_net->rfkill)
dev_err(dev, "%s - Out of memory\n", __func__);
return; return;
}
if (rfkill_register(hso_net->rfkill) < 0) { if (rfkill_register(hso_net->rfkill) < 0) {
rfkill_destroy(hso_net->rfkill); rfkill_destroy(hso_net->rfkill);
hso_net->rfkill = NULL; hso_net->rfkill = NULL;
...@@ -2556,7 +2554,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface, ...@@ -2556,7 +2554,7 @@ static struct hso_device *hso_create_net_device(struct usb_interface *interface,
return hso_dev; return hso_dev;
exit: exit:
hso_free_net_device(hso_dev); hso_free_net_device(hso_dev, true);
return NULL; return NULL;
} }
...@@ -3133,7 +3131,7 @@ static void hso_free_interface(struct usb_interface *interface) ...@@ -3133,7 +3131,7 @@ static void hso_free_interface(struct usb_interface *interface)
rfkill_unregister(rfk); rfkill_unregister(rfk);
rfkill_destroy(rfk); rfkill_destroy(rfk);
} }
hso_free_net_device(network_table[i]); hso_free_net_device(network_table[i], false);
} }
} }
} }
......
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