aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrant Likely <grant.likely@linaro.org>2014-10-01 11:57:07 -0400
committerGrant Likely <grant.likely@linaro.org>2014-10-01 12:01:43 -0400
commite66c98c7a0eacc33a9369a3ec086740044eb986c (patch)
tree639990268861bd1aae22d93b6f92bbbd47768192
parentfe82dcec644244676d55a1384c958d5f67979adb (diff)
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: Grant Likely <grant.likely@linaro.org> Cc: Gaurav Minocha <gaurav.minocha.os@gmail.com>
-rw-r--r--drivers/of/selftest.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c
index a737cb5974de..883e60b04eb5 100644
--- a/drivers/of/selftest.c
+++ b/drivers/of/selftest.c
@@ -637,6 +637,8 @@ static int attach_node_and_children(struct device_node *np)
637 dup = np; 637 dup = np;
638 638
639 while (dup) { 639 while (dup) {
640 if (WARN_ON(last_node_index >= NO_OF_NODES))
641 return -EINVAL;
640 nodes[last_node_index++] = dup; 642 nodes[last_node_index++] = dup;
641 dup = dup->sibling; 643 dup = dup->sibling;
642 } 644 }
@@ -717,10 +719,6 @@ static void detach_node_and_children(struct device_node *np)
717{ 719{
718 while (np->child) 720 while (np->child)
719 detach_node_and_children(np->child); 721 detach_node_and_children(np->child);
720
721 while (np->sibling)
722 detach_node_and_children(np->sibling);
723
724 of_detach_node(np); 722 of_detach_node(np);
725} 723}
726 724
@@ -749,8 +747,7 @@ static void selftest_data_remove(void)
749 if (nodes[last_node_index]) { 747 if (nodes[last_node_index]) {
750 np = of_find_node_by_path(nodes[last_node_index]->full_name); 748 np = of_find_node_by_path(nodes[last_node_index]->full_name);
751 if (strcmp(np->full_name, "/aliases") != 0) { 749 if (strcmp(np->full_name, "/aliases") != 0) {
752 detach_node_and_children(np->child); 750 detach_node_and_children(np);
753 of_detach_node(np);
754 } else { 751 } else {
755 for_each_property_of_node(np, prop) { 752 for_each_property_of_node(np, prop) {
756 if (strcmp(prop->name, "testcase-alias") == 0) 753 if (strcmp(prop->name, "testcase-alias") == 0)