ipq806x: add fixes for smem parser
authorAnsuel Smith <ansuelsmth@gmail.com>
Sun, 16 Jan 2022 03:25:28 +0000 (04:25 +0100)
committerZoltan HERPAI <wigyori@uid0.hu>
Thu, 3 Mar 2022 14:00:49 +0000 (15:00 +0100)
Add 2 fixes for smem parser to handle corner case and
a memory leak.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
target/linux/ipq806x/patches-5.15/104-1-mtd-parsers-qcom-Fix-kernel-panic-on-skipped-partiti.patch [new file with mode: 0644]
target/linux/ipq806x/patches-5.15/104-2-mtd-parsers-qcom-Fix-missing-free-for-pparts-in-clea.patch [new file with mode: 0644]

diff --git a/target/linux/ipq806x/patches-5.15/104-1-mtd-parsers-qcom-Fix-kernel-panic-on-skipped-partiti.patch b/target/linux/ipq806x/patches-5.15/104-1-mtd-parsers-qcom-Fix-kernel-panic-on-skipped-partiti.patch
new file mode 100644 (file)
index 0000000..686d8f0
--- /dev/null
@@ -0,0 +1,104 @@
+From 85cf2c8eab0a231a40394aefbdb16f5abcb11a97 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 16 Jan 2022 04:07:27 +0100
+Subject: [PATCH 1/2] 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>
+---
+ drivers/mtd/parsers/qcomsmempart.c | 31 ++++++++++++++++++------------
+ 1 file changed, 19 insertions(+), 12 deletions(-)
+
+diff --git a/drivers/mtd/parsers/qcomsmempart.c b/drivers/mtd/parsers/qcomsmempart.c
+index 06a818cd2433..f4fc7635c1f3 100644
+--- a/drivers/mtd/parsers/qcomsmempart.c
++++ b/drivers/mtd/parsers/qcomsmempart.c
+@@ -58,11 +58,11 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
+                              const struct mtd_partition **pparts,
+                              struct mtd_part_parser_data *data)
+ {
++      size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
++      int ret, i, j, tmpparts, numparts = 0;
+       struct smem_flash_pentry *pentry;
+       struct smem_flash_ptable *ptable;
+-      size_t len = SMEM_FLASH_PTABLE_HDR_LEN;
+       struct mtd_partition *parts;
+-      int ret, i, numparts;
+       char *name, *c;
+       if (IS_ENABLED(CONFIG_MTD_SPI_NOR_USE_4K_SECTORS)
+@@ -87,8 +87,8 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
+       }
+       /* Ensure that # of partitions is less than the max we have allocated */
+-      numparts = le32_to_cpu(ptable->numparts);
+-      if (numparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
++      tmpparts = le32_to_cpu(ptable->numparts);
++      if (tmpparts > SMEM_FLASH_PTABLE_MAX_PARTS_V4) {
+               pr_err("Partition numbers exceed the max limit\n");
+               return -EINVAL;
+       }
+@@ -116,11 +116,17 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
+               return PTR_ERR(ptable);
+       }
++      for (i = 0; i < tmpparts; i++) {
++              pentry = &ptable->pentry[i];
++              if (pentry->name[0] != '\0')
++                      numparts++;
++      }
++
+       parts = kcalloc(numparts, sizeof(*parts), GFP_KERNEL);
+       if (!parts)
+               return -ENOMEM;
+-      for (i = 0; i < numparts; i++) {
++      for (i = 0, j = 0; i < tmpparts; i++) {
+               pentry = &ptable->pentry[i];
+               if (pentry->name[0] == '\0')
+                       continue;
+@@ -135,24 +141,25 @@ static int parse_qcomsmem_part(struct mtd_info *mtd,
+               for (c = name; *c != '\0'; c++)
+                       *c = tolower(*c);
+-              parts[i].name = name;
+-              parts[i].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
+-              parts[i].mask_flags = pentry->attr;
+-              parts[i].size = le32_to_cpu(pentry->length) * mtd->erasesize;
++              parts[j].name = name;
++              parts[j].offset = le32_to_cpu(pentry->offset) * mtd->erasesize;
++              parts[j].mask_flags = pentry->attr;
++              parts[j].size = 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);
++              j++;
+       }
+       pr_debug("SMEM partition table found: ver: %d len: %d\n",
+-               le32_to_cpu(ptable->version), numparts);
++               le32_to_cpu(ptable->version), tmpparts);
+       *pparts = parts;
+       return numparts;
+ out_free_parts:
+-      while (--i >= 0)
+-              kfree(parts[i].name);
++      while (--j >= 0)
++              kfree(parts[j].name);
+       kfree(parts);
+       *pparts = NULL;
+-- 
+2.33.1
+
diff --git a/target/linux/ipq806x/patches-5.15/104-2-mtd-parsers-qcom-Fix-missing-free-for-pparts-in-clea.patch b/target/linux/ipq806x/patches-5.15/104-2-mtd-parsers-qcom-Fix-missing-free-for-pparts-in-clea.patch
new file mode 100644 (file)
index 0000000..29fe34c
--- /dev/null
@@ -0,0 +1,32 @@
+From 0917995af3ad71ccaf41c73ad8fbf2b18a076a91 Mon Sep 17 00:00:00 2001
+From: Ansuel Smith <ansuelsmth@gmail.com>
+Date: Sun, 16 Jan 2022 04:14:01 +0100
+Subject: [PATCH 2/2] mtd: parsers: qcom: Fix missing free for pparts in
+ cleanup
+
+Mtdpart doesn't free pparts when a cleanup function is declared.
+Add missing free for pparts in cleanup function for smem to fix the
+leak.
+
+Fixes: 10f3b4d79958 ("mtd: parsers: qcom: Fix leaking of partition name")
+Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
+---
+ drivers/mtd/parsers/qcomsmempart.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/drivers/mtd/parsers/qcomsmempart.c b/drivers/mtd/parsers/qcomsmempart.c
+index f4fc7635c1f3..32ddfea70142 100644
+--- a/drivers/mtd/parsers/qcomsmempart.c
++++ b/drivers/mtd/parsers/qcomsmempart.c
+@@ -173,6 +173,8 @@ static void parse_qcomsmem_cleanup(const struct mtd_partition *pparts,
+       for (i = 0; i < nr_parts; i++)
+               kfree(pparts[i].name);
++
++      kfree(pparts);
+ }
+ static const struct of_device_id qcomsmem_of_match_table[] = {
+-- 
+2.33.1
+