ANDROID: dm-bow: Protect Ranges fetched and erased from the RB tree

Bug: 195565510
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Change-Id: Ic8134eb902aa7d929e3121b2f69b1d258f570652
diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c
index cfd1fa63..2e95d61 100644
--- a/drivers/md/dm-bow.c
+++ b/drivers/md/dm-bow.c
@@ -599,6 +599,7 @@
 	struct bow_context *bc = (struct bow_context *) ti->private;
 	struct kobject *kobj;
 
+	mutex_lock(&bc->ranges_lock);
 	while (rb_first(&bc->ranges)) {
 		struct bow_range *br = container_of(rb_first(&bc->ranges),
 						    struct bow_range, node);
@@ -606,6 +607,8 @@
 		rb_erase(&br->node, &bc->ranges);
 		kfree(br);
 	}
+	mutex_unlock(&bc->ranges_lock);
+
 	if (bc->workqueue)
 		destroy_workqueue(bc->workqueue);
 	if (bc->bufio)
@@ -1181,6 +1184,7 @@
 		return;
 	}
 
+	mutex_lock(&bc->ranges_lock);
 	for (i = rb_first(&bc->ranges); i; i = rb_next(i)) {
 		struct bow_range *br = container_of(i, struct bow_range, node);
 
@@ -1188,11 +1192,11 @@
 				    readable_type[br->type],
 				    (unsigned long long)br->sector);
 		if (result >= end)
-			return;
+			goto unlock;
 
 		result += scnprintf(result, end - result, "\n");
 		if (result >= end)
-			return;
+			goto unlock;
 
 		if (br->type == TRIMMED)
 			++trimmed_range_count;
@@ -1214,19 +1218,22 @@
 		if (!rb_next(i)) {
 			scnprintf(result, end - result,
 				  "\nERROR: Last range not of type TOP");
-			return;
+			goto unlock;
 		}
 
 		if (br->sector > range_top(br)) {
 			scnprintf(result, end - result,
 				  "\nERROR: sectors out of order");
-			return;
+			goto unlock;
 		}
 	}
 
 	if (trimmed_range_count != trimmed_list_length)
 		scnprintf(result, end - result,
 			  "\nERROR: not all trimmed ranges in trimmed list");
+
+unlock:
+	mutex_unlock(&bc->ranges_lock);
 }
 
 static void dm_bow_status(struct dm_target *ti, status_type_t type,