mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
mtd: parsers: qcom: fix offset/size overflow on large partitions
In parse_qcomsmem_part() the partition offset and size are computed as
parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
parts[j].size = le32_to_cpu(pentry->length) * mtd->erasesize;
Both le32_to_cpu() and mtd->erasesize are 32-bit (u32). The multiply is
therefore evaluated in 32-bit arithmetic and the product is truncated to
32 bits before being widened and stored into the 64-bit (u64)
parts[j].offset / parts[j].size fields, so the 64-bit destinations are
never used at their full width.
The SMEM partition table is firmware-provided and the per-entry offset
and length are not bounds-checked against the device geometry (only
numparts is capped). On a sufficiently large flash, a partition whose
(offset|length) * erasesize is >= 2^32 gets a silently truncated
offset/size and is mapped to the wrong region of the master MTD, which
can overlap or extend into an unintended area.
Cast one operand to u64 so the multiplication is performed in 64-bit and
the result fits the 64-bit fields without truncation.
Found by static analysis tool CodeQL.
Fixes: 803eb124e1 ("mtd: parsers: Add Qcom SMEM parser")
Cc: stable@vger.kernel.org
Assisted-by: LLM codeql
Signed-off-by: Weigang He <geoffreyhe2@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
This commit is contained in:
parent
112a666bd8
commit
2f7fa8d906
|
|
@ -143,9 +143,9 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
|
|||
*c = tolower(*c);
|
||||
|
||||
parts[j].name = name;
|
||||
parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
|
||||
parts[j].offset = (u64)le32_to_cpu(pentry->offset) * mtd->erasesize;
|
||||
parts[j].mask_flags = pentry->attr;
|
||||
parts[j].size = le32_to_cpu(pentry->length) * mtd->erasesize;
|
||||
parts[j].size = (u64)le32_to_cpu(pentry->length) * mtd->erasesize;
|
||||
pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
|
||||
i, pentry->name, le32_to_cpu(pentry->offset),
|
||||
le32_to_cpu(pentry->length), pentry->attr);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user