linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
@ 2018-01-15 17:26 Max Kellermann
  2018-01-15 19:58 ` Madhani, Himanshu
  0 siblings, 1 reply; 8+ messages in thread
From: Max Kellermann @ 2018-01-15 17:26 UTC (permalink / raw)
  To: gregkh, linux-scsi, qla2xxx-upstream; +Cc: max.kellermann, linux-kernel

When the qla2xxx firmware is unavailable, eventually
qla2x00_sp_timeout() is reached, which calls the timeout function and
frees the srb_t instance.

The timeout function always resolves to qla2x00_async_iocb_timeout(),
which invokes another callback function called "done".  All of these
qla2x00_*_sp_done() callbacks also free the srb_t instance; after
returning to qla2x00_sp_timeout(), it is freed again.

The fix is to remove the "sp->free(sp)" call from qla2x00_sp_timeout()
and add it to those code paths in qla2x00_async_iocb_timeout() which
do not already free the object.

This is how it looks like with KASAN:

 BUG: KASAN: use-after-free in qla2x00_sp_timeout+0x228/0x250
 Read of size 8 at addr ffff88278147a590 by task swapper/2/0

 Allocated by task 1502:
  save_stack+0x33/0xa0
  kasan_kmalloc+0xa0/0xd0
  kmem_cache_alloc+0xb8/0x1c0
  mempool_alloc+0xd6/0x260
  qla24xx_async_gnl+0x3c5/0x1100

 Freed by task 0:
  save_stack+0x33/0xa0
  kasan_slab_free+0x72/0xc0
  kmem_cache_free+0x75/0x200
  qla24xx_async_gnl_sp_done+0x556/0x9e0
  qla2x00_async_iocb_timeout+0x1c7/0x420
  qla2x00_sp_timeout+0x16d/0x250
  call_timer_fn+0x36/0x200

 The buggy address belongs to the object at ffff88278147a440
  which belongs to the cache qla2xxx_srbs of size 344
 The buggy address is located 336 bytes inside of
  344-byte region [ffff88278147a440, ffff88278147a598)

Signed-off-by: Max Kellermann <mk@cm4all.com>
---
 drivers/scsi/qla2xxx/qla_init.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b5b48ddca962..801890564e00 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -58,7 +58,6 @@ qla2x00_sp_timeout(unsigned long __data)
 	req->outstanding_cmds[sp->handle] = NULL;
 	iocb = &sp->u.iocb_cmd;
 	iocb->timeout(sp);
-	sp->free(sp);
 	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
 }
 
@@ -121,9 +120,11 @@ qla2x00_async_iocb_timeout(void *data)
 		ea.data[1] = lio->u.logio.data[1];
 		ea.sp = sp;
 		qla24xx_handle_plogi_done_event(fcport->vha, &ea);
+		sp->free(sp);
 		break;
 	case SRB_LOGOUT_CMD:
 		qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
+		sp->free(sp);
 		break;
 	case SRB_CT_PTHRU_CMD:
 	case SRB_MB_IOCB:

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

* Re: [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
  2018-01-15 17:26 [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout Max Kellermann
@ 2018-01-15 19:58 ` Madhani, Himanshu
  2018-01-15 20:37   ` Max Kellermann
  0 siblings, 1 reply; 8+ messages in thread
From: Madhani, Himanshu @ 2018-01-15 19:58 UTC (permalink / raw)
  To: Max Kellermann
  Cc: Greg KH, linux-scsi, Dept-Eng QLA2xxx Upstream, max.kellermann,
	linux-kernel

Hi Max, 

> On Jan 15, 2018, at 9:26 AM, Max Kellermann <mk@cm4all.com> wrote:
> 
> When the qla2xxx firmware is unavailable, eventually
> qla2x00_sp_timeout() is reached, which calls the timeout function and
> frees the srb_t instance.
> 
> The timeout function always resolves to qla2x00_async_iocb_timeout(),
> which invokes another callback function called "done".  All of these
> qla2x00_*_sp_done() callbacks also free the srb_t instance; after
> returning to qla2x00_sp_timeout(), it is freed again.
> 
> The fix is to remove the "sp->free(sp)" call from qla2x00_sp_timeout()
> and add it to those code paths in qla2x00_async_iocb_timeout() which
> do not already free the object.
> 
> This is how it looks like with KASAN:
> 
> BUG: KASAN: use-after-free in qla2x00_sp_timeout+0x228/0x250
> Read of size 8 at addr ffff88278147a590 by task swapper/2/0
> 
> Allocated by task 1502:
>  save_stack+0x33/0xa0
>  kasan_kmalloc+0xa0/0xd0
>  kmem_cache_alloc+0xb8/0x1c0
>  mempool_alloc+0xd6/0x260
>  qla24xx_async_gnl+0x3c5/0x1100
> 
> Freed by task 0:
>  save_stack+0x33/0xa0
>  kasan_slab_free+0x72/0xc0
>  kmem_cache_free+0x75/0x200
>  qla24xx_async_gnl_sp_done+0x556/0x9e0
>  qla2x00_async_iocb_timeout+0x1c7/0x420
>  qla2x00_sp_timeout+0x16d/0x250
>  call_timer_fn+0x36/0x200
> 
> The buggy address belongs to the object at ffff88278147a440
>  which belongs to the cache qla2xxx_srbs of size 344
> The buggy address is located 336 bytes inside of
>  344-byte region [ffff88278147a440, ffff88278147a598)
> 
> Signed-off-by: Max Kellermann <mk@cm4all.com>
> ---
> drivers/scsi/qla2xxx/qla_init.c |    3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index b5b48ddca962..801890564e00 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -58,7 +58,6 @@ qla2x00_sp_timeout(unsigned long __data)
> 	req->outstanding_cmds[sp->handle] = NULL;
> 	iocb = &sp->u.iocb_cmd;
> 	iocb->timeout(sp);
> -	sp->free(sp);
> 	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
> }
> 
> @@ -121,9 +120,11 @@ qla2x00_async_iocb_timeout(void *data)
> 		ea.data[1] = lio->u.logio.data[1];
> 		ea.sp = sp;
> 		qla24xx_handle_plogi_done_event(fcport->vha, &ea);
> +		sp->free(sp);
> 		break;
> 	case SRB_LOGOUT_CMD:
> 		qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
> +		sp->free(sp);
> 		break;
> 	case SRB_CT_PTHRU_CMD:
> 	case SRB_MB_IOCB:
> 

We have patch to prevent this double free in 4.16/scsi-queue already. 

https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/commit/?h=4.16/scsi-queue&id=045d6ea200af794ba15515984cff63787a7fc3c0

Thanks,
- Himanshu

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

* Re: [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
  2018-01-15 19:58 ` Madhani, Himanshu
