]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.11/pegasus-use-heap-buffers-for-all-register-access.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.9.11 / pegasus-use-heap-buffers-for-all-register-access.patch
1 From foo@baz Tue Feb 14 17:03:08 PST 2017
2 From: Ben Hutchings <ben@decadent.org.uk>
3 Date: Sat, 4 Feb 2017 16:56:03 +0000
4 Subject: pegasus: Use heap buffers for all register access
5
6 From: Ben Hutchings <ben@decadent.org.uk>
7
8
9 [ Upstream commit 5593523f968bc86d42a035c6df47d5e0979b5ace ]
10
11 Allocating USB buffers on the stack is not portable, and no longer
12 works on x86_64 (with VMAP_STACK enabled as per default).
13
14 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
15 References: https://bugs.debian.org/852556
16 Reported-by: Lisandro Damián Nicanor Pérez Meyer <lisandro@debian.org>
17 Tested-by: Lisandro Damián Nicanor Pérez Meyer <lisandro@debian.org>
18 Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
19 Signed-off-by: David S. Miller <davem@davemloft.net>
20 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
21 ---
22 drivers/net/usb/pegasus.c | 29 +++++++++++++++++++++++++----
23 1 file changed, 25 insertions(+), 4 deletions(-)
24
25 --- a/drivers/net/usb/pegasus.c
26 +++ b/drivers/net/usb/pegasus.c
27 @@ -126,40 +126,61 @@ static void async_ctrl_callback(struct u
28
29 static int get_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
30 {
31 + u8 *buf;
32 int ret;
33
34 + buf = kmalloc(size, GFP_NOIO);
35 + if (!buf)
36 + return -ENOMEM;
37 +
38 ret = usb_control_msg(pegasus->usb, usb_rcvctrlpipe(pegasus->usb, 0),
39 PEGASUS_REQ_GET_REGS, PEGASUS_REQT_READ, 0,
40 - indx, data, size, 1000);
41 + indx, buf, size, 1000);
42 if (ret < 0)
43 netif_dbg(pegasus, drv, pegasus->net,
44 "%s returned %d\n", __func__, ret);
45 + else if (ret <= size)
46 + memcpy(data, buf, ret);
47 + kfree(buf);
48 return ret;
49 }
50
51 -static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size, void *data)
52 +static int set_registers(pegasus_t *pegasus, __u16 indx, __u16 size,
53 + const void *data)
54 {
55 + u8 *buf;
56 int ret;
57
58 + buf = kmemdup(data, size, GFP_NOIO);
59 + if (!buf)
60 + return -ENOMEM;
61 +
62 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
63 PEGASUS_REQ_SET_REGS, PEGASUS_REQT_WRITE, 0,
64 - indx, data, size, 100);
65 + indx, buf, size, 100);
66 if (ret < 0)
67 netif_dbg(pegasus, drv, pegasus->net,
68 "%s returned %d\n", __func__, ret);
69 + kfree(buf);
70 return ret;
71 }
72
73 static int set_register(pegasus_t *pegasus, __u16 indx, __u8 data)
74 {
75 + u8 *buf;
76 int ret;
77
78 + buf = kmemdup(&data, 1, GFP_NOIO);
79 + if (!buf)
80 + return -ENOMEM;
81 +
82 ret = usb_control_msg(pegasus->usb, usb_sndctrlpipe(pegasus->usb, 0),
83 PEGASUS_REQ_SET_REG, PEGASUS_REQT_WRITE, data,
84 - indx, &data, 1, 1000);
85 + indx, buf, 1, 1000);
86 if (ret < 0)
87 netif_dbg(pegasus, drv, pegasus->net,
88 "%s returned %d\n", __func__, ret);
89 + kfree(buf);
90 return ret;
91 }
92