Commit c909fec6 authored by Ivan Stepchenko's avatar Ivan Stepchenko Committed by Miquel Raynal
Browse files

mtd: lpddr_cmds: fix signed shifts in lpddr_cmds



There are several places where a value of type 'int' is shifted by
lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and
might reach 31 when QINFO reports a 2 GiB size - the maximum supported by
LPDDR(1) compliant chips. This may cause unexpected sign-extensions when
casting the integer value to the type of 'unsigned long'.

Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before
shifting so the computation is performed at the destination width.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: c6826471 ("[MTD] LPDDR Command set driver")
Signed-off-by: default avatarIvan Stepchenko <sid@itb.spb.ru>
Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
parent 1cce5a5e
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map)
		mutex_init(&shared[i].lock);
		for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) {
			*chip = lpddr->chips[i];
			chip->start += j << lpddr->chipshift;
			chip->start += (unsigned long)j << lpddr->chipshift;
			chip->oldstate = chip->state = FL_READY;
			chip->priv = &shared[i];
			/* those should be reset too since
@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
			break;

		if ((len + ofs - 1) >> lpddr->chipshift)
			thislen = (1<<lpddr->chipshift) - ofs;
			thislen = (1UL << lpddr->chipshift) - ofs;
		else
			thislen = len;
		/* get the chip */
@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len,
		len -= thislen;

		ofs = 0;
		last_end += 1 << lpddr->chipshift;
		last_end += 1UL << lpddr->chipshift;
		chipnum++;
		chip = &lpddr->chips[chipnum];
	}
@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len)
			break;

		if ((len + ofs - 1) >> lpddr->chipshift)
			thislen = (1<<lpddr->chipshift) - ofs;
			thislen = (1UL << lpddr->chipshift) - ofs;
		else
			thislen = len;