Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a413e26 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-Fix-on-stack-USB-buffers'



Ben Hutchings says:

====================
net: Fix on-stack USB buffers

Allocating USB buffers on the stack is not portable, and no longer
works on x86_64 (with VMAP_STACK enabled as per default).  This
series fixes all the instances I could find where USB networking
drivers do that.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 432d4f8a 2d6a0e9d
Loading
Loading
Loading
Loading
+34 −22
Original line number Diff line number Diff line
@@ -776,7 +776,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
	struct net_device *netdev;
	struct catc *catc;
	u8 broadcast[ETH_ALEN];
	int i, pktsz;
	int pktsz, ret;

	if (usb_set_interface(usbdev,
			intf->altsetting->desc.bInterfaceNumber, 1)) {
@@ -811,12 +811,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
	if ((!catc->ctrl_urb) || (!catc->tx_urb) || 
	    (!catc->rx_urb) || (!catc->irq_urb)) {
		dev_err(&intf->dev, "No free urbs available.\n");
		usb_free_urb(catc->ctrl_urb);
		usb_free_urb(catc->tx_urb);
		usb_free_urb(catc->rx_urb);
		usb_free_urb(catc->irq_urb);
		free_netdev(netdev);
		return -ENOMEM;
		ret = -ENOMEM;
		goto fail_free;
	}

	/* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */
@@ -844,15 +840,24 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
                catc->irq_buf, 2, catc_irq_done, catc, 1);

	if (!catc->is_f5u011) {
		u32 *buf;
		int i;

		dev_dbg(dev, "Checking memory size\n");

		i = 0x12345678;
		catc_write_mem(catc, 0x7a80, &i, 4);
		i = 0x87654321;	
		catc_write_mem(catc, 0xfa80, &i, 4);
		catc_read_mem(catc, 0x7a80, &i, 4);
		buf = kmalloc(4, GFP_KERNEL);
		if (!buf) {
			ret = -ENOMEM;
			goto fail_free;
		}

		switch (i) {
		*buf = 0x12345678;
		catc_write_mem(catc, 0x7a80, buf, 4);
		*buf = 0x87654321;
		catc_write_mem(catc, 0xfa80, buf, 4);
		catc_read_mem(catc, 0x7a80, buf, 4);
	  
		switch (*buf) {
		case 0x12345678:
			catc_set_reg(catc, TxBufCount, 8);
			catc_set_reg(catc, RxBufCount, 32);
@@ -868,6 +873,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
			break;
		}

		kfree(buf);
	  
		dev_dbg(dev, "Getting MAC from SEEROM.\n");
	  
		catc_get_mac(catc, netdev->dev_addr);
@@ -913,16 +920,21 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
	usb_set_intfdata(intf, catc);

	SET_NETDEV_DEV(netdev, &intf->dev);
	if (register_netdev(netdev) != 0) {
	ret = register_netdev(netdev);
	if (ret)
		goto fail_clear_intfdata;

	return 0;

fail_clear_intfdata:
	usb_set_intfdata(intf, NULL);
fail_free:
	usb_free_urb(catc->ctrl_urb);
	usb_free_urb(catc->tx_urb);
	usb_free_urb(catc->rx_urb);
	usb_free_urb(catc->irq_urb);
	free_netdev(netdev);
		return -EIO;
	}
	return 0;
	return ret;
}

static void catc_disconnect(struct usb_interface *intf)
+25 −4
Original line number Diff line number Diff line
@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb)

static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
{
	u8 *buf;
	int ret;

	buf = kmalloc(size, GFP_NOIO);
	if (!buf)
		return -ENOMEM;

	ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
			      PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
			      indx, data, size, 1000);
			      indx, buf, size, 1000);
	if (ret < 0)
		netif_dbg(pegasus, drv, pegasus->net,
			  "%s returned %d\n", __func__, ret);
	else if (ret <= size)
		memcpy(data, buf, ret);
	kfree(buf);
	return ret;
}

static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
			 const void *data)
{
	u8 *buf;
	int ret;

	buf = kmemdup(data, size, GFP_NOIO);
	if (!buf)
		return -ENOMEM;

	ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
			      PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
			      indx, data, size, 100);
			      indx, buf, size, 100);
	if (ret < 0)
		netif_dbg(pegasus, drv, pegasus->net,
			  "%s returned %d\n", __func__, ret);
	kfree(buf);
	return ret;
}

static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
{
	u8 *buf;
	int ret;

	buf = kmemdup(&data, 1, GFP_NOIO);
	if (!buf)
		return -ENOMEM;

	ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
			      PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
			      indx, &data, 1, 1000);
			      indx, buf, 1, 1000);
	if (ret < 0)
		netif_dbg(pegasus, drv, pegasus->net,
			  "%s returned %d\n", __func__, ret);
	kfree(buf);
	return ret;
}

+27 −7
Original line number Diff line number Diff line
@@ -155,16 +155,36 @@ static const char driver_name [] = "rtl8150";
*/
static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
{
	return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
	void *buf;
	int ret;

	buf = kmalloc(size, GFP_NOIO);
	if (!buf)
		return -ENOMEM;

	ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
			      RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
			       indx, 0, data, size, 500);
			      indx, 0, buf, size, 500);
	if (ret > 0 && ret <= size)
		memcpy(data, buf, ret);
	kfree(buf);
	return ret;
}

static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data)
{
	return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
	void *buf;
	int ret;

	buf = kmemdup(data, size, GFP_NOIO);
	if (!buf)
		return -ENOMEM;

	ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
			      RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
			       indx, 0, data, size, 500);
			      indx, 0, buf, size, 500);
	kfree(buf);
	return ret;
}

static void async_set_reg_cb(struct urb *urb)