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

Konstantin Khorenko khorenko at virtuozzo.com
Wed Aug 18 21:08:45 MSK 2021


The commit is pushed to "branch-rh8-4.18.0-305.3.1.vz8.7.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh8-4.18.0-305.3.1.vz8.7.7
------>
commit c89798996bb47da4d524e4bddd53b79edbc98b7a
Author: Kirill Tkhai <ktkhai at virtuozzo.com>
Date:   Wed Aug 18 21:08:44 2021 +0300

    dm-ploop: Fix use-after-free in ploop_grow_relocate_cluster()
    
    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