All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] blkmq: Fix NULL pointer deref when all reserved tags in use
@ 2015-03-18 20:36 Sam Bradshaw
  2015-03-18 20:40 ` Jens Axboe
  0 siblings, 1 reply; 4+ messages in thread
From: Sam Bradshaw @ 2015-03-18 20:36 UTC (permalink / raw)
  To: axboe; +Cc: linux-kernel

When allocating from the reserved tags pool, bt_get() is called with 
a NULL hctx.  If all tags are in use, the hw queue is kicked to push 
out any pending IO, potentially freeing tags, and tag allocation is 
retried.  The problem is that blk_mq_run_hw_queue() doesn't check for 
a NULL hctx.  This patch fixes that bug.

An alternative implementation might skip kicking the queue for reserved 
tags and go right to io_schedule() but we chose to keep it simple.

Tested by hammering mtip32xx with concurrent smartctl/hdparm.

Signed-off-by: Sam Bradshaw <sbradshaw@micron.com>
Signed-off-by: Selvan Mani <smani@micron.com>
---
 block/blk-mq.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/block/blk-mq.c b/block/blk-mq.c
index 59fa239..0471af6 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -887,7 +887,7 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx)
 
 void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
 {
-	if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state) ||
+	if (unlikely(!hctx || test_bit(BLK_MQ_S_STOPPED, &hctx->state) ||
 	    !blk_mq_hw_queue_mapped(hctx)))
 		return;
 
-- 
1.7.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] blkmq: Fix NULL pointer deref when all reserved tags in use
  2015-03-18 20:36 [PATCH] blkmq: Fix NULL pointer deref when all reserved tags in use Sam Bradshaw
@ 2015-03-18 20:40 ` Jens Axboe
  2015-03-18 21:06   ` Sam Bradshaw
  0 siblings, 1 reply; 4+ messages in thread
From: Jens Axboe @ 2015-03-18 20:40 UTC (permalink / raw)
  To: Sam Bradshaw; +Cc: linux-kernel

On 03/18/2015 02:36 PM, Sam Bradshaw wrote:
> When allocating from the reserved tags pool, bt_get() is called with
> a NULL hctx.  If all tags are in use, the hw queue is kicked to push
> out any pending IO, potentially freeing tags, and tag allocation is
> retried.  The problem is that blk_mq_run_hw_queue() doesn't check for
> a NULL hctx.  This patch fixes that bug.
>
> An alternative implementation might skip kicking the queue for reserved
> tags and go right to io_schedule() but we chose to keep it simple.
>
> Tested by hammering mtip32xx with concurrent smartctl/hdparm.
>
> Signed-off-by: Sam Bradshaw <sbradshaw@micron.com>
> Signed-off-by: Selvan Mani <smani@micron.com>
> ---
>   block/blk-mq.c |    2 +-
>   1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/block/blk-mq.c b/block/blk-mq.c
> index 59fa239..0471af6 100644
> --- a/block/blk-mq.c
> +++ b/block/blk-mq.c
> @@ -887,7 +887,7 @@ static int blk_mq_hctx_next_cpu(struct blk_mq_hw_ctx *hctx)
>
>   void blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx, bool async)
>   {
> -	if (unlikely(test_bit(BLK_MQ_S_STOPPED, &hctx->state) ||
> +	if (unlikely(!hctx || test_bit(BLK_MQ_S_STOPPED, &hctx->state) ||
>   	    !blk_mq_hw_queue_mapped(hctx)))
>   		return;

Good catch! But why not put the hctx == NULL check in as a conditional 
in bt_get() before running the queue? I can't imagine other cases where 
calling blk_mq_run_hw_queue() with hctx == NULL would be a valid scenario.

The bug was introduced with commit b32232073e80, so that should probably
be indicated too.

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] blkmq: Fix NULL pointer deref when all reserved tags in use
  2015-03-18 20:40 ` Jens Axboe
@ 2015-03-18 21:06   ` Sam Bradshaw
  2015-03-18 21:51     ` Jens Axboe
  0 siblings, 1 reply; 4+ messages in thread
From: Sam Bradshaw @ 2015-03-18 21:06 UTC (permalink / raw)
  To: Jens Axboe; +Cc: linux-kernel


> Good catch! But why not put the hctx == NULL check in as a conditional
> in bt_get() before running the queue? I can't imagine other cases where
> calling blk_mq_run_hw_queue() with hctx == NULL would be a valid scenario.

The change was meant to be broad in scope.  A runtime NULL deref is a 
rather unfortunate way to determine that there are other invalid scenarios.

But given that both approaches fix the immediate problem, I'd be happy 
to change the patch as you suggest.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] blkmq: Fix NULL pointer deref when all reserved tags in use
  2015-03-18 21:06   ` Sam Bradshaw
@ 2015-03-18 21:51     ` Jens Axboe
  0 siblings, 0 replies; 4+ messages in thread
From: Jens Axboe @ 2015-03-18 21:51 UTC (permalink / raw)
  To: Sam Bradshaw; +Cc: linux-kernel

On 03/18/2015 03:06 PM, Sam Bradshaw wrote:
>
>> Good catch! But why not put the hctx == NULL check in as a conditional
>> in bt_get() before running the queue? I can't imagine other cases where
>> calling blk_mq_run_hw_queue() with hctx == NULL would be a valid
>> scenario.
>
> The change was meant to be broad in scope.  A runtime NULL deref is a
> rather unfortunate way to determine that there are other invalid scenarios.

Normally those kinds of issues would trigger quickly and it'd be 
obvious. Granted, this was an error handling case for the special case 
of reserved tags, so it persisted longer than it should have... But in 
general, I would not be too worried.

> But given that both approaches fix the immediate problem, I'd be happy
> to change the patch as you suggest.

Thanks!

-- 
Jens Axboe


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-03-18 21:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-18 20:36 [PATCH] blkmq: Fix NULL pointer deref when all reserved tags in use Sam Bradshaw
2015-03-18 20:40 ` Jens Axboe
2015-03-18 21:06   ` Sam Bradshaw
2015-03-18 21:51     ` Jens Axboe

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.