All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
@ 2022-12-28 22:40 Fedor Pchelkin
  2023-01-02 10:52 ` Toke Høiland-Jørgensen
  0 siblings, 1 reply; 11+ messages in thread
From: Fedor Pchelkin @ 2022-12-28 22:40 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project

Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
have an incorrect pkt_len or pkt_tag, the skb is dropped and all the
associated skb_pool buffers should be cleaned, too.

Found by Linux Verification Center (linuxtesting.org) with Syzkaller.

Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
 drivers/net/wireless/ath/ath9k/hif_usb.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 1a2e0c7eeb02..d02cec114280 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -586,14 +586,14 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 
 		if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
 			RX_STAT_INC(hif_dev, skb_dropped);
-			return;
+			goto invalid_pkt;
 		}
 
 		if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
 			dev_err(&hif_dev->udev->dev,
 				"ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
 			RX_STAT_INC(hif_dev, skb_dropped);
-			return;
+			goto invalid_pkt;
 		}
 
 		pad_len = 4 - (pkt_len & 0x3);
@@ -654,6 +654,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
 		RX_STAT_INC(hif_dev, skb_completed);
 	}
+	return;
+invalid_pkt:
+	for (i = 0; i < pool_index; i++)
+		kfree_skb(skb_pool[i]);
+	return;
 }
 
 static void ath9k_hif_usb_rx_cb(struct urb *urb)
-- 
2.34.1


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

* Re: [PATCH] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2022-12-28 22:40 [PATCH] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails Fedor Pchelkin
@ 2023-01-02 10:52 ` Toke Høiland-Jørgensen
  2023-01-03 14:29   ` Fedor Pchelkin
  2023-01-03 14:30   ` [PATCH v2] " Fedor Pchelkin
  0 siblings, 2 replies; 11+ messages in thread
From: Toke Høiland-Jørgensen @ 2023-01-02 10:52 UTC (permalink / raw)
  To: Fedor Pchelkin, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project

Fedor Pchelkin <pchelkin@ispras.ru> writes:

> Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
> While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
> skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
> have an incorrect pkt_len or pkt_tag, the skb is dropped and all the
> associated skb_pool buffers should be cleaned, too.
>
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
>
> Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
> Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
> Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>

Is this the same issue reported in
https://lore.kernel.org/r/000000000000f3e5f805f133d3f7@google.com ?

If so, could you please tag the patch appropriately?

-Toke

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

* Re: [PATCH] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-02 10:52 ` Toke Høiland-Jørgensen
@ 2023-01-03 14:29   ` Fedor Pchelkin
  2023-01-03 20:18     ` Toke Høiland-Jørgensen
  2023-01-03 14:30   ` [PATCH v2] " Fedor Pchelkin
  1 sibling, 1 reply; 11+ messages in thread
From: Fedor Pchelkin @ 2023-01-03 14:29 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project

> Is this the same issue reported in
> https://lore.kernel.org/r/000000000000f3e5f805f133d3f7@google.com ?

Actually, this issue is fixed by another patch I've sent you recently:

> [PATCH] wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is
> no callback function

I've added the relevant Reported-by tags to both patches and resent them.

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

* [PATCH v2] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-02 10:52 ` Toke Høiland-Jørgensen
  2023-01-03 14:29   ` Fedor Pchelkin
@ 2023-01-03 14:30   ` Fedor Pchelkin
  2023-01-03 21:03     ` Toke Høiland-Jørgensen
  1 sibling, 1 reply; 11+ messages in thread
From: Fedor Pchelkin @ 2023-01-03 14:30 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project, syzbot+e9632e3eb038d93d6bc6

Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
have an incorrect pkt_len or pkt_tag, the skb is dropped and all the
associated skb_pool buffers should be cleaned, too.

Found by Linux Verification Center (linuxtesting.org) with Syzkaller.

Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com
Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
v1->v2: added Reported-by tag

 drivers/net/wireless/ath/ath9k/hif_usb.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 1a2e0c7eeb02..d02cec114280 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -586,14 +586,14 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 
 		if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
 			RX_STAT_INC(hif_dev, skb_dropped);
