On Wed, Jun 09, 2021 at 02:30:46PM +0800, Ming Lei wrote: > tagset can't be used after blk_cleanup_queue() is returned because > freeing tagset usually follows blk_clenup_queue(). Commit d97e594c5166 > ("blk-mq: Use request queue-wide tags for tagset-wide sbitmap") adds > check on q->tag_set->flags in blk_mq_exit_sched(), and causes > use-after-free. > > Fixes it by using hctx->flags. > > Reported-by: syzbot+77ba3d171a25c56756ea@xxxxxxxxxxxxxxxxxxxxxxxxx > Fixes: d97e594c5166 ("blk-mq: Use request queue-wide tags for tagset-wide sbitmap") > Cc: John Garry <john.garry@xxxxxxxxxx> > Signed-off-by: Ming Lei <ming.lei@xxxxxxxxxx> > --- > block/blk-mq-sched.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c > index a9182d2f8ad3..80273245d11a 100644 > --- a/block/blk-mq-sched.c > +++ b/block/blk-mq-sched.c > @@ -680,6 +680,7 @@ void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e) > { > struct blk_mq_hw_ctx *hctx; > unsigned int i; > + unsigned int flags = 0; > > queue_for_each_hw_ctx(q, hctx, i) { > blk_mq_debugfs_unregister_sched_hctx(hctx); > @@ -687,12 +688,13 @@ void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e) > e->type->ops.exit_hctx(hctx, i); > hctx->sched_data = NULL; > } > + flags = hctx->flags; > } > blk_mq_debugfs_unregister_sched(q); > if (e->type->ops.exit_sched) > e->type->ops.exit_sched(e); > blk_mq_sched_tags_teardown(q); > - if (blk_mq_is_sbitmap_shared(q->tag_set->flags)) > + if (blk_mq_is_sbitmap_shared(flags)) > blk_mq_exit_sched_shared_sbitmap(q); > q->elevator = NULL; > } Hello Jens, Any chance to merge this fix? Thanks, Ming