summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2015-12-17 17:19:11 +1100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-07-19 07:01:08 +0200
commit87acb61eeab78ff031b0ffc0c12cdfaba04fc869 (patch)
treeea1c07989e6bea27cd6b3efb6a729b2ab2e3c1b9
parentlibfdt: check for potential overrun in _fdt_splice() (diff)
downloadrtems-87acb61eeab78ff031b0ffc0c12cdfaba04fc869.tar.bz2
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@hotmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
-rw-r--r--cpukit/dtc/libfdt/fdt.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/cpukit/dtc/libfdt/fdt.c b/cpukit/dtc/libfdt/fdt.c
index 2ce6a44179..22286a1aae 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)