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
(cherry picked from commit 98c15b2bad1a277da43c65c642f8c3c3ee07bacc)
This commit is contained in:
Lee Jones 2022-03-11 14:19:59 +00:00 committed by Lee Jones
parent 7f04e0c309
commit 0840b18507

View File

@ -599,6 +599,7 @@ static void dm_bow_dtr(struct dm_target *ti)
struct bow_context *bc = (struct bow_context *) ti->private; struct bow_context *bc = (struct bow_context *) ti->private;
struct kobject *kobj; struct kobject *kobj;
mutex_lock(&bc->ranges_lock);
while (rb_first(&bc->ranges)) { while (rb_first(&bc->ranges)) {
struct bow_range *br = container_of(rb_first(&bc->ranges), struct bow_range *br = container_of(rb_first(&bc->ranges),
struct bow_range, node); struct bow_range, node);
@ -606,6 +607,8 @@ static void dm_bow_dtr(struct dm_target *ti)
rb_erase(&br->node, &bc->ranges); rb_erase(&br->node, &bc->ranges);
kfree(br); kfree(br);
} }
mutex_unlock(&bc->ranges_lock);
if (bc->workqueue) if (bc->workqueue)
destroy_workqueue(bc->workqueue); destroy_workqueue(bc->workqueue);
if (bc->bufio) if (bc->bufio)
@ -1182,6 +1185,7 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result,
return; return;
} }
mutex_lock(&bc->ranges_lock);
for (i = rb_first(&bc->ranges); i; i = rb_next(i)) { for (i = rb_first(&bc->ranges); i; i = rb_next(i)) {
struct bow_range *br = container_of(i, struct bow_range, node); struct bow_range *br = container_of(i, struct bow_range, node);
@ -1189,11 +1193,11 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result,
readable_type[br->type], readable_type[br->type],
(unsigned long long)br->sector); (unsigned long long)br->sector);
if (result >= end) if (result >= end)
return; goto unlock;
result += scnprintf(result, end - result, "\n"); result += scnprintf(result, end - result, "\n");
if (result >= end) if (result >= end)
return; goto unlock;
if (br->type == TRIMMED) if (br->type == TRIMMED)
++trimmed_range_count; ++trimmed_range_count;
@ -1215,19 +1219,22 @@ static void dm_bow_tablestatus(struct dm_target *ti, char *result,
if (!rb_next(i)) { if (!rb_next(i)) {
scnprintf(result, end - result, scnprintf(result, end - result,
"\nERROR: Last range not of type TOP"); "\nERROR: Last range not of type TOP");
return; goto unlock;
} }
if (br->sector > range_top(br)) { if (br->sector > range_top(br)) {
scnprintf(result, end - result, scnprintf(result, end - result,
"\nERROR: sectors out of order"); "\nERROR: sectors out of order");
return; goto unlock;
} }
} }
if (trimmed_range_count != trimmed_list_length) if (trimmed_range_count != trimmed_list_length)
scnprintf(result, end - result, scnprintf(result, end - result,
"\nERROR: not all trimmed ranges in trimmed list"); "\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, static void dm_bow_status(struct dm_target *ti, status_type_t type,