aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/i2c/i2c-dev.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 45048323b75e..5ec2261574ec 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -265,19 +265,41 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
265 265
266 res = 0; 266 res = 0;
267 for (i = 0; i < rdwr_arg.nmsgs; i++) { 267 for (i = 0; i < rdwr_arg.nmsgs; i++) {
268 /* Limit the size of the message to a sane amount; 268 /* Limit the size of the message to a sane amount */
269 * and don't let length change either. */ 269 if (rdwr_pa[i].len > 8192) {
270 if ((rdwr_pa[i].len > 8192) ||
271 (rdwr_pa[i].flags & I2C_M_RECV_LEN)) {
272 res = -EINVAL; 270 res = -EINVAL;
273 break; 271 break;
274 } 272 }
273
275 data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf; 274 data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
276 rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len); 275 rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
277 if (IS_ERR(rdwr_pa[i].buf)) { 276 if (IS_ERR(rdwr_pa[i].buf)) {
278 res = PTR_ERR(rdwr_pa[i].buf); 277 res = PTR_ERR(rdwr_pa[i].buf);
279 break; 278 break;
280 } 279 }
280
281 /*
282 * If the message length is received from the slave (similar
283 * to SMBus block read), we must ensure that the buffer will
284 * be large enough to cope with a message length of
285 * I2C_SMBUS_BLOCK_MAX as this is the maximum underlying bus
286 * drivers allow. The first byte in the buffer must be
287 * pre-filled with the number of extra bytes, which must be
288 * at least one to hold the message length, but can be
289 * greater (for example to account for a checksum byte at
290 * the end of the message.)
291 */
292 if (rdwr_pa[i].flags & I2C_M_RECV_LEN) {
293 if (!(rdwr_pa[i].flags & I2C_M_RD) ||
294 rdwr_pa[i].buf[0] < 1 ||
295 rdwr_pa[i].len < rdwr_pa[i].buf[0] +
296 I2C_SMBUS_BLOCK_MAX) {
297 res = -EINVAL;
298 break;
299 }
300
301 rdwr_pa[i].len = rdwr_pa[i].buf[0];
302 }
281 } 303 }
282 if (res < 0) { 304 if (res < 0) {
283 int j; 305 int j;