Commit 49426437 authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab

V4L/DVB (9621): Avoid writing outside shadow.bytes[] array

There were no check about the limits of shadow.bytes array. This offers
a risk of writing values outside the limits, overriding other data
areas.
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 81cb5c4f
...@@ -154,7 +154,7 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) ...@@ -154,7 +154,7 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
{ {
unsigned char buffer[2]; unsigned char buffer[2];
if (-1 == subaddr) { if (subaddr < 0) {
v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n",
chip->c->name, val); chip->c->name, val);
chip->shadow.bytes[1] = val; chip->shadow.bytes[1] = val;
...@@ -165,6 +165,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) ...@@ -165,6 +165,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
return -1; return -1;
} }
} else { } else {
if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
v4l_info(chip->c,
"Tried to access a non-existent register: %d\n",
subaddr);
return -EINVAL;
}
v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n",
chip->c->name, subaddr, val); chip->c->name, subaddr, val);
chip->shadow.bytes[subaddr+1] = val; chip->shadow.bytes[subaddr+1] = val;
...@@ -179,12 +186,20 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) ...@@ -179,12 +186,20 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val)
return 0; return 0;
} }
static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask) static int chip_write_masked(struct CHIPSTATE *chip,
int subaddr, int val, int mask)
{ {
if (mask != 0) { if (mask != 0) {
if (-1 == subaddr) { if (subaddr < 0) {
val = (chip->shadow.bytes[1] & ~mask) | (val & mask); val = (chip->shadow.bytes[1] & ~mask) | (val & mask);
} else { } else {
if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
v4l_info(chip->c,
"Tried to access a non-existent register: %d\n",
subaddr);
return -EINVAL;
}
val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask);
} }
} }
...@@ -230,6 +245,15 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) ...@@ -230,6 +245,15 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd)
if (0 == cmd->count) if (0 == cmd->count)
return 0; return 0;
if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) {
v4l_info(chip->c,
"Tried to access a non-existent register range: %d to %d\n",
cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1);
return -EINVAL;
}
/* FIXME: it seems that the shadow bytes are wrong bellow !*/
/* update our shadow register set; print bytes if (debug > 0) */ /* update our shadow register set; print bytes if (debug > 0) */
v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:",
chip->c->name, name,cmd->bytes[0]); chip->c->name, name,cmd->bytes[0]);
......
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