diff options
author | gonzo <gonzo@FreeBSD.org> | 2017-05-09 19:54:33 +0000 |
---|---|---|
committer | gonzo <gonzo@FreeBSD.org> | 2017-05-09 19:54:33 +0000 |
commit | 4d315351e9fb14a39b2d95b87e1dde5aaa251598 (patch) | |
tree | ee0e7b31883c88646ee55a3cf10fd68e512f410f /contrib/dtc/fdtdump.c | |
parent | 557f7d447f32ca3aea8efb1091fabb542e3d6784 (diff) | |
download | FreeBSD-src-4d315351e9fb14a39b2d95b87e1dde5aaa251598.zip FreeBSD-src-4d315351e9fb14a39b2d95b87e1dde5aaa251598.tar.gz |
MFC r315009:
Merge from vendor branch importing dtc 1.4.3
Major new feature in this import is FDT overlay support
Diffstat (limited to 'contrib/dtc/fdtdump.c')
-rw-r--r-- | contrib/dtc/fdtdump.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/contrib/dtc/fdtdump.c b/contrib/dtc/fdtdump.c index 723770d..194e9d6 100644 --- a/contrib/dtc/fdtdump.c +++ b/contrib/dtc/fdtdump.c @@ -15,6 +15,9 @@ #include "util.h" +#define FDT_MAGIC_SIZE 4 +#define MAX_VERSION 17 + #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1)) #define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a)))) #define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4))) @@ -22,7 +25,7 @@ static const char *tagname(uint32_t tag) { static const char * const names[] = { -#define TN(t) [t] #t +#define TN(t) [t] = #t TN(FDT_BEGIN_NODE), TN(FDT_END_NODE), TN(FDT_PROP), @@ -88,7 +91,7 @@ static void dump_blob(void *blob, bool debug) if (addr == 0 && size == 0) break; - printf("/memreserve/ %llx %llx;\n", + printf("/memreserve/ %#llx %#llx;\n", (unsigned long long)addr, (unsigned long long)size); } @@ -157,6 +160,20 @@ static const char * const usage_opts_help[] = { USAGE_COMMON_OPTS_HELP }; +static bool valid_header(char *p, off_t len) +{ + if (len < sizeof(struct fdt_header) || + fdt_magic(p) != FDT_MAGIC || + fdt_version(p) > MAX_VERSION || + fdt_last_comp_version(p) >= MAX_VERSION || + fdt_totalsize(p) >= len || + fdt_off_dt_struct(p) >= len || + fdt_off_dt_strings(p) >= len) + return 0; + else + return 1; +} + int main(int argc, char *argv[]) { int opt; @@ -188,26 +205,21 @@ int main(int argc, char *argv[]) /* try and locate an embedded fdt in a bigger blob */ if (scan) { - unsigned char smagic[4]; + unsigned char smagic[FDT_MAGIC_SIZE]; char *p = buf; char *endp = buf + len; fdt_set_magic(smagic, FDT_MAGIC); /* poor man's memmem */ - while (true) { - p = memchr(p, smagic[0], endp - p - 4); + while ((endp - p) >= FDT_MAGIC_SIZE) { + p = memchr(p, smagic[0], endp - p - FDT_MAGIC_SIZE); if (!p) break; if (fdt_magic(p) == FDT_MAGIC) { /* try and validate the main struct */ off_t this_len = endp - p; - fdt32_t max_version = 17; - if (fdt_version(p) <= max_version && - fdt_last_comp_version(p) < max_version && - fdt_totalsize(p) < this_len && - fdt_off_dt_struct(p) < this_len && - fdt_off_dt_strings(p) < this_len) + if (valid_header(p, this_len)) break; if (debug) printf("%s: skipping fdt magic at offset %#zx\n", @@ -215,11 +227,12 @@ int main(int argc, char *argv[]) } ++p; } - if (!p) + if (!p || endp - p < sizeof(struct fdt_header)) die("%s: could not locate fdt magic\n", file); printf("%s: found fdt at offset %#zx\n", file, p - buf); buf = p; - } + } else if (!valid_header(buf, len)) + die("%s: header is not valid\n", file); dump_blob(buf, debug); |