-			return;
+			goto invalid_pkt;
 		}
 
 		if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
 			dev_err(&hif_dev->udev->dev,
 				"ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
 			RX_STAT_INC(hif_dev, skb_dropped);
-			return;
+			goto invalid_pkt;
 		}
 
 		pad_len = 4 - (pkt_len & 0x3);
@@ -654,6 +654,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
 		RX_STAT_INC(hif_dev, skb_completed);
 	}
+	return;
+invalid_pkt:
+	for (i = 0; i < pool_index; i++)
+		kfree_skb(skb_pool[i]);
+	return;
 }
 
 static void ath9k_hif_usb_rx_cb(struct urb *urb)
-- 
2.34.1


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

* Re: [PATCH] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-03 14:29   ` Fedor Pchelkin
@ 2023-01-03 20:18     ` Toke Høiland-Jørgensen
  0 siblings, 0 replies; 11+ messages in thread
From: Toke Høiland-Jørgensen @ 2023-01-03 20:18 UTC (permalink / raw)
  To: Fedor Pchelkin, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project

Fedor Pchelkin <pchelkin@ispras.ru> writes:

>> Is this the same issue reported in
>> https://lore.kernel.org/r/000000000000f3e5f805f133d3f7@google.com ?
>
> Actually, this issue is fixed by another patch I've sent you recently:

Ah, great!

>> [PATCH] wifi: ath9k: htc_hst: free skb in ath9k_htc_rx_msg() if there is
>> no callback function
>
> I've added the relevant Reported-by tags to both patches and resent them.

Awesome, thank you :)

-Toke

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

* Re: [PATCH v2] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-03 14:30   ` [PATCH v2] " Fedor Pchelkin
@ 2023-01-03 21:03     ` Toke Høiland-Jørgensen
  2023-01-03 22:30       ` Fedor Pchelkin
  0 siblings, 1 reply; 11+ messages in thread
From: Toke Høiland-Jørgensen @ 2023-01-03 21:03 UTC (permalink / raw)
  To: Fedor Pchelkin, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project, syzbot+e9632e3eb038d93d6bc6

Fedor Pchelkin <pchelkin@ispras.ru> writes:

> Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
> While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
> skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
> have an incorrect pkt_len or pkt_tag, the skb is dropped and all the
> associated skb_pool buffers should be cleaned, too.
>
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
>
> Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
> Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
> Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com
> Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
> ---
> v1->v2: added Reported-by tag
>
>  drivers/net/wireless/ath/ath9k/hif_usb.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
> index 1a2e0c7eeb02..d02cec114280 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.c
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
> @@ -586,14 +586,14 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
>  
>  		if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
>  			RX_STAT_INC(hif_dev, skb_dropped);
> -			return;
> +			goto invalid_pkt;
>  		}
>  
>  		if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
>  			dev_err(&hif_dev->udev->dev,
>  				"ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
>  			RX_STAT_INC(hif_dev, skb_dropped);
> -			return;
> +			goto invalid_pkt;
>  		}
>  
>  		pad_len = 4 - (pkt_len & 0x3);
> @@ -654,6 +654,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
>  				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
>  		RX_STAT_INC(hif_dev, skb_completed);
>  	}
> +	return;
> +invalid_pkt:
> +	for (i = 0; i < pool_index; i++)
> +		kfree_skb(skb_pool[i]);
> +	return;

Hmm, so in the other error cases (if SKB allocation fails), we just
'goto err' and call the receive handler for the packets already in
skb_pool. Why can't we do the same here?

Also, I think there's another bug in that function, which this change
will make worse? Specifically, in the start of that function,
hif_dev->remain_skb is moved to skb_pool[0], but not cleared from
hif_dev itself. So if we then hit the invalid check and free it, the
next time the function is called, we'll get the same remain_skb pointer,
which has now been freed.

So I think we'll need to clear out hif_dev->remain_skb after moving it
to skb_pool. Care to add that as well?

-Toke

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

* Re: [PATCH v2] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-03 21:03     ` Toke Høiland-Jørgensen
@ 2023-01-03 22:30       ` Fedor Pchelkin
  2023-01-03 23:38         ` Toke Høiland-Jørgensen
  0 siblings, 1 reply; 11+ messages in thread
