Skip to content

Commit

Permalink
[media] dw2102: limit messages to buffer size
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
noopwafel authored and mchehab committed Apr 19, 2017
1 parent a12b8ab commit 950e252
Showing 1 changed file with 54 additions and 0 deletions.
54 changes: 54 additions & 0 deletions drivers/media/usb/dvb-usb/dw2102.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,20 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,

switch (num) {
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 */
buf6[0] = msg[0].addr << 1;
buf6[1] = msg[0].len;
Expand All @@ -219,6 +233,13 @@ static int dw2102_serit_i2c_transfer(struct i2c_adapter *adap,
case 1:
switch (msg[0].addr) {
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 */
buf6[0] = msg[0].addr << 1;
buf6[1] = msg[0].len;
Expand Down Expand Up @@ -262,6 +283,13 @@ static int dw2102_earda_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg ms
/* first write first register number */
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)) {
warn("i2c rd: len=%d is too big!\n",
msg[1].len);
Expand Down Expand Up @@ -462,6 +490,12 @@ static int dw3101_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
/* first write first register number */
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)) {
warn("i2c rd: len=%d is too big!\n",
msg[1].len);
Expand Down Expand Up @@ -696,6 +730,13 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
msg[0].buf[0] = state->data[1];
break;
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*/
state->data[0] = 0x08;
state->data[1] = msg[0].addr;
Expand All @@ -711,6 +752,19 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
break;
case 2:
/* 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[1] = msg[0].len;
state->data[2] = msg[1].len;
Expand Down

0 comments on commit 950e252

Please sign in to comment.