From c4a17c8dd492b106846abb443c071be65ca6e484 Mon Sep 17 00:00:00 2001
From: vijay kumar <vpendo@codeaurora.org>
Date: Mon, 11 Aug 2014 17:17:59 +0530
Subject: [PATCH] scripts/dtc/libfdt: add integer overflow checks

This patch applies the same changes in the original commit
below to the dtc to keep both sources in sync.

original commit:
    lib: fdt: add integer overflow checks

    added integer overflow checks to avoid buffer over reads/write
    while using the fdt header fields.

    CRs-fixed: 705078.
    Change-Id: I062ee9e0610eeeeea32dd95695b18aa9dbca06ea

Bug: 19136881
Signed-off-by: Patrick Tjin <pattjin@google.com>
---
 scripts/dtc/libfdt/fdt_rw.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/scripts/dtc/libfdt/fdt_rw.c b/scripts/dtc/libfdt/fdt_rw.c
index 8e7ec4cb7bcd..05d08d9e834a 100644
--- a/scripts/dtc/libfdt/fdt_rw.c
+++ b/scripts/dtc/libfdt/fdt_rw.c
@@ -388,20 +388,31 @@ static void _fdt_packblocks(const char *old, char *new,
 
 int fdt_open_into(const void *fdt, void *buf, int bufsize)
 {
-	int err;
-	int mem_rsv_size, struct_size;
-	int newsize;
+	int err = -1;
+	uint32_t mem_rsv_size;
+	int struct_size;
+	uint32_t newsize;
 	const char *fdtstart = fdt;
-	const char *fdtend = fdtstart + fdt_totalsize(fdt);
+	const char *fdtend = NULL;
 	char *tmp;
 
+	if (fdtstart + fdt_totalsize(fdt) < fdtstart) {
+		return err;
+	}
+	fdtend = fdtstart + fdt_totalsize(fdt);
 	FDT_CHECK_HEADER(fdt);
 
+	if ((fdt_num_mem_rsv(fdt)+1) > (UINT_MAX / sizeof(struct fdt_reserve_entry)))  {
+		return err;
+	}
+
 	mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
 		* sizeof(struct fdt_reserve_entry);
 
 	if (fdt_version(fdt) >= 17) {
 		struct_size = fdt_size_dt_struct(fdt);
+			if (struct_size < 0)
+				return struct_size;
 	} else {
 		struct_size = 0;
 		while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
@@ -418,16 +429,22 @@ int fdt_open_into(const void *fdt, void *buf, int bufsize)
 		fdt_set_totalsize(buf, bufsize);
 		return 0;
 	}
+	if (((uint64_t)FDT_ALIGN(sizeof(struct fdt_header), 8) + (uint64_t)mem_rsv_size \
+                + (uint64_t)struct_size + (uint64_t)fdt_size_dt_strings(fdt)) > UINT_MAX) {
+		return (err = -1);
+	}
 
 	/* Need to reorder */
 	newsize = FDT_ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
 		+ struct_size + fdt_size_dt_strings(fdt);
-
 	if (bufsize < newsize)
 		return -FDT_ERR_NOSPACE;
 
 	/* First attempt to build converted tree at beginning of buffer */
 	tmp = buf;
+	if (((tmp + newsize) < tmp) || ((buf + bufsize) < buf)) {
+		return (err = -1);
+	}
 	/* But if that overlaps with the old tree... */
 	if (((tmp + newsize) > fdtstart) && (tmp < fdtend)) {
 		/* Try right after the old tree instead */
-- 
GitLab