mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 10:01:39 -05:00
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: c68264711c ("[MTD] LPDDR Command set driver")
Signed-off-by: Ivan Stepchenko <sid@itb.spb.ru>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
committed by
Miquel Raynal
parent
1cce5a5eca
commit
c909fec69f
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user