Skip to content

Commit 65d003c

Browse files
Ansuelmiquelraynal
authored andcommitted
mtd: parsers: qcom: Fix kernel panic on skipped partition
In the event of a skipped partition (case when the entry name is empty) the kernel panics in the cleanup function as the name entry is NULL. Rework the parser logic by first checking the real partition number and then allocate the space and set the data for the valid partitions. The logic was also fundamentally wrong as with a skipped partition, the parts number returned was incorrect by not decreasing it for the skipped partitions. Fixes: 803eb12 ("mtd: parsers: Add Qcom SMEM parser") Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20220116032211.9728-1-ansuelsmth@gmail.com
1 parent 079e6bd commit 65d003c

1 file changed

Lines changed: 19 additions & 12 deletions

File tree

drivers/mtd/parsers/qcomsmempart.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,11 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
5858
const struct mtd_partition **pparts,
5959
struct mtd_part_parser_data *data)
6060
{
61+
size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
62+
int ret, i, j, tmpparts, numparts = 0;
6163
struct smem_flash_pentry *pentry;
6264
struct smem_flash_ptable *ptable;
63-
size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
6465
struct mtd_partition *parts;
65-
int ret, i, numparts;
6666
char *name, *c;
6767

6868
if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS)
@@ -88,8 +88,8 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
8888
}
8989

9090
/* Ensure that # of partitions is less than the max we have allocated */
91-
numparts = le32_to_cpu(ptable->numparts);
92-
if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
91+
tmpparts = le32_to_cpu(ptable->numparts);
92+
if (tmpparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
9393
pr_err("Partition numbers exceed the max limit\n");
9494
return -EINVAL;
9595
}
@@ -117,11 +117,17 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
117117
return PTR_ERR(ptable);
118118
}
119119

120+
for (i = 0; i < tmpparts; i++) {
121+
pentry = &ptable->pentry[i];
122+
if (pentry->name[0] != '\0')
123+
numparts++;
124+
}
125+
120126
parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL);
121127
if (!parts)
122128
return -ENOMEM;
123129

124-
for (i = 0; i < numparts; i++) {
130+
for (i = 0, j = 0; i < tmpparts; i++) {
125131
pentry = &ptable->pentry[i];
126132
if (pentry->name[0] == '\0')
127133
continue;
@@ -136,24 +142,25 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
136142
for (c = name; *c != '\0'; c++)
137143
*c = tolower(*c);
138144

139-
parts[i].name = name;
140-
parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
141-
parts[i].mask_flags = pentry->attr;
142-
parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize;
145+
parts[j].name = name;
146+
parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
147+
parts[j].mask_flags = pentry->attr;
148+
parts[j].size = le32_to_cpu(pentry->length) * mtd->erasesize;
143149
pr_debug("%d: %s offs=0x%08x size=0x%08x attr:0x%08x\n",
144150
i, pentry->name, le32_to_cpu(pentry->offset),
145151
le32_to_cpu(pentry->length), pentry->attr);
152+
j++;
146153
}
147154

148155
pr_debug("SMEM partition table found: ver: %d len: %d\n",
149-
le32_to_cpu(ptable->version), numparts);
156+
le32_to_cpu(ptable->version), tmpparts);
150157
*pparts = parts;
151158

152159
return numparts;
153160

154161
out_free_parts:
155-
while (--i >= 0)
156-
kfree(parts[i].name);
162+
while (--j >= 0)
163+
kfree(parts[j].name);
157164
kfree(parts);
158165
*pparts = NULL;
159166

0 commit comments

Comments
 (0)