From e5f309b277075f8e39639847892a068e7e008464 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Fri, 11 Mar 2022 14:19:59 +0000 Subject: [PATCH] ANDROID: dm-bow: Protect Ranges fetched and erased from the RB tree Bug: 195565510 Signed-off-by: Lee Jones (cherry picked from commit 98c15b2bad1a277da43c65c642f8c3c3ee07bacc) Signed-off-by: Lee Jones (cherry picked from https://android-review.googlesource.com/q/commit:5188b662614e86d094e09571e5853f910e9c9404) Merged-In: Ic8134eb902aa7d929e3121b2f69b1d258f570652 Change-Id: Ic8134eb902aa7d929e3121b2f69b1d258f570652 --- drivers/md/dm-bow.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/md/dm-bow.c b/drivers/md/dm-bow.c index a9764ea8940f..e12b8f986686 100644 --- a/drivers/md/dm-bow.c +++ b/drivers/md/dm-bow.c @@ -612,6 +612,7 @@ static void dm_bow_dtr(struct dm_target *ti) wait_for_completion(dm_get_completion_from_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); @@ -619,6 +620,7 @@ static void dm_bow_dtr(struct dm_target *ti) rb_erase(&br->node, &bc->ranges); kfree(br); } + mutex_unlock(&bc->ranges_lock); mutex_destroy(&bc->ranges_lock); kfree(bc->log_sector); @@ -1191,6 +1193,7 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result, 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); @@ -1198,11 +1201,11 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result, 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; @@ -1224,19 +1227,22 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result, 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,