aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-02-07 10:07:03 -0500
committerDavid S. Miller <davem@davemloft.net>2017-02-07 10:07:03 -0500
commit6a413e269b170d6d3bd32a71de4d5dcf987d6843 (patch)
treec17a5d52ac023e720cf7d57d479e0ac1a0524df3
parent432d4f8ab03527958294ad5e539acaebfc4625e3 (diff)
parent2d6a0e9de03ee658a9adc3bfb2f0ca55dff1e478 (diff)
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: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/usb/catc.c56
-rw-r--r--drivers/net/usb/pegasus.c29
-rw-r--r--drivers/net/usb/rtl8150.c34
3 files changed, 86 insertions, 33 deletions
diff --git a/drivers/net/usb/catc.c b/drivers/net/usb/catc.c
index 3daa41bdd4ea..0acc9b640419 100644
--- a/drivers/net/usb/catc.c
+++ b/drivers/net/usb/catc.c
@@ -776,7 +776,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
776 struct net_device *netdev; 776 struct net_device *netdev;
777 struct catc *catc; 777 struct catc *catc;
778 u8 broadcast[ETH_ALEN]; 778 u8 broadcast[ETH_ALEN];
779 int i, pktsz; 779 int pktsz, ret;
780 780
781 if (usb_set_interface(usbdev, 781 if (usb_set_interface(usbdev,
782 intf->altsetting->desc.bInterfaceNumber, 1)) { 782 intf->altsetting->desc.bInterfaceNumber, 1)) {
@@ -811,12 +811,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
811 if ((!catc->ctrl_urb) || (!catc->tx_urb) || 811 if ((!catc->ctrl_urb) || (!catc->tx_urb) ||
812 (!catc->rx_urb) || (!catc->irq_urb)) { 812 (!catc->rx_urb) || (!catc->irq_urb)) {
813 dev_err(&intf->dev, "No free urbs available.\n"); 813 dev_err(&intf->dev, "No free urbs available.\n");
814 usb_free_urb(catc->ctrl_urb); 814 ret = -ENOMEM;
815 usb_free_urb(catc->tx_urb); 815 goto fail_free;
816 usb_free_urb(catc->rx_urb);
817 usb_free_urb(catc->irq_urb);
818 free_netdev(netdev);
819 return -ENOMEM;
820 } 816 }
821 817
822 /* The F5U011 has the same vendor/product as the netmate but a device version of 0x130 */ 818 /* 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
844 catc->irq_buf, 2, catc_irq_done, catc, 1); 840 catc->irq_buf, 2, catc_irq_done, catc, 1);
845 841
846 if (!catc->is_f5u011) { 842 if (!catc->is_f5u011) {
843 u32 *buf;
844 int i;
845
847 dev_dbg(dev, "Checking memory size\n"); 846 dev_dbg(dev, "Checking memory size\n");
848 847
849 i = 0x12345678; 848 buf = kmalloc(4, GFP_KERNEL);
850 catc_write_mem(catc, 0x7a80, &i, 4); 849 if (!buf) {
851 i = 0x87654321; 850 ret = -ENOMEM;
852 catc_write_mem(catc, 0xfa80, &i, 4); 851 goto fail_free;
853 catc_read_mem(catc, 0x7a80, &i, 4); 852 }
853
854 *buf = 0x12345678;
855 catc_write_mem(catc, 0x7a80, buf, 4);
856 *buf = 0x87654321;
857 catc_write_mem(catc, 0xfa80, buf, 4);
858 catc_read_mem(catc, 0x7a80, buf, 4);
854 859
855 switch (i) { 860 switch (*buf) {
856 case 0x12345678: 861 case 0x12345678:
857 catc_set_reg(catc, TxBufCount, 8); 862 catc_set_reg(catc, TxBufCount, 8);
858 catc_set_reg(catc, RxBufCount, 32); 863 catc_set_reg(catc, RxBufCount, 32);
@@ -867,6 +872,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
867 dev_dbg(dev, "32k Memory\n"); 872 dev_dbg(dev, "32k Memory\n");
868 break; 873 break;
869 } 874 }
875
876 kfree(buf);
870 877
871 dev_dbg(dev, "Getting MAC from SEEROM.\n"); 878 dev_dbg(dev, "Getting MAC from SEEROM.\n");
872 879
@@ -913,16 +920,21 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
913 usb_set_intfdata(intf, catc); 920 usb_set_intfdata(intf, catc);
914 921
915 SET_NETDEV_DEV(netdev, &intf->dev); 922 SET_NETDEV_DEV(netdev, &intf->dev);
916 if (register_netdev(netdev) != 0) { 923 ret = register_netdev(netdev);
917 usb_set_intfdata(intf, NULL); 924 if (ret)
918 usb_free_urb(catc->ctrl_urb); 925 goto fail_clear_intfdata;
919 usb_free_urb(catc->tx_urb); 926
920 usb_free_urb(catc->rx_urb);
921 usb_free_urb(catc->irq_urb);
922 free_netdev(netdev);
923 return -EIO;
924 }
925 return 0; 927 return 0;
928
929fail_clear_intfdata:
930 usb_set_intfdata(intf, NULL);
931fail_free:
932 usb_free_urb(catc->ctrl_urb);
933 usb_free_urb(catc->tx_urb);
934 usb_free_urb(catc->rx_urb);
935 usb_free_urb(catc->irq_urb);
936 free_netdev(netdev);
937 return ret;
926} 938}
927 939
928static void catc_disconnect(struct usb_interface *intf) 940static void catc_disconnect(struct usb_interface *intf)
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 24e803fe9a53..36674484c6fb 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb)
126 126
127static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) 127static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
128{ 128{
129 u8 *buf;
129 int ret; 130 int ret;
130 131
132 buf = kmalloc(size, GFP_NOIO);
133 if (!buf)
134 return -ENOMEM;
135
131 ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0), 136 ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
132 PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0, 137 PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
133 indx, data, size, 1000); 138 indx, buf, size, 1000);
134 if (ret < 0) 139 if (ret < 0)
135 netif_dbg(pegasus, drv, pegasus->net, 140 netif_dbg(pegasus, drv, pegasus->net,
136 "%s returned %d\n", __func__, ret); 141 "%s returned %d\n", __func__, ret);
142 else if (ret <= size)
143 memcpy(data, buf, ret);
144 kfree(buf);
137 return ret; 145 return ret;
138} 146}
139 147
140static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) 148static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
149 const void *data)
141{ 150{
151 u8 *buf;
142 int ret; 152 int ret;
143 153
154 buf = kmemdup(data, size, GFP_NOIO);
155 if (!buf)
156 return -ENOMEM;
157
144 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), 158 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
145 PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0, 159 PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
146 indx, data, size, 100); 160 indx, buf, size, 100);
147 if (ret < 0) 161 if (ret < 0)
148 netif_dbg(pegasus, drv, pegasus->net, 162 netif_dbg(pegasus, drv, pegasus->net,
149 "%s returned %d\n", __func__, ret); 163 "%s returned %d\n", __func__, ret);
164 kfree(buf);
150 return ret; 165 return ret;
151} 166}
152 167
153static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data) 168static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
154{ 169{
170 u8 *buf;
155 int ret; 171 int ret;
156 172
173 buf = kmemdup(&data, 1, GFP_NOIO);
174 if (!buf)
175 return -ENOMEM;
176
157 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0), 177 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
158 PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data, 178 PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
159 indx, &data, 1, 1000); 179 indx, buf, 1, 1000);
160 if (ret < 0) 180 if (ret < 0)
161 netif_dbg(pegasus, drv, pegasus->net, 181 netif_dbg(pegasus, drv, pegasus->net,
162 "%s returned %d\n", __func__, ret); 182 "%s returned %d\n", __func__, ret);
183 kfree(buf);
163 return ret; 184 return ret;
164} 185}
165 186
diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c
index 95b7bd0d7abc..c81c79110cef 100644
--- a/drivers/net/usb/rtl8150.c
+++ b/drivers/net/usb/rtl8150.c
@@ -155,16 +155,36 @@ static const char driver_name [] = "rtl8150";
155*/ 155*/
156static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) 156static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
157{ 157{
158 return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), 158 void *buf;
159 RTL8150_REQ_GET_REGS, RTL8150_REQT_READ, 159 int ret;
160 indx, 0, data, size, 500); 160
161 buf = kmalloc(size, GFP_NOIO);
162 if (!buf)
163 return -ENOMEM;
164
165 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
166 RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
167 indx, 0, buf, size, 500);
168 if (ret > 0 && ret <= size)
169 memcpy(data, buf, ret);
170 kfree(buf);
171 return ret;
161} 172}
162 173
163static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data) 174static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data)
164{ 175{
165 return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), 176 void *buf;
166 RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE, 177 int ret;
167 indx, 0, data, size, 500); 178
179 buf = kmemdup(data, size, GFP_NOIO);
180 if (!buf)
181 return -ENOMEM;
182
183 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
184 RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
185 indx, 0, buf, size, 500);
186 kfree(buf);
187 return ret;
168} 188}
169 189
170static void async_set_reg_cb(struct urb *urb) 190static void async_set_reg_cb(struct urb *urb)