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");