diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2016-04-03 11:22:52 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2016-04-03 11:22:52 +0000 |
commit | 795937e6615917fee9bdcc4cba8aba427d21d57b (patch) | |
tree | 18326b7d23b87cd542c47c333bece4a29db1f411 /sys/dev | |
parent | 601117e2d9b9df75e6977447d3fd4563f1536702 (diff) |
The callers of fdt_next_node() expect it to return NULL if a next node
cannot be found. Due to implementation details, it used to return
a pointer to the next node, without checking if it actually exists.
Modify fdt_next_node() to only return a next node if it actually exists
and implement an internal skip_node() function that keeps the previous
behaviour.
ok mpi@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/ofw/fdt.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/sys/dev/ofw/fdt.c b/sys/dev/ofw/fdt.c index 6810fdddfbc..984c2b127b8 100644 --- a/sys/dev/ofw/fdt.c +++ b/sys/dev/ofw/fdt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdt.c,v 1.3 2016/03/17 14:10:29 mpi Exp $ */ +/* $OpenBSD: fdt.c,v 1.4 2016/04/03 11:22:51 patrick Exp $ */ /* * Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net> @@ -30,6 +30,7 @@ char *fdt_get_str(u_int32_t); void *skip_property(u_int32_t *); void *skip_props(u_int32_t *); void *skip_node_name(u_int32_t *); +void *skip_node(void *); void *fdt_parent_node_recurse(void *, void *); #ifdef DEBUG void fdt_print_node_recurse(void *, int); @@ -172,8 +173,30 @@ fdt_node_property(void *node, char *name, char **out) } /* - * Retrieves next node, skipping all the children nodes of the pointed node - * if passed 0 wil return first node of the tree (root) + * Retrieves next node, skipping all the children nodes of the pointed node, + * returns pointer to next node, no matter if it exists or not. + */ +void * +skip_node(void *node) +{ + u_int32_t *ptr = node; + + ptr++; + + ptr = skip_node_name(ptr); + ptr = skip_props(ptr); + + /* skip children */ + while (betoh32(*ptr) == FDT_NODE_BEGIN) + ptr = skip_node(ptr); + + return (ptr + 1); +} + +/* + * Retrieves next node, skipping all the children nodes of the pointed node, + * returns pointer to next node if exists, otherwise returns NULL. + * If passed 0 will return first node of the tree (root). */ void * fdt_next_node(void *node) @@ -185,7 +208,7 @@ fdt_next_node(void *node) ptr = node; - if (!node) { + if (node == NULL) { ptr = tree.tree; return (betoh32(*ptr) == FDT_NODE_BEGIN) ? ptr : NULL; } @@ -200,9 +223,15 @@ fdt_next_node(void *node) /* skip children */ while (betoh32(*ptr) == FDT_NODE_BEGIN) - ptr = fdt_next_node(ptr); + ptr = skip_node(ptr); + + if (betoh32(*ptr) != FDT_NODE_END) + return NULL; + + if (betoh32(*(ptr + 1)) != FDT_NODE_BEGIN) + return NULL; - return (betoh32(*ptr) == FDT_NODE_END) ? (ptr + 1) : NULL; + return (ptr + 1); } /* |