platform: msm_shared: change location of integer overflow checks

Integer overflow in fdt header removed in open source library,
added them in dev_tree.c file.

Change-Id: I5649ff5c24cdb6b60f546417555f38691cd1005a
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index c43b83e..15e66e4 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -70,19 +70,6 @@
 	} else {
 		return -FDT_ERR_BADMAGIC;
 	}
-
-	if (fdt_off_dt_struct(fdt) > (UINT_MAX - fdt_size_dt_struct(fdt)))
-		return FDT_ERR_BADOFFSET;
-
-	if (fdt_off_dt_strings(fdt) > (UINT_MAX -  fdt_size_dt_strings(fdt)))
-		return FDT_ERR_BADOFFSET;
-
-	if ((fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt)) > fdt_totalsize(fdt))
-		return FDT_ERR_BADOFFSET;
-
-	if ((fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)) > fdt_totalsize(fdt))
-		return FDT_ERR_BADOFFSET;
-
 	return 0;
 }
 
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 5c3d16a..40c24a4 100755
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -60,6 +60,32 @@
  */
 extern int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
 
+int fdt_check_header_ext(const void *fdt)
+{
+	uintptr_t fdt_start, fdt_end;
+	fdt_start = (uintptr_t)fdt;
+	if(fdt_start + fdt_totalsize(fdt) < fdt_start)
+	{
+		dprintf(CRITICAL,"Integer over in fdt header %s\t%d",__func__,__LINE__);
+		return FDT_ERR_BADOFFSET;
+	}
+	fdt_end = fdt_start + fdt_totalsize(fdt);
+
+	if (((uint64_t)fdt_start + (uint64_t)fdt_off_dt_struct(fdt) + (uint64_t)fdt_size_dt_struct(fdt)) > UINT_MAX)
+		return FDT_ERR_BADOFFSET;
+
+	if ((fdt_start + fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt)) > fdt_end)
+		return FDT_ERR_BADOFFSET;
+
+	if (((uint64_t)fdt_start + (uint64_t)fdt_off_dt_strings(fdt) + (uint64_t)fdt_size_dt_strings(fdt)) > UINT_MAX)
+		return FDT_ERR_BADOFFSET;
+
+	if ((fdt_start + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)) > fdt_end)
+		return FDT_ERR_BADOFFSET;
+
+	return 0;
+}
+
 /* Returns soc version if platform id and hardware id matches
    otherwise return 0xFFFFFFFF */
 #define INVALID_SOC_REV_ID 0XFFFFFFFF
@@ -454,6 +480,7 @@
 		 * and operate on it separately */
 		memcpy(&dtb_hdr, dtb, sizeof(struct fdt_header));
 		if (fdt_check_header((const void *)&dtb_hdr) != 0 ||
+		    fdt_check_header_ext((const void *)&dtb_hdr) != 0 ||
 		    ((uintptr_t)dtb + (uintptr_t)fdt_totalsize((const void *)&dtb_hdr) < (uintptr_t)dtb) ||
 			((uintptr_t)dtb + (uintptr_t)fdt_totalsize((const void *)&dtb_hdr) > (uintptr_t)kernel_end))
 			break;
@@ -1262,7 +1289,7 @@
 	uint32_t offset;
 
 	/* Check the device tree header */
-	ret = fdt_check_header(fdt);
+	ret = fdt_check_header(fdt) || fdt_check_header_ext(fdt);
 	if (ret)
 	{
 		dprintf(CRITICAL, "Invalid device tree header \n");