Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+27 −3
Original line number Diff line number Diff line
@@ -154,7 +154,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;
@@ -165,6 +165,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;
@@ -179,12 +186,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);
		}
	}
@@ -230,6 +245,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]);