Snap for 9157512 from 98ab028002c083a84acfff83c7cf8b806b737d1c to mainline-tzdata3-release

Change-Id: Ib9ee871dee473d2a988ae92722269c3fa3ac673e
diff --git a/OWNERS b/OWNERS
index ffe9515..62b9704 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,5 @@
+mikemcternan@google.com
+ptosi@google.com
 # Default code reviewers picked from top 3 or more developers.
-# Please update this list if you find better candidates.
 szuweilin@google.com
 bowgotsai@google.com
-hridya@google.com
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
index c28fcc1..17ac7d6 100644
--- a/libfdt/fdt.c
+++ b/libfdt/fdt.c
@@ -134,16 +134,20 @@
 
 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
 {
-	unsigned absoffset = offset + fdt_off_dt_struct(fdt);
+	unsigned int uoffset = offset;
+	unsigned int absoffset = offset + fdt_off_dt_struct(fdt);
+
+	if (offset < 0)
+		return NULL;
 
 	if (!can_assume(VALID_INPUT))
-		if ((absoffset < offset)
+		if ((absoffset < uoffset)
 		    || ((absoffset + len) < absoffset)
 		    || (absoffset + len) > fdt_totalsize(fdt))
 			return NULL;
 
 	if (can_assume(LATEST) || fdt_version(fdt) >= 0x11)
-		if (((offset + len) < offset)
+		if (((uoffset + len) < uoffset)
 		    || ((offset + len) > fdt_size_dt_struct(fdt)))
 			return NULL;
 
@@ -176,12 +180,20 @@
 		break;
 
 	case FDT_PROP:
-		lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
+		lenp = fdt_offset_ptr(fdt, offset, sizeof(struct fdt_property) - FDT_TAGSIZE);
 		if (!can_assume(VALID_DTB) && !lenp)
 			return FDT_END; /* premature end */
-		/* skip-name offset, length and value */
-		offset += sizeof(struct fdt_property) - FDT_TAGSIZE
-			+ fdt32_to_cpu(*lenp);
+
+		/* skip name offset, length */
+		offset += sizeof(struct fdt_property) - FDT_TAGSIZE;
+
+		if (!can_assume(VALID_DTB)
+		    && !fdt_offset_ptr(fdt, offset, fdt32_to_cpu(*lenp)))
+			return FDT_END; /* premature end */
+
+		/* skip value */
+		offset += fdt32_to_cpu(*lenp);
+
 		if (!can_assume(LATEST) &&
 		    fdt_version(fdt) < 0x10 && fdt32_to_cpu(*lenp) >= 8 &&
 		    ((offset - fdt32_to_cpu(*lenp)) % 8) != 0)
@@ -197,7 +209,8 @@
 		return FDT_END;
 	}
 
-	if (!fdt_offset_ptr(fdt, startoffset, offset - startoffset))
+	if (!can_assume(VALID_DTB) && (offset <= startoffset
+	    || !fdt_offset_ptr(fdt, startoffset, offset - startoffset)))
 		return FDT_END; /* premature end */
 
 	*nextoffset = FDT_TAGALIGN(offset);
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index e03570a..67fb218 100644
--- a/libfdt/fdt_ro.c
+++ b/libfdt/fdt_ro.c
@@ -253,6 +253,12 @@
 
 	FDT_RO_PROBE(fdt);
 
+	if (namelen < 1)
+		return -FDT_ERR_BADPATH;
+
+	if (namelen < 1)
+		return -FDT_ERR_BADPATH;
+
 	/* see if we have an alias */
 	if (*path != '/') {
 		const char *q = memchr(path, '/', end - p);