aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-mq.c
diff options
context:
space:
mode:
authorMing Lei <ming.lei@canonical.com>2015-01-19 22:00:56 -0500
committerJens Axboe <axboe@fb.com>2015-01-20 11:28:33 -0500
commit76d697d10769048e5721510100bf3a9413a56385 (patch)
treee7d78afb91e9f7ff47f7e1e558f762908c50f49e /block/blk-mq.c
parent6222d1721dd7d533b43747642419a8ff78ad6f99 (diff)
blk-mq: fix hctx/ctx kobject use-after-free
The kobject memory shouldn't have been freed before the kobject is released because driver core can access it freely before its release. This patch frees hctx in its release callback. For ctx, they share one single per-cpu variable which is associated with the request queue, so free ctx in q->mq_kobj's release handler. Signed-off-by: Sasha Levin <sasha.levin@oracle.com> (fix ctx kobjects) Signed-off-by: Ming Lei <ming.lei@canonical.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'block/blk-mq.c')
-rw-r--r--block/blk-mq.c6
1 files changed, 1 insertions, 5 deletions
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 2f95747c287e..9ee3b87c4498 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1641,10 +1641,8 @@ static void blk_mq_free_hw_queues(struct request_queue *q,
1641 struct blk_mq_hw_ctx *hctx; 1641 struct blk_mq_hw_ctx *hctx;
1642 unsigned int i; 1642 unsigned int i;
1643 1643
1644 queue_for_each_hw_ctx(q, hctx, i) { 1644 queue_for_each_hw_ctx(q, hctx, i)
1645 free_cpumask_var(hctx->cpumask); 1645 free_cpumask_var(hctx->cpumask);
1646 kfree(hctx);
1647 }
1648} 1646}
1649 1647
1650static int blk_mq_init_hctx(struct request_queue *q, 1648static int blk_mq_init_hctx(struct request_queue *q,
@@ -2002,11 +2000,9 @@ void blk_mq_free_queue(struct request_queue *q)
2002 2000
2003 percpu_ref_exit(&q->mq_usage_counter); 2001 percpu_ref_exit(&q->mq_usage_counter);
2004 2002
2005 free_percpu(q->queue_ctx);
2006 kfree(q->queue_hw_ctx); 2003 kfree(q->queue_hw_ctx);
2007 kfree(q->mq_map); 2004 kfree(q->mq_map);
2008 2005
2009 q->queue_ctx = NULL;
2010 q->queue_hw_ctx = NULL; 2006 q->queue_hw_ctx = NULL;
2011 q->mq_map = NULL; 2007 q->mq_map = NULL;
2012 2008