Skip to content

Commit 6a413e2

Browse files
committed
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 <[email protected]>
2 parents 432d4f8 + 2d6a0e9 commit 6a413e2

File tree

3 files changed

+86
-33
lines changed

3 files changed

+86
-33
lines changed

drivers/net/usb/catc.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
776776
struct net_device *netdev;
777777
struct catc *catc;
778778
u8 broadcast[ETH_ALEN];
779-
int i, pktsz;
779+
int pktsz, ret;
780780

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

822818
/* 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
844840
catc->irq_buf, 2, catc_irq_done, catc, 1);
845841

846842
if (!catc->is_f5u011) {
843+
u32 *buf;
844+
int i;
845+
847846
dev_dbg(dev, "Checking memory size\n");
848847

849-
i = 0x12345678;
850-
catc_write_mem(catc, 0x7a80, &i, 4);
851-
i = 0x87654321;
852-
catc_write_mem(catc, 0xfa80, &i, 4);
853-
catc_read_mem(catc, 0x7a80, &i, 4);
848+
buf = kmalloc(4, GFP_KERNEL);
849+
if (!buf) {
850+
ret = -ENOMEM;
851+
goto fail_free;
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);
854859

855-
switch (i) {
860+
switch (*buf) {
856861
case 0x12345678:
857862
catc_set_reg(catc, TxBufCount, 8);
858863
catc_set_reg(catc, RxBufCount, 32);
@@ -867,6 +872,8 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
867872
dev_dbg(dev, "32k Memory\n");
868873
break;
869874
}
875+
876+
kfree(buf);
870877

871878
dev_dbg(dev, "Getting MAC from SEEROM.\n");
872879

@@ -913,16 +920,21 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id
913920
usb_set_intfdata(intf, catc);
914921

915922
SET_NETDEV_DEV(netdev, &intf->dev);
916-
if (register_netdev(netdev) != 0) {
917-
usb_set_intfdata(intf, NULL);
918-
usb_free_urb(catc->ctrl_urb);
919-
usb_free_urb(catc->tx_urb);
920-
usb_free_urb(catc->rx_urb);
921-
usb_free_urb(catc->irq_urb);
922-
free_netdev(netdev);
923-
return -EIO;
924-
}
923+
ret = register_netdev(netdev);
924+
if (ret)
925+
goto fail_clear_intfdata;
926+
925927
return 0;
928+
929+
fail_clear_intfdata:
930+
usb_set_intfdata(intf, NULL);
931+
fail_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;
926938
}
927939

928940
static void catc_disconnect(struct usb_interface *intf)

drivers/net/usb/pegasus.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,40 +126,61 @@ static void async_ctrl_callback(struct urb *urb)
126126

127127
static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
128128
{
129+
u8 *buf;
129130
int ret;
130131

132+
buf = kmalloc(size, GFP_NOIO);
133+
if (!buf)
134+
return -ENOMEM;
135+
131136
ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
132137
PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
133-
indx, data, size, 1000);
138+
indx, buf, size, 1000);
134139
if (ret < 0)
135140
netif_dbg(pegasus, drv, pegasus->net,
136141
"%s returned %d\n", __func__, ret);
142+
else if (ret <= size)
143+
memcpy(data, buf, ret);
144+
kfree(buf);
137145
return ret;
138146
}
139147

140-
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
148+
static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
149+
const void *data)
141150
{
151+
u8 *buf;
142152
int ret;
143153

154+
buf = kmemdup(data, size, GFP_NOIO);
155+
if (!buf)
156+
return -ENOMEM;
157+
144158
ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
145159
PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
146-
indx, data, size, 100);
160+
indx, buf, size, 100);
147161
if (ret < 0)
148162
netif_dbg(pegasus, drv, pegasus->net,
149163
"%s returned %d\n", __func__, ret);
164+
kfree(buf);
150165
return ret;
151166
}
152167

153168
static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
154169
{
170+
u8 *buf;
155171
int ret;
156172

173+
buf = kmemdup(&data, 1, GFP_NOIO);
174+
if (!buf)
175+
return -ENOMEM;
176+
157177
ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
158178
PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
159-
indx, &data, 1, 1000);
179+
indx, buf, 1, 1000);
160180
if (ret < 0)
161181
netif_dbg(pegasus, drv, pegasus->net,
162182
"%s returned %d\n", __func__, ret);
183+
kfree(buf);
163184
return ret;
164185
}
165186

drivers/net/usb/rtl8150.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,16 +155,36 @@ static const char driver_name [] = "rtl8150";
155155
*/
156156
static int get_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
157157
{
158-
return usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
159-
RTL8150_REQ_GET_REGS, RTL8150_REQT_READ,
160-
indx, 0, data, size, 500);
158+
void *buf;
159+
int ret;
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;
161172
}
162173

163-
static int set_registers(rtl8150_t * dev, u16 indx, u16 size, void *data)
174+
static int set_registers(rtl8150_t * dev, u16 indx, u16 size, const void *data)
164175
{
165-
return usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
166-
RTL8150_REQ_SET_REGS, RTL8150_REQT_WRITE,
167-
indx, 0, data, size, 500);
176+
void *buf;
177+
int ret;
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;
168188
}
169189

170190
static void async_set_reg_cb(struct urb *urb)

0 commit comments

Comments
 (0)