diff mbox series

[3/5] blk-mq: Fix a recently introduced regression in blk_mq_realloc_hw_ctxs()

Message ID 20200217210839.28535-4-bvanassche@acm.org (mailing list archive)
State New, archived
Headers show
Series Five patches related to changing the number of hardware queues | expand

Commit Message

Bart Van Assche Feb. 17, 2020, 9:08 p.m. UTC
q->nr_hw_queues must only be updated once it is known that
blk_mq_realloc_hw_ctxs() has succeeded. Otherwise it can happen that
reallocation fails and that q->nr_hw_queues is larger than the number of
allocated hardware queues. This patch fixes the following crash if
increasing the number of hardware queues fails:

BUG: KASAN: null-ptr-deref in blk_mq_map_swqueue+0x775/0x810
Write of size 8 at addr 0000000000000118 by task check/977

CPU: 3 PID: 977 Comm: check Not tainted 5.6.0-rc1-dbg+ #8
Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
Call Trace:
 dump_stack+0xa5/0xe6
 __kasan_report.cold+0x65/0x99
 kasan_report+0x16/0x20
 check_memory_region+0x140/0x1b0
 memset+0x28/0x40
 blk_mq_map_swqueue+0x775/0x810
 blk_mq_update_nr_hw_queues+0x468/0x710
 nullb_device_submit_queues_store+0xf7/0x1a0 [null_blk]
 configfs_write_file+0x1c4/0x250 [configfs]
 __vfs_write+0x4c/0x90
 vfs_write+0x145/0x2c0
 ksys_write+0xd7/0x180
 __x64_sys_write+0x47/0x50
 do_syscall_64+0x6f/0x2f0
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

Cc: Christoph Hellwig <hch@infradead.org>
Cc: Ming Lei <ming.lei@redhat.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Johannes Thumshirn <jth@kernel.org>
Cc: Keith Busch <kbusch@kernel.org>
Fixes: ac0d6b926e74 ("block: Reduce the amount of memory required per request queue")
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
 block/blk-mq.c | 1 -
 1 file changed, 1 deletion(-)

Comments

Ming Lei Feb. 18, 2020, 3:45 a.m. UTC | #1
On Mon, Feb 17, 2020 at 01:08:37PM -0800, Bart Van Assche wrote:
> q->nr_hw_queues must only be updated once it is known that
> blk_mq_realloc_hw_ctxs() has succeeded. Otherwise it can happen that
> reallocation fails and that q->nr_hw_queues is larger than the number of
> allocated hardware queues. This patch fixes the following crash if
> increasing the number of hardware queues fails:
> 
> BUG: KASAN: null-ptr-deref in blk_mq_map_swqueue+0x775/0x810
> Write of size 8 at addr 0000000000000118 by task check/977
> 
> CPU: 3 PID: 977 Comm: check Not tainted 5.6.0-rc1-dbg+ #8
> Hardware name: Bochs Bochs, BIOS Bochs 01/01/2011
> Call Trace:
>  dump_stack+0xa5/0xe6
>  __kasan_report.cold+0x65/0x99
>  kasan_report+0x16/0x20
>  check_memory_region+0x140/0x1b0
>  memset+0x28/0x40
>  blk_mq_map_swqueue+0x775/0x810
>  blk_mq_update_nr_hw_queues+0x468/0x710
>  nullb_device_submit_queues_store+0xf7/0x1a0 [null_blk]
>  configfs_write_file+0x1c4/0x250 [configfs]
>  __vfs_write+0x4c/0x90
>  vfs_write+0x145/0x2c0
>  ksys_write+0xd7/0x180
>  __x64_sys_write+0x47/0x50
>  do_syscall_64+0x6f/0x2f0
>  entry_SYSCALL_64_after_hwframe+0x49/0xbe
> 
> Cc: Christoph Hellwig <hch@infradead.org>
> Cc: Ming Lei <ming.lei@redhat.com>
> Cc: Hannes Reinecke <hare@suse.com>
> Cc: Johannes Thumshirn <jth@kernel.org>
> Cc: Keith Busch <kbusch@kernel.org>
> Fixes: ac0d6b926e74 ("block: Reduce the amount of memory required per request queue")
> Signed-off-by: Bart Van Assche <bvanassche@acm.org>
> ---
>  block/blk-mq.c | 1 -
>  1 file changed, 1 deletion(-)
> 
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 2b9f490f5a64..5408098b58f2 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -2824,7 +2824,6 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
>  			memcpy(new_hctxs, hctxs, q->nr_hw_queues *
>  			       sizeof(*hctxs));
>  		q->queue_hw_ctx = new_hctxs;
> -		q->nr_hw_queues = set->nr_hw_queues;
>  		kfree(hctxs);
>  		hctxs = new_hctxs;
>  	}

Looks correct, since ->nr_hw_queues needs to be updated after hctxs are
initialized successfully:

Reviewed-by: Ming Lei <ming.lei@redhat.com>


thanks,
Ming
diff mbox series

Patch

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 2b9f490f5a64..5408098b58f2 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -2824,7 +2824,6 @@  static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
 			memcpy(new_hctxs, hctxs, q->nr_hw_queues *
 			       sizeof(*hctxs));
 		q->queue_hw_ctx = new_hctxs;
-		q->nr_hw_queues = set->nr_hw_queues;
 		kfree(hctxs);
 		hctxs = new_hctxs;
 	}