drivers: cpuidle: lpm-levels: Fix untrusted pointer dereference.

The list_for_each macro was not used correctly, where the intermediate
variable would be LIST_POISON, resulting in a untrusted pointer
dereference. Switch to using list_for_each_entry_safe to for safe
removal of a list entry.

Change-Id: I0e0fd5dd9f251b5093d6e9d6335387512ec59249
Signed-off-by: Mahesh Sivasubramanian <msivasub@codeaurora.org>
diff --git a/drivers/cpuidle/lpm-levels-of.c b/drivers/cpuidle/lpm-levels-of.c
index fec75b1..61c0ae8 100644
--- a/drivers/cpuidle/lpm-levels-of.c
+++ b/drivers/cpuidle/lpm-levels-of.c
@@ -739,26 +739,22 @@ static int parse_cpu_levels(struct device_node *node, struct lpm_cluster *c)
 
 void free_cluster_node(struct lpm_cluster *cluster)
 {
-	struct list_head *list;
 	struct lpm_cpu *cpu, *n;
-	int i;
+	struct lpm_cluster *cl, *m;
 
-	list_for_each(list, &cluster->child) {
-		struct lpm_cluster *n;
-
-		n = list_entry(list, typeof(*n), list);
-		list_del(list);
-		free_cluster_node(n);
+	list_for_each_entry_safe(cl, m, &cluster->child, list) {
+		list_del(&cl->list);
+		free_cluster_node(cl);
 	};
 
 	list_for_each_entry_safe(cpu, n, &cluster->cpu, list) {
-		struct lpm_cpu *cpu = list_entry(list, typeof(*cpu), list);
+		int i;
 
+		list_del(&cpu->list);
 		for (i = 0; i < cpu->nlevels; i++) {
 			kfree(cpu->levels[i].name);
 			cpu->levels[i].name = NULL;
 		}
-		list_del(list);
 	}
 }