[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen staging] libfdt: Fix undefined behaviour in fdt_offset_ptr()



commit 66fb1406568c7e582dbd5ffd8f3b8a8350146960
Author:     David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
AuthorDate: Tue Mar 17 16:18:57 2020 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Tue Mar 17 16:18:57 2020 +0100

    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@xxxxxxxxxxx>
    Signed-off-by: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx>
    [upstream commit d0b3ab0a0f46ac929b4713da46f7fdcd893dd3bd]
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Julien Grall <jgrall@xxxxxxxxxx>
---
 xen/common/libfdt/fdt.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/xen/common/libfdt/fdt.c b/xen/common/libfdt/fdt.c
index d02f4bf5f3..bbc77177d9 100644
--- a/xen/common/libfdt/fdt.c
+++ b/xen/common/libfdt/fdt.c
@@ -74,18 +74,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)
--
generated by git-patchbot for /home/xen/git/xen.git#staging

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.