aboutsummaryrefslogtreecommitdiff
path: root/fdtdump.c
diff options
context:
space:
mode:
authorHeinrich Schuchardt <xypron.glpk@gmx.de>2016-12-22 00:59:06 +0100
committerDavid Gibson <david@gibson.dropbear.id.au>2016-12-27 09:44:17 +1100
commit0931cea3ba20d41013284c20b5a204dca002c058 (patch)
tree42a35c51af713588abcf81c9cb0f60b15a697f10 /fdtdump.c
parentf88865469b65455bdc4ebe7ad8601fafea9b8ef3 (diff)
downloaddtc-0931cea3ba20d41013284c20b5a204dca002c058.zip
dtc-0931cea3ba20d41013284c20b5a204dca002c058.tar.gz
dtc-0931cea3ba20d41013284c20b5a204dca002c058.tar.bz2
dtc: fdtdump: check fdt if not in scanning mode
Running fdtdump without scan mode for an invalid file often results in a segmentation fault because the fdt header is not checked. With the patch the header is checked both in scanning as well as in non-scanning mode. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: David Gibson <david@gibson.dropbear.id.au> [dwg: Removed unnecessary inline, changed type from int to bool] Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'fdtdump.c')
-rw-r--r--fdtdump.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fdtdump.c b/fdtdump.c
index a9a2484..194e9d6 100644
--- a/fdtdump.c
+++ b/fdtdump.c
@@ -16,6 +16,7 @@
#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))))
@@ -159,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;
@@ -204,12 +219,7 @@ int main(int argc, char *argv[])
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",
@@ -217,11 +227,12 @@ int main(int argc, char *argv[])
}
++p;
}
- if (!p || ((endp - p) < FDT_MAGIC_SIZE))
+ 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);