| From 5593523f968bc86d42a035c6df47d5e0979b5ace Mon Sep 17 00:00:00 2001 |
| From: Ben Hutchings <ben@decadent.org.uk> |
| Date: Sat, 4 Feb 2017 16:56:03 +0000 |
| Subject: [PATCH] pegasus: Use heap buffers for all register access |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| commit 5593523f968bc86d42a035c6df47d5e0979b5ace upstream. |
| |
| Allocating USB buffers on the stack is not portable, and no longer |
| works on x86_64 (with VMAP_STACK enabled as per default). |
| |
| Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") |
| References: https://bugs.debian.org/852556 |
| Reported-by: Lisandro Damián Nicanor Pérez Meyer <lisandro@debian.org> |
| Tested-by: Lisandro Damián Nicanor Pérez Meyer <lisandro@debian.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| |
| 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) |
| |
| 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; |
| } |
| |
| -- |
| 2.12.0 |
| |