summaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorSimon Arlott <simon@fire.lp0.eu>2015-12-13 23:51:37 +0100
committerBrian Norris <computersforpeace@gmail.com>2016-02-12 19:34:16 +0100
commit2c4fd433fb934c7d5ed02113a5eaa3edb42ea10b (patch)
treea3a0427b29bc527c87ed525a4a57879e0cb05ea2 /drivers/mtd
parentmtd: bcm63xxpart: Extract read of image tag to separate function (diff)
downloadlinux-2c4fd433fb934c7d5ed02113a5eaa3edb42ea10b.tar.xz
linux-2c4fd433fb934c7d5ed02113a5eaa3edb42ea10b.zip
mtd: bcm63xxpart: Null terminate and validate conversion of flash strings
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>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/bcm63xxpart.c38
1 files changed, 34 insertions, 4 deletions
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index eafbf521a547..41aa2021cb6d 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -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;