[Devel] [PATCH RH8] dm-ploop: Fix use-after-free in ploop_grow_relocate_cluster()

Kirill Tkhai ktkhai at virtuozzo.com
Tue Aug 17 18:36:17 MSK 2021


piwb is freed on last put_piwb(), so we can't use it to get
bi_status of async wb.

So, we introduce a new pointer to store bi_status.

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
 drivers/md/dm-ploop-cmd.c |    8 ++++++--
 drivers/md/dm-ploop-map.c |    6 +++++-
 drivers/md/dm-ploop.h     |    3 ++-
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index e313619c95e3..3ba866cb0ec0 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -282,6 +282,7 @@ static int ploop_grow_relocate_cluster(struct ploop *ploop,
 	struct ploop_index_wb *piwb;
 	u32 new_dst, clu, dst_clu;
 	struct completion comp;
+	blk_status_t bi_status;
 	struct md_page *md;
 	bool is_locked;
 	int ret = 0;
@@ -322,11 +323,12 @@ static int ploop_grow_relocate_cluster(struct ploop *ploop,
 	ploop_make_md_wb(ploop, md);
 	init_completion(&comp);
 	piwb->comp = &comp;
+	piwb->comp_bi_status = &bi_status;
 	/* Write new index on disk */
 	ploop_index_wb_submit(ploop, piwb);
 	wait_for_completion(&comp);
 
-	ret = blk_status_to_errno(piwb->bi_status);
+	ret = blk_status_to_errno(bi_status);
 	if (ret)
 		goto out;
 
@@ -356,6 +358,7 @@ static int ploop_grow_update_header(struct ploop *ploop,
 	struct ploop_index_wb *piwb;
 	u32 nr_be, offset, clus;
 	struct completion comp;
+	blk_status_t bi_status;
 	struct md_page *md;
 	u64 sectors;
 	int ret;
@@ -381,10 +384,11 @@ static int ploop_grow_update_header(struct ploop *ploop,
 	ploop_make_md_wb(ploop, md);
 	init_completion(&comp);
 	piwb->comp = &comp;
+	piwb->comp_bi_status = &bi_status;
 	ploop_index_wb_submit(ploop, piwb);
 	wait_for_completion(&comp);
 
-	ret = blk_status_to_errno(piwb->bi_status);
+	ret = blk_status_to_errno(bi_status);
 	if (!ret) {
 		/* Now update our cached page */
 		hdr = kmap_atomic(cmd->resize.md0->page);
diff --git a/drivers/md/dm-ploop-map.c b/drivers/md/dm-ploop-map.c
index 6b59a9c8620a..67d61bd757bd 100644
--- a/drivers/md/dm-ploop-map.c
+++ b/drivers/md/dm-ploop-map.c
@@ -45,6 +45,7 @@ void ploop_index_wb_init(struct ploop_index_wb *piwb, struct ploop *ploop)
 {
 	piwb->ploop = ploop;
 	piwb->comp = NULL;
+	piwb->comp_bi_status = NULL;
 	spin_lock_init(&piwb->lock);
 	piwb->md = NULL;
 	piwb->bat_page = NULL;
@@ -849,8 +850,11 @@ static void put_piwb(struct ploop_index_wb *piwb)
 		if (piwb->bi_status)
 			ploop_advance_local_after_bat_wb(ploop, piwb, false);
 
-		if (piwb->comp)
+		if (piwb->comp) {
 			complete(piwb->comp);
+			if (piwb->comp_bi_status)
+				*piwb->comp_bi_status = piwb->bi_status;
+		}
 		free_piwb(piwb);
 	}
 }
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index b5ceacc1a145..6d92b82cbe1b 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -94,6 +94,7 @@ enum piwb_type {
 struct ploop_index_wb {
 	struct ploop *ploop;
 	struct completion *comp;
+	blk_status_t *comp_bi_status;
 	enum piwb_type type;
 	spinlock_t lock;
 	struct md_page *md;
@@ -103,7 +104,7 @@ struct ploop_index_wb {
 	struct list_head cow_list;
 	atomic_t count;
 	bool completed;
-	int bi_status;
+	blk_status_t bi_status;
 	u32 page_id;
 };
 




More information about the Devel mailing list