Currently pegasus passes stack memory (which must not be used for DMA transfers) as URB buffers with get_registers(), set_registers() and set_register(). Apply fix inside these functions instead of changing every call site. Stack usage was introduced by recent commit 323b34963d11 "drivers: net: usb: pegasus: fix control urb submission". Patch is only compile tested. Cc: <stable@xxxxxxxxxxxxxxx> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@xxxxxx> --- drivers/net/usb/pegasus.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 03e8a15..3bce862 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -127,39 +127,59 @@ static void async_ctrl_callback(struct urb *urb) static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) { int ret; + void *buf; + + buf = kmalloc(size, GFP_KERNEL); + 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 + memcpy(data, buf, ret); /* ret == bytes read (max == size) */ + kfree(buf); return ret; } static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data) { int ret; + void *buf; + + buf = kmemdup(data, size, GFP_KERNEL); + 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) { int ret; + void *buf; + + buf = kmemdup(&data, 1, GFP_KERNEL); + 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; } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html