diff options
-rw-r--r-- | drivers/media/usb/dvb-usb/cxusb.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/media/usb/dvb-usb/cxusb.c b/drivers/media/usb/dvb-usb/cxusb.c index 3940bb0f9ef6..20e345d9fe8f 100644 --- a/drivers/media/usb/dvb-usb/cxusb.c +++ b/drivers/media/usb/dvb-usb/cxusb.c | |||
@@ -43,6 +43,9 @@ | |||
43 | #include "lgs8gxx.h" | 43 | #include "lgs8gxx.h" |
44 | #include "atbm8830.h" | 44 | #include "atbm8830.h" |
45 | 45 | ||
46 | /* Max transfer size done by I2C transfer functions */ | ||
47 | #define MAX_XFER_SIZE 64 | ||
48 | |||
46 | /* debug */ | 49 | /* debug */ |
47 | static int dvb_usb_cxusb_debug; | 50 | static int dvb_usb_cxusb_debug; |
48 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); | 51 | module_param_named(debug, dvb_usb_cxusb_debug, int, 0644); |
@@ -57,7 +60,14 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d, | |||
57 | u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) | 60 | u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen) |
58 | { | 61 | { |
59 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ | 62 | int wo = (rbuf == NULL || rlen == 0); /* write-only */ |
60 | u8 sndbuf[1+wlen]; | 63 | u8 sndbuf[MAX_XFER_SIZE]; |
64 | |||
65 | if (1 + wlen > sizeof(sndbuf)) { | ||
66 | warn("i2c wr: len=%d is too big!\n", | ||
67 | wlen); | ||
68 | return -EOPNOTSUPP; | ||
69 | } | ||
70 | |||
61 | memset(sndbuf, 0, 1+wlen); | 71 | memset(sndbuf, 0, 1+wlen); |
62 | 72 | ||
63 | sndbuf[0] = cmd; | 73 | sndbuf[0] = cmd; |
@@ -158,7 +168,13 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
158 | 168 | ||
159 | if (msg[i].flags & I2C_M_RD) { | 169 | if (msg[i].flags & I2C_M_RD) { |
160 | /* read only */ | 170 | /* read only */ |
161 | u8 obuf[3], ibuf[1+msg[i].len]; | 171 | u8 obuf[3], ibuf[MAX_XFER_SIZE]; |
172 | |||
173 | if (1 + msg[i].len > sizeof(ibuf)) { | ||
174 | warn("i2c rd: len=%d is too big!\n", | ||
175 | msg[i].len); | ||
176 | return -EOPNOTSUPP; | ||
177 | } | ||
162 | obuf[0] = 0; | 178 | obuf[0] = 0; |
163 | obuf[1] = msg[i].len; | 179 | obuf[1] = msg[i].len; |
164 | obuf[2] = msg[i].addr; | 180 | obuf[2] = msg[i].addr; |
@@ -172,7 +188,18 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
172 | } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) && | 188 | } else if (i+1 < num && (msg[i+1].flags & I2C_M_RD) && |
173 | msg[i].addr == msg[i+1].addr) { | 189 | msg[i].addr == msg[i+1].addr) { |
174 | /* write to then read from same address */ | 190 | /* write to then read from same address */ |
175 | u8 obuf[3+msg[i].len], ibuf[1+msg[i+1].len]; | 191 | u8 obuf[MAX_XFER_SIZE], ibuf[MAX_XFER_SIZE]; |
192 | |||
193 | if (3 + msg[i].len > sizeof(obuf)) { | ||
194 | warn("i2c wr: len=%d is too big!\n", | ||
195 | msg[i].len); | ||
196 | return -EOPNOTSUPP; | ||
197 | } | ||
198 | if (1 + msg[i + 1].len > sizeof(ibuf)) { | ||
199 | warn("i2c rd: len=%d is too big!\n", | ||
200 | msg[i + 1].len); | ||
201 | return -EOPNOTSUPP; | ||
202 | } | ||
176 | obuf[0] = msg[i].len; | 203 | obuf[0] = msg[i].len; |
177 | obuf[1] = msg[i+1].len; | 204 | obuf[1] = msg[i+1].len; |
178 | obuf[2] = msg[i].addr; | 205 | obuf[2] = msg[i].addr; |
@@ -191,7 +218,13 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], | |||
191 | i++; | 218 | i++; |
192 | } else { | 219 | } else { |
193 | /* write only */ | 220 | /* write only */ |
194 | u8 obuf[2+msg[i].len], ibuf; | 221 | u8 obuf[MAX_XFER_SIZE], ibuf; |
222 | |||
223 | if (2 + msg[i].len > sizeof(obuf)) { | ||
224 | warn("i2c wr: len=%d is too big!\n", | ||
225 | msg[i].len); | ||
226 | return -EOPNOTSUPP; | ||
227 | } | ||
195 | obuf[0] = msg[i].addr; | 228 | obuf[0] = msg[i].addr; |
196 | obuf[1] = msg[i].len; | 229 | obuf[1] = msg[i].len; |
197 | memcpy(&obuf[2], msg[i].buf, msg[i].len); | 230 | memcpy(&obuf[2], msg[i].buf, msg[i].len); |