linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Toke Høiland-Jørgensen" <toke@toke.dk>
To: Fedor Pchelkin <pchelkin@ispras.ru>
Cc: Fedor Pchelkin <pchelkin@ispras.ru>,
	Kalle Valo <kvalo@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	"John W. Linville" <linville@tuxdriver.com>,
	Vasanthakumar Thiagarajan <vasanth@atheros.com>,
	Senthil Balasubramanian <senthilkumar@atheros.com>,
	Sujith <Sujith.Manoharan@atheros.com>,
	linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Alexey Khoroshilov <khoroshilov@ispras.ru>,
	lvc-project@linuxtesting.org
Subject: Re: [PATCH 1/1] wifi: ath9k: hif_usb: fix memory leak of remain_skbs
Date: Thu, 16 Feb 2023 17:15:32 +0100	[thread overview]
Message-ID: <87a61dsi1n.fsf@toke.dk> (raw)
In-Reply-To: <20230212145238.123055-2-pchelkin@ispras.ru>

Fedor Pchelkin <pchelkin@ispras.ru> writes:

> hif_dev->remain_skb is allocated and used exclusively in
> ath9k_hif_usb_rx_stream(). It is implied that an allocated remain_skb is
> processed and subsequently freed (in error paths) only during the next
> call of ath9k_hif_usb_rx_stream().
>
> So, if the device is deinitialized between those two calls or if the skb
> contents are incorrect, it is possible that ath9k_hif_usb_rx_stream() is
> not called next time and the allocated remain_skb is leaked. Our local
> Syzkaller instance was able to trigger that.
>
> Fix the leak by introducing a function to explicitly free remain_skb (if
> it is not NULL) when the device is being deinitialized. remain_skb is NULL
> when it has not been allocated at all (hif_dev struct is kzalloced) or
> when it has been proccesed in next call to ath9k_hif_usb_rx_stream().
>
> Proper spinlocks are held to prevent possible concurrent access to
> remain_skb from the interrupt context ath9k_hif_usb_rx_stream(). These
> accesses should not happen as rx_urbs have been deallocated before but
> it prevents a dangerous race condition in these cases.
>
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
>
> Fixes: fb9987d0f748 ("ath9k_htc: Support for AR9271 chipset.")
> Signed-off-by: Fedor Pchelkin <pchelkin@ispras.ru>
> Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
> ---
>  drivers/net/wireless/ath/ath9k/hif_usb.c | 18 ++++++++++++++++++
>  1 file changed, 18 insertions(+)
>
> diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
> index f521dfa2f194..e03ab972edf7 100644
> --- a/drivers/net/wireless/ath/ath9k/hif_usb.c
> +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
> @@ -534,6 +534,23 @@ static struct ath9k_htc_hif hif_usb = {
>  	.send = hif_usb_send,
>  };
>  
> +/* Need to free remain_skb allocated in ath9k_hif_usb_rx_stream
> + * in case ath9k_hif_usb_rx_stream wasn't called next time to
> + * process the buffer and subsequently free it.
> + */
> +static void ath9k_hif_usb_free_rx_remain_skb(struct hif_device_usb *hif_dev)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&hif_dev->rx_lock, flags);
> +	if (hif_dev->remain_skb) {
> +		dev_kfree_skb_any(hif_dev->remain_skb);
> +		hif_dev->remain_skb = NULL;
> +		hif_dev->rx_remain_len = 0;
> +	}
> +	spin_unlock_irqrestore(&hif_dev->rx_lock, flags);
> +}
> +
>  static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
>  				    struct sk_buff *skb)
>  {
> @@ -1129,6 +1146,7 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev)
>  static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev)
>  {
>  	ath9k_hif_usb_dealloc_urbs(hif_dev);
> +	ath9k_hif_usb_free_rx_remain_skb(hif_dev);
>  }

Erm, does this actually fix the leak? AFAICT, ath9k_hif_usb_dev_deinit()
is only called on the error path of ath9k_hif_usb_firmware_cb(), not
when the device is subsequently torn down in
ath9k_htc_disconnect_device()?

I think the right place to put this is probably inside
ath9k_hif_usb_dealloc_urbs()? That gets called on USB suspend as well,
but it seems to me that if we're suspending the device to an extent that
we're deallocating the urbs, we should be clearing out the cached skb in
remain_skb anyway?

-Toke

  reply	other threads:[~2023-02-16 16:22 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-12 14:52 [PATCH 0/1] wifi: ath9k: hif_usb: fix memory leak of remain_skbs Fedor Pchelkin
2023-02-12 14:52 ` [PATCH 1/1] " Fedor Pchelkin
2023-02-16 16:15   ` Toke Høiland-Jørgensen [this message]
2023-02-16 17:50     ` Fedor Pchelkin
2023-02-16 18:05       ` Toke Høiland-Jørgensen
2023-02-16 18:44         ` Fedor Pchelkin
2023-02-16 19:23         ` [PATCH v2] " Fedor Pchelkin
2023-02-16 20:54           ` Toke Høiland-Jørgensen
2023-02-20  8:37           ` Kalle Valo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87a61dsi1n.fsf@toke.dk \
    --to=toke@toke.dk \
    --cc=Sujith.Manoharan@atheros.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=khoroshilov@ispras.ru \
    --cc=kuba@kernel.org \
    --cc=kvalo@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=lvc-project@linuxtesting.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pchelkin@ispras.ru \
    --cc=senthilkumar@atheros.com \
    --cc=vasanth@atheros.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).