[rtems commit] libfdt: Fix undefined behaviour in fdt_offset_ptr()

Sebastian Huber sebh at rtems.org
Thu Jul 19 05:07:41 UTC 2018


Module:    rtems
Branch:    master
Commit:    87acb61eeab78ff031b0ffc0c12cdfaba04fc869
Changeset: http://git.rtems.org/rtems/commit/?id=87acb61eeab78ff031b0ffc0c12cdfaba04fc869

Author:    David Gibson <david at gibson.dropbear.id.au>
Date:      Thu Dec 17 17:19:11 2015 +1100

libfdt: Fix undefined behaviour in fdt_offset_ptr()

Using pointer arithmetic to generate a pointer outside a known object is,
technically, undefined behaviour in C.  Unfortunately, we were using that
in fdt_offset_ptr() to detect overflows.

To fix this we need to do our bounds / overflow checking on the offsets
before constructing pointers from them.

Reported-by: David Binderman <dcb314 at hotmail.com>
Signed-off-by: David Gibson <david at gibson.dropbear.id.au>

---

 cpukit/dtc/libfdt/fdt.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/cpukit/dtc/libfdt/fdt.c b/cpukit/dtc/libfdt/fdt.c
index 2ce6a44..22286a1 100644
--- a/cpukit/dtc/libfdt/fdt.c
+++ b/cpukit/dtc/libfdt/fdt.c
@@ -76,18 +76,19 @@ int fdt_check_header(const void *fdt)
 
 const void *fdt_offset_ptr(const void *fdt, int offset, unsigned int len)
 {
-	const char *p;
+	unsigned absoffset = offset + fdt_off_dt_struct(fdt);
+
+	if ((absoffset < offset)
+	    || ((absoffset + len) < absoffset)
+	    || (absoffset + len) > fdt_totalsize(fdt))
+		return NULL;
 
 	if (fdt_version(fdt) >= 0x11)
 		if (((offset + len) < offset)
 		    || ((offset + len) > fdt_size_dt_struct(fdt)))
 			return NULL;
 
-	p = _fdt_offset_ptr(fdt, offset);
-
-	if (p + len < p)
-		return NULL;
-	return p;
+	return _fdt_offset_ptr(fdt, offset);
 }
 
 uint32_t fdt_next_tag(const void *fdt, int startoffset, int *nextoffset)



More information about the vc mailing list