[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 = ∁
+ 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 = ∁
+ 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