diff --git a/libfdt/fdt.c b/libfdt/fdt.c index 179168e..d6ce7c0 100644 --- a/libfdt/fdt.c +++ b/libfdt/fdt.c @@ -15,8 +15,10 @@ * that the given buffer contains what appears to be a flattened * device tree with sane information in its header. */ -int fdt_ro_probe_(const void *fdt) +int32_t fdt_ro_probe_(const void *fdt) { + uint32_t totalsize = fdt_totalsize(fdt); + if (fdt_magic(fdt) == FDT_MAGIC) { /* Complete tree */ if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) @@ -31,7 +33,10 @@ int fdt_ro_probe_(const void *fdt) return -FDT_ERR_BADMAGIC; } - return 0; + if (totalsize < INT32_MAX) + return totalsize; + else + return -FDT_ERR_TRUNCATED; } static int check_off_(uint32_t hdrsize, uint32_t totalsize, uint32_t off) diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c index 6fd9ec1..a5c2797 100644 --- a/libfdt/fdt_ro.c +++ b/libfdt/fdt_ro.c @@ -33,19 +33,20 @@ static int fdt_nodename_eq_(const void *fdt, int offset, const char *fdt_get_string(const void *fdt, int stroffset, int *lenp) { + int32_t totalsize = fdt_ro_probe_(fdt); uint32_t absoffset = stroffset + fdt_off_dt_strings(fdt); size_t len; int err; const char *s, *n; - err = fdt_ro_probe_(fdt); - if (err != 0) + err = totalsize; + if (totalsize < 0) goto fail; err = -FDT_ERR_BADOFFSET; - if (absoffset >= fdt_totalsize(fdt)) + if (absoffset >= totalsize) goto fail; - len = fdt_totalsize(fdt) - absoffset; + len = totalsize - absoffset; if (fdt_magic(fdt) == FDT_MAGIC) { if (stroffset < 0) @@ -288,7 +289,7 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len) const char *nameptr; int err; - if (((err = fdt_ro_probe_(fdt)) != 0) + if (((err = fdt_ro_probe_(fdt)) < 0) || ((err = fdt_check_node_offset_(fdt, nodeoffset)) < 0)) goto fail; diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h index 7830e55..741eeb3 100644 --- a/libfdt/libfdt_internal.h +++ b/libfdt/libfdt_internal.h @@ -11,11 +11,11 @@ #define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE)) int fdt_ro_probe_(const void *fdt); -#define FDT_RO_PROBE(fdt) \ - { \ - int err_; \ - if ((err_ = fdt_ro_probe_(fdt)) != 0) \ - return err_; \ +#define FDT_RO_PROBE(fdt) \ + { \ + int totalsize_; \ + if ((totalsize_ = fdt_ro_probe_(fdt)) < 0) \ + return totalsize_; \ } int fdt_check_node_offset_(const void *fdt, int offset);