From: Fedor Pchelkin @ 2023-01-03 22:30 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project

> Hmm, so in the other error cases (if SKB allocation fails), we just
> 'goto err' and call the receive handler for the packets already in
> skb_pool. Why can't we do the same here?

If SKB allocation fails, then the packets already in skb_pool should be
processed by htc rx handler, yes. About the other two cases: if pkt_tag or
pkt_len is invalid, then the whole SKB is considered invalid and dropped.
That is what the statistics macros tell. So I think we should not process
packets from skb_pool which are associated with a dropped SKB. And so just
free them instead.

> Also, I think there's another bug in that function, which this change
> will make worse? Specifically, in the start of that function,
> hif_dev->remain_skb is moved to skb_pool[0], but not cleared from
> hif_dev itself. So if we then hit the invalid check and free it, the
> next time the function is called, we'll get the same remain_skb pointer,
> which has now been freed.

Sorry, I missed that somehow.
Moving 'hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;' after
"ath9k_htc: RX memory allocation error\n" error path should be done, too.
hif_dev->rx_remain_len is zeroed after remain_skb processing, so we cannot
reference hif_dev->remain_skb unless we explicitly allocate successfully a
new one (making rx_remain_len non zero).

> So I think we'll need to clear out hif_dev->remain_skb after moving it
> to skb_pool. Care to add that as well?

Yes, this must be done. I'll add it to patch v3.

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