@ 2018-01-15 20:37   ` Max Kellermann
  2018-01-15 21:03     ` Madhani, Himanshu
  2018-01-18  1:02     ` Madhani, Himanshu
  0 siblings, 2 replies; 8+ messages in thread
From: Max Kellermann @ 2018-01-15 20:37 UTC (permalink / raw)
  To: Madhani, Himanshu
  Cc: Max Kellermann, Greg KH, linux-scsi, Dept-Eng QLA2xxx Upstream,
	max.kellermann, linux-kernel

On 2018/01/15 20:58, "Madhani, Himanshu" <Himanshu.Madhani@cavium.com> wrote:
> We have patch to prevent this double free in 4.16/scsi-queue
> already.

No, let me repeat: this is a different bug!

Your bug is about the free call after waiting for completion
synchronously in qla24xx_els_dcmd_iocb(), after it was already freed
by qla2x00_sp_timeout().

My bug is about free in qla2x00_*_sp_done() and again in
qla2x00_sp_timeout().  My patch description describes exactly that.

And you know what?  My patch fixes both bugs.  It is superior to the
one that was merged 4 weeks later, isn't it?

You NACKed my patch 5 weeks ago, and I explained to you that you were
talking about a different bug, but you never replied to that.

Max

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

* Re: [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
  2018-01-15 20:37   ` Max Kellermann
@ 2018-01-15 21:03     ` Madhani, Himanshu
  2018-01-18  1:02     ` Madhani, Himanshu
  1 sibling, 0 replies; 8+ messages in thread
From: Madhani, Himanshu @ 2018-01-15 21:03 UTC (permalink / raw)
  To: Max Kellermann
  Cc: Greg KH, linux-scsi, Dept-Eng QLA2xxx Upstream, max.kellermann,
	linux-kernel

Hi Max, 

> On Jan 15, 2018, at 12:37 PM, Max Kellermann <mk@cm4all.com> wrote:
> 
> On 2018/01/15 20:58, "Madhani, Himanshu" <Himanshu.Madhani@cavium.com> wrote:
>> We have patch to prevent this double free in 4.16/scsi-queue
>> already.
> 
> No, let me repeat: this is a different bug!
> 
> Your bug is about the free call after waiting for completion
> synchronously in qla24xx_els_dcmd_iocb(), after it was already freed
> by qla2x00_sp_timeout().
> 
> My bug is about free in qla2x00_*_sp_done() and again in
> qla2x00_sp_timeout().  My patch description describes exactly that.
> 
> And you know what?  My patch fixes both bugs.  It is superior to the
> one that was merged 4 weeks later, isn't it?
> 
> You NACKed my patch 5 weeks ago, and I explained to you that you were
> talking about a different bug, but you never replied to that.
> 
> Max

Thanks for refreshing my memory. Sorry about not getting back to you earlier. 
I was out for couple weeks so it got dropped out of my bucket for response.

I do agree there is double free issue here. I’ll discuss this internally with folks who has 
deeper history of this code and will get back to you and see which approach we want to
take. 

Thanks,
- Himanshu


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

* Re: [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
  2018-01-15 20:37   ` Max Kellermann
  2018-01-15 21:03     ` Madhani, Himanshu
@ 2018-01-18  1:02     ` Madhani, Himanshu
  1 sibling, 0 replies; 8+ messages in thread
From: Madhani, Himanshu @ 2018-01-18  1:02 UTC (permalink / raw)
  To: Max Kellermann
  Cc: Greg KH, linux-scsi, Dept-Eng QLA2xxx Upstream, max.kellermann,
	linux-kernel

Max,

> On Jan 15, 2018, at 12:37 PM, Max Kellermann <mk@cm4all.com> wrote:
> 
> On 2018/01/15 20:58, "Madhani, Himanshu" <Himanshu.Madhani@cavium.com> wrote:
>> We have patch to prevent this double free in 4.16/scsi-queue
>> already.
> 
> No, let me repeat: this is a different bug!
> 
> Your bug is about the free call after waiting for completion
> synchronously in qla24xx_els_dcmd_iocb(), after it was already freed
> by qla2x00_sp_timeout().
> 
> My bug is about free in qla2x00_*_sp_done() and again in
> qla2x00_sp_timeout().  My patch description describes exactly that.
> 
> And you know what?  My patch fixes both bugs.  It is superior to the
> one that was merged 4 weeks later, isn't it?
> 
> You NACKed my patch 5 weeks ago, and I explained to you that you were
> talking about a different bug, but you never replied to that.
> 
> Max

Just to update you, we are working on fixing this internally and will post
patch soon. 

I’ll add you are Reporter and please review and let us know your comments.

Thanks,
- Himanshu


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

* Re: [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
  2017-12-07 20:38 ` Madhani, Himanshu
@ 2017-12-07 22:10   ` Max Kellermann
  0 siblings, 0 replies; 8+ messages in thread
From: Max Kellermann @ 2017-12-07 22:10 UTC (permalink / raw)
  To: Madhani, Himanshu
  Cc: Max Kellermann, gregkh, linux-scsi, Dept-Eng QLA2xxx Upstream,
	max.kellermann, linux-kernel

On 2017/12/07 21:38, "Madhani, Himanshu" <Himanshu.Madhani@cavium.com> wrote:
> NACK
> 
> These calls are asynchronous calls and free should be called by
> completion.

I don't understand the NACK, and your text doesn't explain it.  It
only describes a second bug that is orthogonal to mine.

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

* Re: [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
  2017-12-07 14:46 Max Kellermann
@ 2017-12-07 20:38 ` Madhani, Himanshu
  2017-12-07 22:10   ` Max Kellermann
  0 siblings, 1 reply; 8+ messages in thread
From: Madhani, Himanshu @ 2017-12-07 20:38 UTC (permalink / raw)
  To: Max Kellermann
  Cc: gregkh, linux-scsi, Dept-Eng QLA2xxx Upstream, max.kellermann,
	linux-kernel

Hi Max,

> On Dec 7, 2017, at 6:46 AM, Max Kellermann <mk@cm4all.com> wrote:
> 
> When the qla2xxx firmware is unavailable, eventually
> qla2x00_sp_timeout() is reached, which calls the timeout function and
> frees the srb_t instance.
> 
> The timeout function always resolves to qla2x00_async_iocb_timeout(),
> which invokes another callback function called "done".  All of these
> qla2x00_*_sp_done() callbacks also free the srb_t instance; after
> returning to qla2x00_sp_timeout(), it is freed again.
> 
> The fix is to remove the "sp->free(sp)" call from qla2x00_sp_timeout()
> and add it to those code paths in qla2x00_async_iocb_timeout() which
> do not already free the object.
> 
> This is how it looks like with KASAN:
> 
> BUG: KASAN: use-after-free in qla2x00_sp_timeout+0x228/0x250
> Read of size 8 at addr ffff88278147a590 by task swapper/2/0
> 
> Allocated by task 1502:
>  save_stack+0x33/0xa0
>  kasan_kmalloc+0xa0/0xd0
>  kmem_cache_alloc+0xb8/0x1c0
>  mempool_alloc+0xd6/0x260
>  qla24xx_async_gnl+0x3c5/0x1100
> 
> Freed by task 0:
>  save_stack+0x33/0xa0
>  kasan_slab_free+0x72/0xc0
>  kmem_cache_free+0x75/0x200
>  qla24xx_async_gnl_sp_done+0x556/0x9e0
>  qla2x00_async_iocb_timeout+0x1c7/0x420
>  qla2x00_sp_timeout+0x16d/0x250
>  call_timer_fn+0x36/0x200
> 
> The buggy address belongs to the object at ffff88278147a440
>  which belongs to the cache qla2xxx_srbs of size 344
> The buggy address is located 336 bytes inside of
>  344-byte region [ffff88278147a440, ffff88278147a598)
> 
> Signed-off-by: Max Kellermann <mk@cm4all.com>
> ---
> drivers/scsi/qla2xxx/qla_init.c |    3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
> index b5b48ddca962..801890564e00 100644
> --- a/drivers/scsi/qla2xxx/qla_init.c
> +++ b/drivers/scsi/qla2xxx/qla_init.c
> @@ -58,7 +58,6 @@ qla2x00_sp_timeout(unsigned long __data)
> 	req->outstanding_cmds[sp->handle] = NULL;
> 	iocb = &sp->u.iocb_cmd;
> 	iocb->timeout(sp);
> -	sp->free(sp);
> 	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
> }
> 
> @@ -121,9 +120,11 @@ qla2x00_async_iocb_timeout(void *data)
> 		ea.data[1] = lio->u.logio.data[1];
> 		ea.sp = sp;
> 		qla24xx_handle_plogi_done_event(fcport->vha, &ea);
> +		sp->free(sp);
> 		break;
> 	case SRB_LOGOUT_CMD:
> 		qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
> +		sp->free(sp);
> 		break;
> 	case SRB_CT_PTHRU_CMD:
> 	case SRB_MB_IOCB:
> 


NACK

These calls are asynchronous calls and free should be called by completion.

I am going to send updates to driver which we have fixed similar issue for 4.16

Thanks,
- Himanshu

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

* [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout
@ 2017-12-07 14:46 Max Kellermann
  2017-12-07 20:38 ` Madhani, Himanshu
  0 siblings, 1 reply; 8+ messages in thread
From: Max Kellermann @ 2017-12-07 14:46 UTC (permalink / raw)
  To: gregkh, linux-scsi, qla2xxx-upstream; +Cc: max.kellermann, linux-kernel

When the qla2xxx firmware is unavailable, eventually
qla2x00_sp_timeout() is reached, which calls the timeout function and
frees the srb_t instance.

The timeout function always resolves to qla2x00_async_iocb_timeout(),
which invokes another callback function called "done".  All of these
qla2x00_*_sp_done() callbacks also free the srb_t instance; after
returning to qla2x00_sp_timeout(), it is freed again.

The fix is to remove the "sp->free(sp)" call from qla2x00_sp_timeout()
and add it to those code paths in qla2x00_async_iocb_timeout() which
do not already free the object.

This is how it looks like with KASAN:

 BUG: KASAN: use-after-free in qla2x00_sp_timeout+0x228/0x250
 Read of size 8 at addr ffff88278147a590 by task swapper/2/0

 Allocated by task 1502:
  save_stack+0x33/0xa0
  kasan_kmalloc+0xa0/0xd0
  kmem_cache_alloc+0xb8/0x1c0
  mempool_alloc+0xd6/0x260
  qla24xx_async_gnl+0x3c5/0x1100

 Freed by task 0:
  save_stack+0x33/0xa0
  kasan_slab_free+0x72/0xc0
  kmem_cache_free+0x75/0x200
  qla24xx_async_gnl_sp_done+0x556/0x9e0
  qla2x00_async_iocb_timeout+0x1c7/0x420
  qla2x00_sp_timeout+0x16d/0x250
  call_timer_fn+0x36/0x200

 The buggy address belongs to the object at ffff88278147a440
  which belongs to the cache qla2xxx_srbs of size 344
 The buggy address is located 336 bytes inside of
  344-byte region [ffff88278147a440, ffff88278147a598)

Signed-off-by: Max Kellermann <mk@cm4all.com>
---
 drivers/scsi/qla2xxx/qla_init.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b5b48ddca962..801890564e00 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -58,7 +58,6 @@ qla2x00_sp_timeout(unsigned long __data)
 	req->outstanding_cmds[sp->handle] = NULL;
 	iocb = &sp->u.iocb_cmd;
 	iocb->timeout(sp);
-	sp->free(sp);
 	spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
 }
 
@@ -121,9 +120,11 @@ qla2x00_async_iocb_timeout(void *data)
 		ea.data[1] = lio->u.logio.data[1];
 		ea.sp = sp;
 		qla24xx_handle_plogi_done_event(fcport->vha, &ea);
+		sp->free(sp);
 		break;
 	case SRB_LOGOUT_CMD:
 		qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
+		sp->free(sp);
 		break;
 	case SRB_CT_PTHRU_CMD:
 	case SRB_MB_IOCB:

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

end of thread, other threads:[~2018-01-18  1:02 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-15 17:26 [PATCH] drivers/scsi/qla2xxx: fix double free bug after firmware timeout Max Kellermann
2018-01-15 19:58 ` Madhani, Himanshu
2018-01-15 20:37   ` Max Kellermann
2018-01-15 21:03     ` Madhani, Himanshu
2018-01-18  1:02     ` Madhani, Himanshu
  -- strict thread matches above, loose matches on Subject: below --
2017-12-07 14:46 Max Kellermann
2017-12-07 20:38 ` Madhani, Himanshu
2017-12-07 22:10   ` Max Kellermann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).