[media] dw2102: limit messages to buffer size

Otherwise the i2c transfer functions can read or write beyond the end of
stack or heap buffers.

Signed-off-by: Alyssa Milburn <amilburn@zall.org>
Cc: stable@vger.kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
Alyssa Milburn 2017-04-01 14:34:49 -03:00 committed by Mauro Carvalho Chehab
parent a12b8ab8c5
commit 950e252cb4
1 changed files with 54 additions and 0 deletions

View File

@ -204,6 +204,20 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
switch (num) { switch (num) {
case 2: case 2:
if (msg[0].len != 1) {
warn("i2c rd: len=%d is not 1!\n",
msg[0].len);
num = -EOPNOTSUPP;
break;
}
if (2 + msg[1].len > sizeof(buf6)) {
warn("i2c rd: len=%d is too big!\n",
msg[1].len);
num = -EOPNOTSUPP;
break;
}
/* read si2109 register by number */ /* read si2109 register by number */
buf6[0] = msg[0].addr << 1; buf6[0] = msg[0].addr << 1;
buf6[1] = msg[0].len; buf6[1] = msg[0].len;
@ -219,6 +233,13 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
case 1: case 1:
switch (msg[0].addr) { switch (msg[0].addr) {
case 0x68: case 0x68:
if (2 + msg[0].len > sizeof(buf6)) {
warn("i2c wr: len=%d is too big!\n",
msg[0].len);
num = -EOPNOTSUPP;
break;
}
/* write to si2109 register */ /* write to si2109 register */
buf6[0] = msg[0].addr << 1; buf6[0] = msg[0].addr << 1;
buf6[1] = msg[0].len; buf6[1] = msg[0].len;
@ -262,6 +283,13 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
/* first write first register number */ /* first write first register number */
u8 ibuf[MAX_XFER_SIZE], obuf[3]; u8 ibuf[MAX_XFER_SIZE], obuf[3];
if (2 + msg[0].len != sizeof(obuf)) {
warn("i2c rd: len=%d is not 1!\n",
msg[0].len);
ret = -EOPNOTSUPP;
goto unlock;
}
if (2 + msg[1].len > sizeof(ibuf)) { if (2 + msg[1].len > sizeof(ibuf)) {
warn("i2c rd: len=%d is too big!\n", warn("i2c rd: len=%d is too big!\n",
msg[1].len); msg[1].len);
@ -462,6 +490,12 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
/* first write first register number */ /* first write first register number */
u8 ibuf[MAX_XFER_SIZE], obuf[3]; u8 ibuf[MAX_XFER_SIZE], obuf[3];
if (2 + msg[0].len != sizeof(obuf)) {
warn("i2c rd: len=%d is not 1!\n",
msg[0].len);
ret = -EOPNOTSUPP;
goto unlock;
}
if (2 + msg[1].len > sizeof(ibuf)) { if (2 + msg[1].len > sizeof(ibuf)) {
warn("i2c rd: len=%d is too big!\n", warn("i2c rd: len=%d is too big!\n",
msg[1].len); msg[1].len);
@ -696,6 +730,13 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
msg[0].buf[0] = state->data[1]; msg[0].buf[0] = state->data[1];
break; break;
default: default:
if (3 + msg[0].len > sizeof(state->data)) {
warn("i2c wr: len=%d is too big!\n",
msg[0].len);
num = -EOPNOTSUPP;
break;
}
/* always i2c write*/ /* always i2c write*/
state->data[0] = 0x08; state->data[0] = 0x08;
state->data[1] = msg[0].addr; state->data[1] = msg[0].addr;
@ -711,6 +752,19 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
break; break;
case 2: case 2:
/* always i2c read */ /* always i2c read */
if (4 + msg[0].len > sizeof(state->data)) {
warn("i2c rd: len=%d is too big!\n",
msg[0].len);
num = -EOPNOTSUPP;
break;
}
if (1 + msg[1].len > sizeof(state->data)) {
warn("i2c rd: len=%d is too big!\n",
msg[1].len);
num = -EOPNOTSUPP;
break;
}
state->data[0] = 0x09; state->data[0] = 0x09;
state->data[1] = msg[0].len; state->data[1] = msg[0].len;
state->data[2] = msg[1].len; state->data[2] = msg[1].len;