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

Commit af2c6a4a authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

[TG3]: Fix array overrun in tg3_read_partno().



Use proper upper limits for the loops and check for all error
conditions.

The problem was noticed by Adrian Bunk.

Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 25f484a6
Loading
Loading
Loading
Loading
+12 −7
Original line number Diff line number Diff line
@@ -10212,7 +10212,7 @@ skip_phy_reset:
static void __devinit tg3_read_partno(struct tg3 *tp)
{
	unsigned char vpd_data[256];
	int i;
	unsigned int i;
	u32 magic;

	if (tg3_nvram_read_swab(tp, 0x0, &magic))
@@ -10258,9 +10258,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
	}

	/* Now parse and find the part number. */
	for (i = 0; i < 256; ) {
	for (i = 0; i < 254; ) {
		unsigned char val = vpd_data[i];
		int block_end;
		unsigned int block_end;

		if (val == 0x82 || val == 0x91) {
			i = (i + 3 +
@@ -10276,21 +10276,26 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
			     (vpd_data[i + 1] +
			      (vpd_data[i + 2] << 8)));
		i += 3;
		while (i < block_end) {

		if (block_end > 256)
			goto out_not_found;

		while (i < (block_end - 2)) {
			if (vpd_data[i + 0] == 'P' &&
			    vpd_data[i + 1] == 'N') {
				int partno_len = vpd_data[i + 2];

				if (partno_len > 24)
				i += 3;
				if (partno_len > 24 || (partno_len + i) > 256)
					goto out_not_found;

				memcpy(tp->board_part_number,
				       &vpd_data[i + 3],
				       partno_len);
				       &vpd_data[i], partno_len);

				/* Success. */
				return;
			}
			i += 3 + vpd_data[i + 2];
		}

		/* Part number not found. */