Commit 716e324b authored by Alyssa Milburn's avatar Alyssa Milburn Committed by Ben Hutchings

dw2102: limit messages to buffer size

commit 950e252c upstream.

Otherwise the i2c transfer functions can read or write beyond the end of
stack or heap buffers.
Signed-off-by: default avatarAlyssa Milburn <amilburn@zall.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@s-opensource.com>
[bwh: Backported to 3.2:
 - Use obuf instead of state->data
 - Adjust filename, context]
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent 45fd70b4
......@@ -234,6 +234,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;
......@@ -249,6 +263,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;
......@@ -292,6 +313,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);
......@@ -492,6 +520,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);
......@@ -718,6 +752,13 @@ static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
msg[0].buf[0] = ibuf[1];
break;
default:
if (3 + msg[0].len > sizeof(obuf)) {
warn("i2c wr: len=%d is too big!\n",
msg[0].len);
num = -EOPNOTSUPP;
break;
}
/* always i2c write*/
obuf[0] = 0x08;
obuf[1] = msg[0].addr;
......@@ -733,6 +774,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(obuf)) {
warn("i2c rd: len=%d is too big!\n",
msg[0].len);
num = -EOPNOTSUPP;
break;
}
if (1 + msg[1].len > sizeof(obuf)) {
warn("i2c rd: len=%d is too big!\n",
msg[1].len);
num = -EOPNOTSUPP;
break;
}
obuf[0] = 0x09;
obuf[1] = msg[0].len;
obuf[2] = msg[1].len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment