diff options
| author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-13 15:03:28 -0500 |
|---|---|---|
| committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-11-14 11:24:45 -0500 |
| commit | 494264379d186bf806613d27aafb7d88d42f4212 (patch) | |
| tree | 681aeb1444d7e1b2d994d5045644a0c8ec44e342 | |
| parent | 81cb5c4f7fbe6971d9c61401bc47193290fd59b7 (diff) | |
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: Mauro Carvalho Chehab <mchehab@redhat.com>
| -rw-r--r-- | drivers/media/video/tvaudio.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c index 5ec369d54e6e..55b39b9a33d9 100644 --- a/drivers/media/video/tvaudio.c +++ b/drivers/media/video/tvaudio.c | |||
| @@ -154,7 +154,7 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
| 154 | { | 154 | { |
| 155 | unsigned char buffer[2]; | 155 | unsigned char buffer[2]; |
| 156 | 156 | ||
| 157 | if (-1 == subaddr) { | 157 | if (subaddr < 0) { |
| 158 | v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", | 158 | v4l_dbg(1, debug, chip->c, "%s: chip_write: 0x%x\n", |
| 159 | chip->c->name, val); | 159 | chip->c->name, val); |
| 160 | chip->shadow.bytes[1] = val; | 160 | chip->shadow.bytes[1] = val; |
| @@ -165,6 +165,13 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
| 165 | return -1; | 165 | return -1; |
| 166 | } | 166 | } |
| 167 | } else { | 167 | } else { |
| 168 | if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | ||
| 169 | v4l_info(chip->c, | ||
| 170 | "Tried to access a non-existent register: %d\n", | ||
| 171 | subaddr); | ||
| 172 | return -EINVAL; | ||
| 173 | } | ||
| 174 | |||
| 168 | v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", | 175 | v4l_dbg(1, debug, chip->c, "%s: chip_write: reg%d=0x%x\n", |
| 169 | chip->c->name, subaddr, val); | 176 | chip->c->name, subaddr, val); |
| 170 | chip->shadow.bytes[subaddr+1] = val; | 177 | chip->shadow.bytes[subaddr+1] = val; |
| @@ -179,12 +186,20 @@ static int chip_write(struct CHIPSTATE *chip, int subaddr, int val) | |||
| 179 | return 0; | 186 | return 0; |
| 180 | } | 187 | } |
| 181 | 188 | ||
| 182 | static int chip_write_masked(struct CHIPSTATE *chip, int subaddr, int val, int mask) | 189 | static int chip_write_masked(struct CHIPSTATE *chip, |
| 190 | int subaddr, int val, int mask) | ||
| 183 | { | 191 | { |
| 184 | if (mask != 0) { | 192 | if (mask != 0) { |
| 185 | if (-1 == subaddr) { | 193 | if (subaddr < 0) { |
| 186 | val = (chip->shadow.bytes[1] & ~mask) | (val & mask); | 194 | val = (chip->shadow.bytes[1] & ~mask) | (val & mask); |
| 187 | } else { | 195 | } else { |
| 196 | if (subaddr + 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | ||
| 197 | v4l_info(chip->c, | ||
| 198 | "Tried to access a non-existent register: %d\n", | ||
| 199 | subaddr); | ||
| 200 | return -EINVAL; | ||
| 201 | } | ||
| 202 | |||
| 188 | val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); | 203 | val = (chip->shadow.bytes[subaddr+1] & ~mask) | (val & mask); |
| 189 | } | 204 | } |
| 190 | } | 205 | } |
| @@ -230,6 +245,15 @@ static int chip_cmd(struct CHIPSTATE *chip, char *name, audiocmd *cmd) | |||
| 230 | if (0 == cmd->count) | 245 | if (0 == cmd->count) |
| 231 | return 0; | 246 | return 0; |
| 232 | 247 | ||
| 248 | if (cmd->count + cmd->bytes[0] - 1 >= ARRAY_SIZE(chip->shadow.bytes)) { | ||
| 249 | v4l_info(chip->c, | ||
| 250 | "Tried to access a non-existent register range: %d to %d\n", | ||
| 251 | cmd->bytes[0] + 1, cmd->bytes[0] + cmd->count - 1); | ||
| 252 | return -EINVAL; | ||
| 253 | } | ||
| 254 | |||
| 255 | /* FIXME: it seems that the shadow bytes are wrong bellow !*/ | ||
| 256 | |||
| 233 | /* update our shadow register set; print bytes if (debug > 0) */ | 257 | /* update our shadow register set; print bytes if (debug > 0) */ |
| 234 | v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", | 258 | v4l_dbg(1, debug, chip->c, "%s: chip_cmd(%s): reg=%d, data:", |
| 235 | chip->c->name, name,cmd->bytes[0]); | 259 | chip->c->name, name,cmd->bytes[0]); |
