Commit e66c98c7 authored by Grant Likely's avatar Grant Likely

of: Fix NULL dereference in selftest removal code

The selftest code removes its testcase data from the live tree when
exiting, but if the testcases data tree contains an empty child of the
root, then it causes an oops due to a NULL dereference. The reason is
that the code tries to directly dereference the child pointer without
checking first if a child is actually there.

The solution is to pass the parent node into detach_node_and_children()
instead of trying to pass the child. This required removing the code
that attempts to remove all of the sibling nodes in
detach_node_and_children(), which was never sensible in the first place.

At the same time add a check to make sure the bounds of the nodes list
are not exceeded by the testdata tree. If they are then abort.
Signed-off-by: default avatarGrant Likely <grant.likely@linaro.org>
Cc: Gaurav Minocha <gaurav.minocha.os@gmail.com>
parent fe82dcec
...@@ -637,6 +637,8 @@ static int attach_node_and_children(struct device_node *np) ...@@ -637,6 +637,8 @@ static int attach_node_and_children(struct device_node *np)
dup = np; dup = np;
while (dup) { while (dup) {
if (WARN_ON(last_node_index >= NO_OF_NODES))
return -EINVAL;
nodes[last_node_index++] = dup; nodes[last_node_index++] = dup;
dup = dup->sibling; dup = dup->sibling;
} }
...@@ -717,10 +719,6 @@ static void detach_node_and_children(struct device_node *np) ...@@ -717,10 +719,6 @@ static void detach_node_and_children(struct device_node *np)
{ {
while (np->child) while (np->child)
detach_node_and_children(np->child); detach_node_and_children(np->child);
while (np->sibling)
detach_node_and_children(np->sibling);
of_detach_node(np); of_detach_node(np);
} }
...@@ -749,8 +747,7 @@ static void selftest_data_remove(void) ...@@ -749,8 +747,7 @@ static void selftest_data_remove(void)
if (nodes[last_node_index]) { if (nodes[last_node_index]) {
np = of_find_node_by_path(nodes[last_node_index]->full_name); np = of_find_node_by_path(nodes[last_node_index]->full_name);
if (strcmp(np->full_name, "/aliases") != 0) { if (strcmp(np->full_name, "/aliases") != 0) {
detach_node_and_children(np->child); detach_node_and_children(np);
of_detach_node(np);
} else { } else {
for_each_property_of_node(np, prop) { for_each_property_of_node(np, prop) {
if (strcmp(prop->name, "testcase-alias") == 0) if (strcmp(prop->name, "testcase-alias") == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment