linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()
@ 2020-09-11  7:14 Brooke Basile
  2020-09-20  2:03 ` Brooke Basile
                   ` (3 more replies)
  0 siblings, 4 replies; 11+ messages in thread
From: Brooke Basile @ 2020-09-11  7:14 UTC (permalink / raw)
  To: kvalo, davem, kuba
  Cc: gregkh, linux-wireless, linux-kernel, ath9k-devel,
	syzkaller-bugs, Brooke Basile, syzbot+89bd486af9427a9fc605

Calls to usb_kill_anchored_urbs() after usb_kill_urb() on multiprocessor
systems create a race condition in which usb_kill_anchored_urbs() deallocates
the URB before the completer callback is called in usb_kill_urb(), resulting
in a use-after-free.
To fix this, add proper lock protection to usb_kill_urb() calls that can
possibly run concurrently with usb_kill_anchored_urbs().

Reported-by: syzbot+89bd486af9427a9fc605@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?id=cabffad18eb74197f84871802fd2c5117b61febf
Signed-off-by: Brooke Basile <brookebasile@gmail.com>
---
 drivers/net/wireless/ath/ath9k/hif_usb.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 3f563e02d17d..2ed98aaed6fb 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -449,10 +449,19 @@ static void hif_usb_stop(void *hif_handle)
 	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

 	/* The pending URBs have to be canceled. */
+	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
 				 &hif_dev->tx.tx_pending, list) {
+		usb_get_urb(tx_buf->urb);
+		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 		usb_kill_urb(tx_buf->urb);
+		list_del(&tx_buf->list);
+		usb_free_urb(tx_buf->urb);
+		kfree(tx_buf->buf);
+		kfree(tx_buf);
+		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	}
+	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

 	usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
 }
@@ -762,27 +771,37 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
 	struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
 	unsigned long flags;

+	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
 				 &hif_dev->tx.tx_buf, list) {
+		usb_get_urb(tx_buf->urb);
+		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 		usb_kill_urb(tx_buf->urb);
 		list_del(&tx_buf->list);
 		usb_free_urb(tx_buf->urb);
 		kfree(tx_buf->buf);
 		kfree(tx_buf);
+		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	}
+	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

 	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
 	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

+	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
 				 &hif_dev->tx.tx_pending, list) {
+		usb_get_urb(tx_buf->urb);
+		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 		usb_kill_urb(tx_buf->urb);
 		list_del(&tx_buf->list);
 		usb_free_urb(tx_buf->urb);
 		kfree(tx_buf->buf);
 		kfree(tx_buf);
+		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 	}
+	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);

 	usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
 }
--
2.28.0


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

* Re: [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()
  2020-09-11  7:14 [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs() Brooke Basile
@ 2020-09-20  2:03 ` Brooke Basile
  2020-09-21 13:05 ` Kalle Valo
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 11+ messages in thread
From: Brooke Basile @ 2020-09-20  2:03 UTC (permalink / raw)
  To: kvalo, davem, kuba
  Cc: gregkh, linux-wireless, linux-kernel, ath9k-devel,
	syzkaller-bugs, syzbot+89bd486af9427a9fc605

On 9/11/20 3:14 AM, Brooke Basile wrote:
> Calls to usb_kill_anchored_urbs() after usb_kill_urb() on multiprocessor
> systems create a race condition in which usb_kill_anchored_urbs() deallocates
> the URB before the completer callback is called in usb_kill_urb(), resulting
> in a use-after-free.
> To fix this, add proper lock protection to usb_kill_urb() calls that can
> possibly run concurrently with usb_kill_anchored_urbs().
> 
> Reported-by: syzbot+89bd486af9427a9fc605@syzkaller.appspotmail.com
> Link: https://syzkaller.appspot.com/bug?id=cabffad18eb74197f84871802fd2c5117b61febf
> Signed-off-by: Brooke Basile <brookebasile@gmail.com>
> ---
>   drivers/net/wireless/ath/ath9k/hif_usb.c | 19 +++++++++++++++++++
>   1 file changed, 19 insertions(+)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
> index 3f563e02d17d..2ed98aaed6fb 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.c
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
> @@ -449,10 +449,19 @@ static void hif_usb_stop(void *hif_handle)
>   	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
> 
>   	/* The pending URBs have to be canceled. */
> +	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
>   				 &hif_dev->tx.tx_pending, list) {
> +		usb_get_urb(tx_buf->urb);
> +		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
>   		usb_kill_urb(tx_buf->urb);
> +		list_del(&tx_buf->list);
> +		usb_free_urb(tx_buf->urb);
> +		kfree(tx_buf->buf);
> +		kfree(tx_buf);
> +		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	}
> +	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
> 
>   	usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
>   }
> @@ -762,27 +771,37 @@ static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
>   	struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
>   	unsigned long flags;
> 
> +	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
>   				 &hif_dev->tx.tx_buf, list) {
> +		usb_get_urb(tx_buf->urb);
> +		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
>   		usb_kill_urb(tx_buf->urb);
>   		list_del(&tx_buf->list);
>   		usb_free_urb(tx_buf->urb);
>   		kfree(tx_buf->buf);
>   		kfree(tx_buf);
> +		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	}
> +	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
> 
>   	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	hif_dev->tx.flags |= HIF_USB_TX_FLUSH;
>   	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
> 
> +	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
>   				 &hif_dev->tx.tx_pending, list) {
> +		usb_get_urb(tx_buf->urb);
> +		spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
>   		usb_kill_urb(tx_buf->urb);
>   		list_del(&tx_buf->list);
>   		usb_free_urb(tx_buf->urb);
>   		kfree(tx_buf->buf);
>   		kfree(tx_buf);
> +		spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
>   	}
> +	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
> 
>   	usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
>   }
> --
> 2.28.0
> 

Hi,

Just wanted to check on the status of this patch, if there's anything 
wrong I'm happy to make it right.
Sorry to bother!

Best,
Brooke Basile

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

* Re: [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()
  2020-09-11  7:14 [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs() Brooke Basile
  2020-09-20  2:03 ` Brooke Basile
@ 2020-09-21 13:05 ` Kalle Valo
       [not found] ` <20200921130559.005D8C43382@smtp.codeaurora.org>
  2021-03-30 19:36 ` Memory leak in ath9k_hif_usb_dealloc_tx_urbs() Pavel Skripkin
  3 siblings, 0 replies; 11+ messages in thread
From: Kalle Valo @ 2020-09-21 13:05 UTC (permalink / raw)
  To: Brooke Basile
  Cc: davem, kuba, gregkh, linux-wireless, linux-kernel, ath9k-devel,
	syzkaller-bugs, Brooke Basile, syzbot+89bd486af9427a9fc605

Brooke Basile <brookebasile@gmail.com> wrote:

> Calls to usb_kill_anchored_urbs() after usb_kill_urb() on multiprocessor
> systems create a race condition in which usb_kill_anchored_urbs() deallocates
> the URB before the completer callback is called in usb_kill_urb(), resulting
> in a use-after-free.
> To fix this, add proper lock protection to usb_kill_urb() calls that can
> possibly run concurrently with usb_kill_anchored_urbs().
> 
> Reported-by: syzbot+89bd486af9427a9fc605@syzkaller.appspotmail.com
> Link: https://syzkaller.appspot.com/bug?id=cabffad18eb74197f84871802fd2c5117b61febf
> Signed-off-by: Brooke Basile <brookebasile@gmail.com>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>

Patch applied to ath-next branch of ath.git, thanks.

03fb92a432ea ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()

-- 
https://patchwork.kernel.org/patch/11769845/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches


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

* Re: [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()
       [not found] ` <20200921130559.005D8C43382@smtp.codeaurora.org>
@ 2020-09-21 23:04   ` Brooke Basile
  0 siblings, 0 replies; 11+ messages in thread
From: Brooke Basile @ 2020-09-21 23:04 UTC (permalink / raw)
  To: Kalle Valo
  Cc: davem, kuba, gregkh, linux-wireless, linux-kernel, ath9k-devel,
	syzkaller-bugs, syzbot+89bd486af9427a9fc605

On 9/21/20 9:05 AM, Kalle Valo wrote:
> Brooke Basile <brookebasile@gmail.com> wrote:
> 
>> Calls to usb_kill_anchored_urbs() after usb_kill_urb() on multiprocessor
>> systems create a race condition in which usb_kill_anchored_urbs() deallocates
>> the URB before the completer callback is called in usb_kill_urb(), resulting
>> in a use-after-free.
>> To fix this, add proper lock protection to usb_kill_urb() calls that can
>> possibly run concurrently with usb_kill_anchored_urbs().
>>
>> Reported-by: syzbot+89bd486af9427a9fc605@syzkaller.appspotmail.com
>> Link: https://syzkaller.appspot.com/bug?id=cabffad18eb74197f84871802fd2c5117b61febf
>> Signed-off-by: Brooke Basile <brookebasile@gmail.com>
>> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
> 
> Patch applied to ath-next branch of ath.git, thanks.
> 
> 03fb92a432ea ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs()
> 

Thank you! :)

Best,
Brooke Basile

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

* Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2020-09-11  7:14 [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs() Brooke Basile
                   ` (2 preceding siblings ...)
       [not found] ` <20200921130559.005D8C43382@smtp.codeaurora.org>
@ 2021-03-30 19:36 ` Pavel Skripkin
  2021-03-31  6:28   ` Greg KH
  3 siblings, 1 reply; 11+ messages in thread
From: Pavel Skripkin @ 2021-03-30 19:36 UTC (permalink / raw)
  To: brookebasile
  Cc: ath9k-devel, davem, gregkh, kuba, kvalo, linux-kernel,
	linux-wireless, syzbot+89bd486af9427a9fc605, syzkaller-bugs

Hi!

I did some debugging on this
https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
and, I believe, I recognized the problem. The problem appears in case of
ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb krefs will be
initialized to 1, but in free function:

static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)

....

static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
{
    ...
	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
				 &hif_dev->tx.tx_buf, list) {
		usb_get_urb(tx_buf->urb);
		...
		usb_free_urb(tx_buf->urb);
		...
		}

Krefs are incremented and then decremented, that means urbs won't be freed.
I found your patch and I can't properly understand why You added usb_get_urb(tx_buf->urb).
Can You explain please, I believe this will help me or somebody to fix this ussue :)

With regards,
Pavel Skripkin

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

* Re: Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2021-03-30 19:36 ` Memory leak in ath9k_hif_usb_dealloc_tx_urbs() Pavel Skripkin
@ 2021-03-31  6:28   ` Greg KH
  2021-04-27 11:35     ` Atul Gopinathan
  0 siblings, 1 reply; 11+ messages in thread
From: Greg KH @ 2021-03-31  6:28 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: brookebasile, ath9k-devel, davem, kuba, kvalo, linux-kernel,
	linux-wireless, syzbot+89bd486af9427a9fc605, syzkaller-bugs

On Tue, Mar 30, 2021 at 10:36:52PM +0300, Pavel Skripkin wrote:
> Hi!
> 
> I did some debugging on this
> https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
> and, I believe, I recognized the problem. The problem appears in case of
> ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb krefs will be
> initialized to 1, but in free function:
> 
> static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
> 
> ....
> 
> static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
> {
>     ...
> 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
> 				 &hif_dev->tx.tx_buf, list) {
> 		usb_get_urb(tx_buf->urb);
> 		...
> 		usb_free_urb(tx_buf->urb);
> 		...
> 		}
> 
> Krefs are incremented and then decremented, that means urbs won't be freed.
> I found your patch and I can't properly understand why You added usb_get_urb(tx_buf->urb).
> Can You explain please, I believe this will help me or somebody to fix this ussue :)

I think almost everyone who has looked into this has given up due to the
mess of twisty-passages here with almost no real-world benefits for
unwinding them :)

Good luck!

greg k-h

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

* Re: Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2021-03-31  6:28   ` Greg KH
@ 2021-04-27 11:35     ` Atul Gopinathan
  2021-04-27 11:50       ` Greg KH
  2021-04-27 12:04       ` Pavel Skripkin
  0 siblings, 2 replies; 11+ messages in thread
From: Atul Gopinathan @ 2021-04-27 11:35 UTC (permalink / raw)
  To: Greg KH
  Cc: Pavel Skripkin, brookebasile, ath9k-devel, davem, kuba, kvalo,
	linux-kernel, linux-wireless, syzbot+89bd486af9427a9fc605,
	syzkaller-bugs

On Wed, Mar 31, 2021 at 08:28:15AM +0200, Greg KH wrote:
> On Tue, Mar 30, 2021 at 10:36:52PM +0300, Pavel Skripkin wrote:
> > Hi!
> > 
> > I did some debugging on this
> > https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
> > and, I believe, I recognized the problem. The problem appears in case of
> > ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb krefs will be
> > initialized to 1, but in free function:
> > 
> > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
> > 
> > ....
> > 
> > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
> > {
> >     ...
> > 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
> > 				 &hif_dev->tx.tx_buf, list) {
> > 		usb_get_urb(tx_buf->urb);
> > 		...
> > 		usb_free_urb(tx_buf->urb);
> > 		...
> > 		}
> > 
> > Krefs are incremented and then decremented, that means urbs won't be freed.
> > I found your patch and I can't properly understand why You added usb_get_urb(tx_buf->urb).
> > Can You explain please, I believe this will help me or somebody to fix this ussue :)
> 
> I think almost everyone who has looked into this has given up due to the
> mess of twisty-passages here with almost no real-world benefits for
> unwinding them :)

Just wanted to confirm, what is the status of this bug then, as in is it
invalid (not sure if that's the correct word)? I happened to stumble
across the same syzkaller bug report Pavel posted above, in the morning.
Saw that there has been no patch tests/fixes on this yet according to
syzkaller. Spent a couple of hours going through it before sending a
test patch to syzbot which returned an "OK" (and the patch is exactly
what Pavel pointed out, I simply removed the `usb_get_urb()`). Before
sending anything to the mailing list, I made sure to search all the
relavant networking lists to see if this topic had been brought up (learnt
to do this from my preious mistakes of sending already accepted patches) and
luckily I found this.

Syzbot has had 380 crashes caused by this bug, with the latest being
today. So I wanted to confirm what should be done be about this bug. 

Thank you!
Atul

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

* Re: Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2021-04-27 11:35     ` Atul Gopinathan
@ 2021-04-27 11:50       ` Greg KH
  2021-04-27 12:04       ` Pavel Skripkin
  1 sibling, 0 replies; 11+ messages in thread
From: Greg KH @ 2021-04-27 11:50 UTC (permalink / raw)
  To: Atul Gopinathan
  Cc: Pavel Skripkin, brookebasile, ath9k-devel, davem, kuba, kvalo,
	linux-kernel, linux-wireless, syzbot+89bd486af9427a9fc605,
	syzkaller-bugs

On Tue, Apr 27, 2021 at 05:05:59PM +0530, Atul Gopinathan wrote:
> On Wed, Mar 31, 2021 at 08:28:15AM +0200, Greg KH wrote:
> > On Tue, Mar 30, 2021 at 10:36:52PM +0300, Pavel Skripkin wrote:
> > > Hi!
> > > 
> > > I did some debugging on this
> > > https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
> > > and, I believe, I recognized the problem. The problem appears in case of
> > > ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb krefs will be
> > > initialized to 1, but in free function:
> > > 
> > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
> > > 
> > > ....
> > > 
> > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev)
> > > {
> > >     ...
> > > 	list_for_each_entry_safe(tx_buf, tx_buf_tmp,
> > > 				 &hif_dev->tx.tx_buf, list) {
> > > 		usb_get_urb(tx_buf->urb);
> > > 		...
> > > 		usb_free_urb(tx_buf->urb);
> > > 		...
> > > 		}
> > > 
> > > Krefs are incremented and then decremented, that means urbs won't be freed.
> > > I found your patch and I can't properly understand why You added usb_get_urb(tx_buf->urb).
> > > Can You explain please, I believe this will help me or somebody to fix this ussue :)
> > 
> > I think almost everyone who has looked into this has given up due to the
> > mess of twisty-passages here with almost no real-world benefits for
> > unwinding them :)
> 
> Just wanted to confirm, what is the status of this bug then, as in is it
> invalid (not sure if that's the correct word)? I happened to stumble
> across the same syzkaller bug report Pavel posted above, in the morning.
> Saw that there has been no patch tests/fixes on this yet according to
> syzkaller. Spent a couple of hours going through it before sending a
> test patch to syzbot which returned an "OK" (and the patch is exactly
> what Pavel pointed out, I simply removed the `usb_get_urb()`). Before
> sending anything to the mailing list, I made sure to search all the
> relavant networking lists to see if this topic had been brought up (learnt
> to do this from my preious mistakes of sending already accepted patches) and
> luckily I found this.
> 
> Syzbot has had 380 crashes caused by this bug, with the latest being
> today. So I wanted to confirm what should be done be about this bug. 

If you think you can fix it, wonderful, go ahead please!

greg k-h

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

* Re: Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2021-04-27 11:35     ` Atul Gopinathan
  2021-04-27 11:50       ` Greg KH
@ 2021-04-27 12:04       ` Pavel Skripkin
  2021-04-27 12:29         ` Pavel Skripkin
  1 sibling, 1 reply; 11+ messages in thread
From: Pavel Skripkin @ 2021-04-27 12:04 UTC (permalink / raw)
  To: Atul Gopinathan, Greg KH
  Cc: brookebasile, ath9k-devel, davem, kuba, kvalo, linux-kernel,
	linux-wireless, syzbot+89bd486af9427a9fc605, syzkaller-bugs

Hi!

On Tue, 2021-04-27 at 17:05 +0530, Atul Gopinathan wrote:
> On Wed, Mar 31, 2021 at 08:28:15AM +0200, Greg KH wrote:
> > On Tue, Mar 30, 2021 at 10:36:52PM +0300, Pavel Skripkin wrote:
> > > Hi!
> > > 
> > > I did some debugging on this
> > > https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
> > > and, I believe, I recognized the problem. The problem appears in
> > > case of
> > > ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb
> > > krefs will be
> > > initialized to 1, but in free function:
> > > 
> > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb
> > > *hif_dev)
> > > 
> > > ....
> > > 
> > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb
> > > *hif_dev)
> > > {
> > >     ...
> > >         list_for_each_entry_safe(tx_buf, tx_buf_tmp,
> > >                                  &hif_dev->tx.tx_buf, list) {
> > >                 usb_get_urb(tx_buf->urb);
> > >                 ...
> > >                 usb_free_urb(tx_buf->urb);
> > >                 ...
> > >                 }
> > > 
> > > Krefs are incremented and then decremented, that means urbs won't
> > > be freed.
> > > I found your patch and I can't properly understand why You added
> > > usb_get_urb(tx_buf->urb).
> > > Can You explain please, I believe this will help me or somebody
> > > to fix this ussue :)
> > 
> > I think almost everyone who has looked into this has given up due
> > to the
> > mess of twisty-passages here with almost no real-world benefits for
> > unwinding them :)
> 
> Just wanted to confirm, what is the status of this bug then, as in is
> it
> invalid (not sure if that's the correct word)? I happened to stumble
> across the same syzkaller bug report Pavel posted above, in the
> morning.
> Saw that there has been no patch tests/fixes on this yet according to
> syzkaller. Spent a couple of hours going through it before sending a
> test patch to syzbot which returned an "OK" (and the patch is exactly
> what Pavel pointed out, I simply removed the `usb_get_urb()`). Before
> sending anything to the mailing list, I made sure to search all the
> relavant networking lists to see if this topic had been brought up
> (learnt
> to do this from my preious mistakes of sending already accepted
> patches) and
> luckily I found this.
> 
> Syzbot has had 380 crashes caused by this bug, with the latest being
> today. So I wanted to confirm what should be done be about this bug. 
> 

I saw on dashboard, that Dmitry tested latest upstream commit and
syzbot returned "OK", but usb_get_urb(tx_buf->urb); is still there.

I think, this usb_get_urb prevents race condition, but I'm not sure
about it, that's why I sent an email to patch author. As You can see,
he has not responded yet :)

> Thank you!
> Atul

With regards,
Pavel Skripkin



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

* Re: Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2021-04-27 12:04       ` Pavel Skripkin
@ 2021-04-27 12:29         ` Pavel Skripkin
  2021-04-27 13:01           ` Atul Gopinathan
  0 siblings, 1 reply; 11+ messages in thread
From: Pavel Skripkin @ 2021-04-27 12:29 UTC (permalink / raw)
  To: Atul Gopinathan, Greg KH
  Cc: brookebasile, ath9k-devel, davem, kuba, kvalo, linux-kernel,
	linux-wireless, syzbot+89bd486af9427a9fc605, syzkaller-bugs

On Tue, 27 Apr 2021 15:04:29 +0300
Pavel Skripkin <paskripkin@gmail.com> wrote:

> Hi!
> 
> On Tue, 2021-04-27 at 17:05 +0530, Atul Gopinathan wrote:
> > On Wed, Mar 31, 2021 at 08:28:15AM +0200, Greg KH wrote:
> > > On Tue, Mar 30, 2021 at 10:36:52PM +0300, Pavel Skripkin wrote:
> > > > Hi!
> > > > 
> > > > I did some debugging on this
> > > > https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
> > > > and, I believe, I recognized the problem. The problem appears in
> > > > case of
> > > > ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb
> > > > krefs will be
> > > > initialized to 1, but in free function:
> > > > 
> > > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb
> > > > *hif_dev)
> > > > 
> > > > ....
> > > > 
> > > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb
> > > > *hif_dev)
> > > > {
> > > >     ...
> > > >         list_for_each_entry_safe(tx_buf, tx_buf_tmp,
> > > >                                  &hif_dev->tx.tx_buf, list) {
> > > >                 usb_get_urb(tx_buf->urb);
> > > >                 ...
> > > >                 usb_free_urb(tx_buf->urb);
> > > >                 ...
> > > >                 }
> > > > 
> > > > Krefs are incremented and then decremented, that means urbs
> > > > won't be freed.
> > > > I found your patch and I can't properly understand why You added
> > > > usb_get_urb(tx_buf->urb).
> > > > Can You explain please, I believe this will help me or somebody
> > > > to fix this ussue :)
> > > 
> > > I think almost everyone who has looked into this has given up due
> > > to the
> > > mess of twisty-passages here with almost no real-world benefits
> > > for unwinding them :)
> > 
> > Just wanted to confirm, what is the status of this bug then, as in
> > is it
> > invalid (not sure if that's the correct word)? I happened to stumble
> > across the same syzkaller bug report Pavel posted above, in the
> > morning.
> > Saw that there has been no patch tests/fixes on this yet according
> > to syzkaller. Spent a couple of hours going through it before
> > sending a test patch to syzbot which returned an "OK" (and the
> > patch is exactly what Pavel pointed out, I simply removed the
> > `usb_get_urb()`). Before sending anything to the mailing list, I
> > made sure to search all the relavant networking lists to see if
> > this topic had been brought up (learnt
> > to do this from my preious mistakes of sending already accepted
> > patches) and
> > luckily I found this.
> > 
> > Syzbot has had 380 crashes caused by this bug, with the latest being
> > today. So I wanted to confirm what should be done be about this
> > bug. 
> > 
> 
> I saw on dashboard, that Dmitry tested latest upstream commit and
> syzbot returned "OK", but usb_get_urb(tx_buf->urb); is still there.
> 

I am sorry, I clicked wrong link on dashboard :( My bad.

I believe, You can test your patch on this
https://syzkaller.appspot.com/bug?id=cabffad18eb74197f84871802fd2c5117b61febf.

usb_get_urb(tx_buf->urb) was introduced in patch related to this bug

> I think, this usb_get_urb prevents race condition, but I'm not sure
> about it, that's why I sent an email to patch author. As You can see,
> he has not responded yet :)
> 
> > Thank you!
> > Atul
> 
> With regards,
> Pavel Skripkin
> 
> 



With regards,
Pavel Skripkin

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

* Re: Memory leak in ath9k_hif_usb_dealloc_tx_urbs()
  2021-04-27 12:29         ` Pavel Skripkin
@ 2021-04-27 13:01           ` Atul Gopinathan
  0 siblings, 0 replies; 11+ messages in thread
From: Atul Gopinathan @ 2021-04-27 13:01 UTC (permalink / raw)
  To: Pavel Skripkin
  Cc: Greg KH, brookebasile, ath9k-devel, davem, kuba, kvalo,
	linux-kernel, linux-wireless, syzbot+89bd486af9427a9fc605,
	syzkaller-bugs

On Tue, Apr 27, 2021 at 03:29:28PM +0300, Pavel Skripkin wrote:
> On Tue, 27 Apr 2021 15:04:29 +0300
> Pavel Skripkin <paskripkin@gmail.com> wrote:
> 
> > Hi!
> > 
> > On Tue, 2021-04-27 at 17:05 +0530, Atul Gopinathan wrote:
> > > On Wed, Mar 31, 2021 at 08:28:15AM +0200, Greg KH wrote:
> > > > On Tue, Mar 30, 2021 at 10:36:52PM +0300, Pavel Skripkin wrote:
> > > > > Hi!
> > > > > 
> > > > > I did some debugging on this
> > > > > https://syzkaller.appspot.com/bug?id=3ea507fb3c47426497b52bd82b8ef0dd5b6cc7ee
> > > > > and, I believe, I recognized the problem. The problem appears in
> > > > > case of
> > > > > ath9k_htc_hw_init() fail. In case of this fail all tx_buf->urb
> > > > > krefs will be
> > > > > initialized to 1, but in free function:
> > > > > 
> > > > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb
> > > > > *hif_dev)
> > > > > 
> > > > > ....
> > > > > 
> > > > > static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb
> > > > > *hif_dev)
> > > > > {
> > > > >     ...
> > > > >         list_for_each_entry_safe(tx_buf, tx_buf_tmp,
> > > > >                                  &hif_dev->tx.tx_buf, list) {
> > > > >                 usb_get_urb(tx_buf->urb);
> > > > >                 ...
> > > > >                 usb_free_urb(tx_buf->urb);
> > > > >                 ...
> > > > >                 }
> > > > > 
> > > > > Krefs are incremented and then decremented, that means urbs
> > > > > won't be freed.
> > > > > I found your patch and I can't properly understand why You added
> > > > > usb_get_urb(tx_buf->urb).
> > > > > Can You explain please, I believe this will help me or somebody
> > > > > to fix this ussue :)
> > > > 
> > > > I think almost everyone who has looked into this has given up due
> > > > to the
> > > > mess of twisty-passages here with almost no real-world benefits
> > > > for unwinding them :)
> > > 
> > > Just wanted to confirm, what is the status of this bug then, as in
> > > is it
> > > invalid (not sure if that's the correct word)? I happened to stumble
> > > across the same syzkaller bug report Pavel posted above, in the
> > > morning.
> > > Saw that there has been no patch tests/fixes on this yet according
> > > to syzkaller. Spent a couple of hours going through it before
> > > sending a test patch to syzbot which returned an "OK" (and the
> > > patch is exactly what Pavel pointed out, I simply removed the
> > > `usb_get_urb()`). Before sending anything to the mailing list, I
> > > made sure to search all the relavant networking lists to see if
> > > this topic had been brought up (learnt
> > > to do this from my preious mistakes of sending already accepted
> > > patches) and
> > > luckily I found this.
> > > 
> > > Syzbot has had 380 crashes caused by this bug, with the latest being
> > > today. So I wanted to confirm what should be done be about this
> > > bug. 
> > > 
> > 
> > I saw on dashboard, that Dmitry tested latest upstream commit and
> > syzbot returned "OK", but usb_get_urb(tx_buf->urb); is still there.
> > 
> 
> I am sorry, I clicked wrong link on dashboard :( My bad.

Oh right, I forgot to mention. Just want to make it clear that the test
patch was mine. There was a bug in syzkaller, so when I sent the patches
for testing they returned a weird error. Dmitry later pointed out that
it was a syzkaller bug and was kind enough to re-send my patch on a
fixed commit of syzkaller.

https://groups.google.com/g/syzkaller-bugs/c/cBQP4fKjhFQ

> 
> I believe, You can test your patch on this
> https://syzkaller.appspot.com/bug?id=cabffad18eb74197f84871802fd2c5117b61febf.
> 
> usb_get_urb(tx_buf->urb) was introduced in patch related to this bug
> 
> > I think, this usb_get_urb prevents race condition, but I'm not sure
> > about it, that's why I sent an email to patch author. As You can see,
> > he has not responded yet :)

Ah that's how it is. Well not sure we could do much here. Also thanks
for clarifying things, I thought that no one had been looking into this
bug especially when it had so many crash counts which suprised me, but I
guess I was wrong.

Thank you!
Atul

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

end of thread, other threads:[~2021-04-27 13:01 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-11  7:14 [PATCH] wireless: ath9k: hif_usb: fix race condition between usb_get_urb() and usb_kill_anchored_urbs() Brooke Basile
2020-09-20  2:03 ` Brooke Basile
2020-09-21 13:05 ` Kalle Valo
     [not found] ` <20200921130559.005D8C43382@smtp.codeaurora.org>
2020-09-21 23:04   ` Brooke Basile
2021-03-30 19:36 ` Memory leak in ath9k_hif_usb_dealloc_tx_urbs() Pavel Skripkin
2021-03-31  6:28   ` Greg KH
2021-04-27 11:35     ` Atul Gopinathan
2021-04-27 11:50       ` Greg KH
2021-04-27 12:04       ` Pavel Skripkin
2021-04-27 12:29         ` Pavel Skripkin
2021-04-27 13:01           ` Atul Gopinathan

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).