* Re: [PATCH v2] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-03 22:30       ` Fedor Pchelkin
@ 2023-01-03 23:38         ` Toke Høiland-Jørgensen
  2023-01-04 12:36           ` [PATCH v3] " Fedor Pchelkin
  0 siblings, 1 reply; 11+ messages in thread
From: Toke Høiland-Jørgensen @ 2023-01-03 23:38 UTC (permalink / raw)
  To: Fedor Pchelkin, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project

Fedor Pchelkin <pchelkin@ispras.ru> writes:

>> Hmm, so in the other error cases (if SKB allocation fails), we just
>> 'goto err' and call the receive handler for the packets already in
>> skb_pool. Why can't we do the same here?
>
> If SKB allocation fails, then the packets already in skb_pool should be
> processed by htc rx handler, yes. About the other two cases: if pkt_tag or
> pkt_len is invalid, then the whole SKB is considered invalid and dropped.
> That is what the statistics macros tell. So I think we should not process
> packets from skb_pool which are associated with a dropped SKB. And so just
> free them instead.

Hmm, okay, but if we're counting packets, your patch is not incrementing
any drop counters for the extra SKBs it's dropping either? They would
previously have been counted as 'RX_STAT_INC(hif_dev, skb_allocated)',
so shouldn't they now be counted as 'skb_dropped' as well? The single
counter increase inside the err if statements refers to the skb that's
the function parameter (which AFAICT is a different kind of skb than the
ones being allocated and processed in that loop? it's being split into
chunks or?).

>> Also, I think there's another bug in that function, which this change
>> will make worse? Specifically, in the start of that function,
>> hif_dev->remain_skb is moved to skb_pool[0], but not cleared from
>> hif_dev itself. So if we then hit the invalid check and free it, the
>> next time the function is called, we'll get the same remain_skb pointer,
>> which has now been freed.
>
> Sorry, I missed that somehow.
> Moving 'hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;' after
> "ath9k_htc: RX memory allocation error\n" error path should be done, too.
> hif_dev->rx_remain_len is zeroed after remain_skb processing, so we cannot
> reference hif_dev->remain_skb unless we explicitly allocate successfully a
> new one (making rx_remain_len non zero).
>
>> So I think we'll need to clear out hif_dev->remain_skb after moving it
>> to skb_pool. Care to add that as well?
>
> Yes, this must be done. I'll add it to patch v3.

OK, cool!

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

* [PATCH v3] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-03 23:38         ` Toke Høiland-Jørgensen
@ 2023-01-04 12:36           ` Fedor Pchelkin
  2023-01-04 14:50             ` Toke Høiland-Jørgensen
  2023-01-17 11:53             ` Kalle Valo
  0 siblings, 2 replies; 11+ messages in thread
From: Fedor Pchelkin @ 2023-01-04 12:36 UTC (permalink / raw)
  To: Toke Høiland-Jørgensen, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project, syzbot+e9632e3eb038d93d6bc6

Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
have an incorrect pkt_len or pkt_tag, the input skb is considered invalid
and dropped. All the associated packets already in skb_pool should be
dropped and freed. Added a comment describing this issue.

The patch also makes remain_skb NULL after being processed so that it
cannot be referenced after potential free. The initialization of hif_dev
fields which are associated with remain_skb (rx_remain_len,
rx_transfer_len and rx_pad_len) is moved after a new remain_skb is
allocated. 

Found by Linux Verification Center (linuxtesting.org) with Syzkaller.

Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com
Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
---
v1->v2: added Reported-by tag
v2->v3: added proper remain_skb processing, stat macro, comment 

 drivers/net/wireless/ath/ath9k/hif_usb.c | 31 +++++++++++++++++-------
 1 file changed, 22 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 1a2e0c7eeb02..de6c0824c9ca 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -561,11 +561,11 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 			memcpy(ptr, skb->data, rx_remain_len);
 
 			rx_pkt_len += rx_remain_len;
-			hif_dev->rx_remain_len = 0;
 			skb_put(remain_skb, rx_pkt_len);
 
 			skb_pool[pool_index++] = remain_skb;
-
+			hif_dev->remain_skb = NULL;
+			hif_dev->rx_remain_len = 0;
 		} else {
 			index = rx_remain_len;
 		}
@@ -584,16 +584,21 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 		pkt_len = get_unaligned_le16(ptr + index);
 		pkt_tag = get_unaligned_le16(ptr + index + 2);
 
+		/* It is supposed that if we have an invalid pkt_tag or
+		 * pkt_len then the whole input SKB is considered invalid
+		 * and dropped; the associated packets already in skb_pool
+		 * are dropped, too.
+		 */
 		if (pkt_tag != ATH_USB_RX_STREAM_MODE_TAG) {
 			RX_STAT_INC(hif_dev, skb_dropped);
-			return;
+			goto invalid_pkt;
 		}
 
 		if (pkt_len > 2 * MAX_RX_BUF_SIZE) {
 			dev_err(&hif_dev->udev->dev,
 				"ath9k_htc: invalid pkt_len (%x)\n", pkt_len);
 			RX_STAT_INC(hif_dev, skb_dropped);
-			return;
+			goto invalid_pkt;
 		}
 
 		pad_len = 4 - (pkt_len & 0x3);
@@ -605,11 +610,6 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 
 		if (index > MAX_RX_BUF_SIZE) {
 			spin_lock(&hif_dev->rx_lock);
-			hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
-			hif_dev->rx_transfer_len =
-				MAX_RX_BUF_SIZE - chk_idx - 4;
-			hif_dev->rx_pad_len = pad_len;
-
 			nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC);
 			if (!nskb) {
 				dev_err(&hif_dev->udev->dev,
@@ -617,6 +617,12 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 				spin_unlock(&hif_dev->rx_lock);
 				goto err;
 			}
+
+			hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE;
+			hif_dev->rx_transfer_len =
+				MAX_RX_BUF_SIZE - chk_idx - 4;
+			hif_dev->rx_pad_len = pad_len;
+
 			skb_reserve(nskb, 32);
 			RX_STAT_INC(hif_dev, skb_allocated);
 
@@ -654,6 +660,13 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
 				 skb_pool[i]->len, USB_WLAN_RX_PIPE);
 		RX_STAT_INC(hif_dev, skb_completed);
 	}
+	return;
+invalid_pkt:
+	for (i = 0; i < pool_index; i++) {
+		dev_kfree_skb_any(skb_pool[i]);
+		RX_STAT_INC(hif_dev, skb_dropped);
+	}
+	return;
 }
 
 static void ath9k_hif_usb_rx_cb(struct urb *urb)
-- 
2.34.1


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

* Re: [PATCH v3] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-04 12:36           ` [PATCH v3] " Fedor Pchelkin
@ 2023-01-04 14:50             ` Toke Høiland-Jørgensen
  2023-01-17 11:53             ` Kalle Valo
  1 sibling, 0 replies; 11+ messages in thread
