mirror of https://gitee.com/openkylin/linux.git
[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:
parent
a12b8ab8c5
commit
950e252cb4
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue