]> git.karo-electronics.de Git - linux-beck.git/commitdiff
mtd: bcm63xxpart: Null terminate and validate conversion of flash strings
authorSimon Arlott <simon@fire.lp0.eu>
Sun, 13 Dec 2015 22:51:37 +0000 (22:51 +0000)
committerBrian Norris <computersforpeace@gmail.com>
Fri, 12 Feb 2016 18:34:16 +0000 (10:34 -0800)
Strings read from flash could be missing null termination characters, or
not contain valid integers.

Null terminate the strings and check for errors when converting them to
integers.

Also validate that the addresses are at least BCM963XX_EXTENDED_SIZE
because this will be subtracted from them.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/bcm63xxpart.c

index eafbf521a547c4fb79f99746188451dd3eda4e31..41aa2021cb6d64877be36b50617fe37cf5e0ef80 100644 (file)
@@ -169,10 +169,39 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
        /* Get the tag */
        ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf);
        if (!ret) {
-               sscanf(buf->flash_image_start, "%u", &rootfsaddr);
-               sscanf(buf->kernel_address, "%u", &kerneladdr);
-               sscanf(buf->kernel_length, "%u", &kernellen);
-               sscanf(buf->total_length, "%u", &totallen);
+               STR_NULL_TERMINATE(buf->flash_image_start);
+               if (kstrtouint(buf->flash_image_start, 10, &rootfsaddr) ||
+                               rootfsaddr < BCM963XX_EXTENDED_SIZE) {
+                       pr_err("invalid rootfs address: %*ph\n",
+                               sizeof(buf->flash_image_start),
+                               buf->flash_image_start);
+                       goto invalid_tag;
+               }
+
+               STR_NULL_TERMINATE(buf->kernel_address);
+               if (kstrtouint(buf->kernel_address, 10, &kerneladdr) ||
+                               kerneladdr < BCM963XX_EXTENDED_SIZE) {
+                       pr_err("invalid kernel address: %*ph\n",
+                               sizeof(buf->kernel_address),
+                               buf->kernel_address);
+                       goto invalid_tag;
+               }
+
+               STR_NULL_TERMINATE(buf->kernel_length);
+               if (kstrtouint(buf->kernel_length, 10, &kernellen)) {
+                       pr_err("invalid kernel length: %*ph\n",
+                               sizeof(buf->kernel_length),
+                               buf->kernel_length);
+                       goto invalid_tag;
+               }
+
+               STR_NULL_TERMINATE(buf->total_length);
+               if (kstrtouint(buf->total_length, 10, &totallen)) {
+                       pr_err("invalid total length: %*ph\n",
+                               sizeof(buf->total_length),
+                               buf->total_length);
+                       goto invalid_tag;
+               }
 
                kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE;
                rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE;
@@ -188,6 +217,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
                        rootfslen = spareaddr - rootfsaddr;
                }
        } else if (ret > 0) {
+invalid_tag:
                kernellen = 0;
                rootfslen = 0;
                rootfsaddr = 0;