From: Toke Høiland-Jørgensen @ 2023-01-04 14:50 UTC (permalink / raw)
  To: Fedor Pchelkin, Kalle Valo
  Cc: Fedor Pchelkin, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Zekun Shen, Joe Perches, John W. Linville,
	linux-wireless, netdev, linux-kernel, Alexey Khoroshilov,
	lvc-project, syzbot+e9632e3eb038d93d6bc6

Fedor Pchelkin <pchelkin@ispras.ru> writes:

> Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
> While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
> skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
> have an incorrect pkt_len or pkt_tag, the input skb is considered invalid
> and dropped. All the associated packets already in skb_pool should be
> dropped and freed. Added a comment describing this issue.
>
> The patch also makes remain_skb NULL after being processed so that it
> cannot be referenced after potential free. The initialization of hif_dev
> fields which are associated with remain_skb (rx_remain_len,
> rx_transfer_len and rx_pad_len) is moved after a new remain_skb is
> allocated. 
>
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
>
> Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
> Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
> Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com
> Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>

Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>

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

* Re: [PATCH v3] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails
  2023-01-04 12:36           ` [PATCH v3] " Fedor Pchelkin
  2023-01-04 14:50             ` Toke Høiland-Jørgensen
@ 2023-01-17 11:53             ` Kalle Valo
  1 sibling, 0 replies; 11+ messages in thread
From: Kalle Valo @ 2023-01-17 11:53 UTC (permalink / raw)
  To: Fedor Pchelkin
  Cc: Toke Høiland-Jørgensen, Fedor Pchelkin,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Zekun Shen, Joe Perches, John W. Linville, linux-wireless,
	netdev, linux-kernel, Alexey Khoroshilov, lvc-project,
	syzbot+e9632e3eb038d93d6bc6

Fedor Pchelkin <pchelkin@ispras.ru> wrote:

> Syzkaller detected a memory leak of skbs in ath9k_hif_usb_rx_stream().
> While processing skbs in ath9k_hif_usb_rx_stream(), the already allocated
> skbs in skb_pool are not freed if ath9k_hif_usb_rx_stream() fails. If we
> have an incorrect pkt_len or pkt_tag, the input skb is considered invalid
> and dropped. All the associated packets already in skb_pool should be
> dropped and freed. Added a comment describing this issue.
> 
> The patch also makes remain_skb NULL after being processed so that it
> cannot be referenced after potential free. The initialization of hif_dev
> fields which are associated with remain_skb (rx_remain_len,
> rx_transfer_len and rx_pad_len) is moved after a new remain_skb is
> allocated.
> 
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
> 
> Fixes: 6ce708f54cc8 ("ath9k: Fix out-of-bound memcpy in ath9k_hif_usb_rx_stream")
> Fixes: 44b23b488d44 ("ath9k: hif_usb: Reduce indent 1 column")
> Reported-by: syzbot+e9632e3eb038d93d6bc6@syzkaller.appspotmail.com
> Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
> Acked-by: Toke Høiland-Jørgensen <toke@toke.dk>
> Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>

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

0af54343a762 wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails

-- 
https://patchwork.kernel.org/project/linux-wireless/patch/20230104123615.51511-1-pchelkin@ispras.ru/

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


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

end of thread, other threads:[~2023-01-17 11:54 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-28 22:40 [PATCH] wifi: ath9k: hif_usb: clean up skbs if ath9k_hif_usb_rx_stream() fails Fedor Pchelkin
2023-01-02 10:52 ` Toke Høiland-Jørgensen
2023-01-03 14:29   ` Fedor Pchelkin
2023-01-03 20:18     ` Toke Høiland-Jørgensen
2023-01-03 14:30   ` [PATCH v2] " Fedor Pchelkin
2023-01-03 21:03     ` Toke Høiland-Jørgensen
2023-01-03 22:30       ` Fedor Pchelkin
2023-01-03 23:38         ` Toke Høiland-Jørgensen
2023-01-04 12:36           ` [PATCH v3] " Fedor Pchelkin
2023-01-04 14:50             ` Toke Høiland-Jørgensen
2023-01-17 11:53             ` Kalle Valo

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.