diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-13 18:03:28 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-13 18:03:28 -0200 |
commit | ae85a80ddd128705ff86971d904a2a12e7cb48ad (patch) | |
tree | c9d0e9f92a3fe1323bd59579a1fe22be55b848ae | |
parent | a08c59762c341f4247d52bedd399077fcaac38d2 (diff) | |
download | mediapointer-dvb-s2-ae85a80ddd128705ff86971d904a2a12e7cb48ad.tar.gz mediapointer-dvb-s2-ae85a80ddd128705ff86971d904a2a12e7cb48ad.tar.bz2 |
Avoid writing outside shadow.bytes[] array
From: Mauro Carvalho Chehab <mchehab@redhat.com>
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.
Priority: normal
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | linux/drivers/media/video/tvaudio.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c index 1575e6f9d..4a5c20ffa 100644 --- a/linux/drivers/media/video/tvaudio.c +++ b/linux/drivers/media/video/tvaudio.c @@ -157,7 +157,7 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) { unsigned char buffer[2]; - if (-1 == subaddr) { + if (subaddr < 0) { v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", chip->c->name, val); chip->shadow.bytes[1] = val; @@ -168,6 +168,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) return -1; } } 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", chip->c->name, subaddr, val); chip->shadow.bytes[subaddr+1] = val; @@ -182,12 +189,20 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) 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 (-1 == subaddr) { + if (subaddr < 0) { val = (chip->shadow.bytes[1] & ~mask) | (val & mask); } 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); } } @@ -233,6 +248,15 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) if (0 == cmd->count) 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) */ v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", chip->c->name, name,cmd->bytes[0]); |