From 661bb13788797a21529668ff61bb20f27e1632ee Mon Sep 17 00:00:00 2001
From: rmilecki <rmilecki@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Date: Thu, 12 Feb 2015 06:57:24 +0000
Subject: [PATCH] mtdsplit_uimage: more generic header verify function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Some devices have uImage headers after some extra headers (e.g. Edimax
devices). To support such cases our verify callback function should be
allowed to return header offset, not just a boolean value.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>


git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44412 3c298f89-4303-0410-b956-a3cf2f4a3e73
---
 .../drivers/mtd/mtdsplit/mtdsplit_uimage.c    | 37 +++++++++++++------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c
index 1df0ac1ae1..fa89f33ac0 100644
--- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_uimage.c
@@ -71,10 +71,16 @@ read_uimage_header(struct mtd_info *mtd, size_t offset,
 	return 0;
 }
 
+/**
+ * __mtdsplit_parse_uimage - scan partition and create kernel + rootfs parts
+ *
+ * @find_header: function to call for a block of data that will return offset
+ *      of a valid uImage header if found
+ */
 static int __mtdsplit_parse_uimage(struct mtd_info *master,
 				   struct mtd_partition **pparts,
 				   struct mtd_part_parser_data *data,
-				   bool (*verify)(struct uimage_header *hdr))
+				   ssize_t (*find_header)(u_char *buf, size_t len))
 {
 	struct mtd_partition *parts;
 	struct uimage_header *header;
@@ -106,11 +112,16 @@ static int __mtdsplit_parse_uimage(struct mtd_info *master,
 		if (ret)
 			continue;
 
-		if (!verify(header)) {
+		ret = find_header((u_char *)header, sizeof(*header));
+		if (ret < 0) {
 			pr_debug("no valid uImage found in \"%s\" at offset %llx\n",
 				 master->name, (unsigned long long) offset);
 			continue;
 		}
+		if (ret > 0) {
+			pr_warn("extra header offsets are not supported yet\n");
+			continue;
+		}
 
 		uimage_size = sizeof(*header) + be32_to_cpu(header->ih_size);
 		if ((offset + uimage_size) > master->size) {
@@ -189,28 +200,30 @@ err_free_parts:
 	return ret;
 }
 
-static bool uimage_verify_default(struct uimage_header *header)
+static ssize_t uimage_verify_default(u_char *buf, size_t len)
 {
+	struct uimage_header *header = (struct uimage_header *)buf;
+
 	/* default sanity checks */
 	if (be32_to_cpu(header->ih_magic) != IH_MAGIC) {
 		pr_debug("invalid uImage magic: %08x\n",
 			 be32_to_cpu(header->ih_magic));
-		return false;
+		return -EINVAL;
 	}
 
 	if (header->ih_os != IH_OS_LINUX) {
 		pr_debug("invalid uImage OS: %08x\n",
 			 be32_to_cpu(header->ih_os));
-		return false;
+		return -EINVAL;
 	}
 
 	if (header->ih_type != IH_TYPE_KERNEL) {
 		pr_debug("invalid uImage type: %08x\n",
 			 be32_to_cpu(header->ih_type));
-		return false;
+		return -EINVAL;
 	}
 
-	return true;
+	return 0;
 }
 
 static int
@@ -238,9 +251,11 @@ static struct mtd_part_parser uimage_generic_parser = {
 #define FW_MAGIC_WNDR3700	0x33373030
 #define FW_MAGIC_WNDR3700V2	0x33373031
 
-static bool uimage_verify_wndr3700(struct uimage_header *header)
+static ssize_t uimage_verify_wndr3700(u_char *buf, size_t len)
 {
+	struct uimage_header *header = (struct uimage_header *)buf;
 	uint8_t expected_type = IH_TYPE_FILESYSTEM;
+
 	switch be32_to_cpu(header->ih_magic) {
 	case FW_MAGIC_WNR612V2:
 	case FW_MAGIC_WNR1000V2:
@@ -254,14 +269,14 @@ static bool uimage_verify_wndr3700(struct uimage_header *header)
 		expected_type = IH_TYPE_KERNEL;
 		break;
 	default:
-		return false;
+		return -EINVAL;
 	}
 
 	if (header->ih_os != IH_OS_LINUX ||
 	    header->ih_type != expected_type)
-		return false;
+		return -EINVAL;
 
-	return true;
+	return 0;
 }
 
 static int
-- 
GitLab