diff mbox series

brcmfmac: NULL pointer dereference on tx statistic update

Message ID 20250109155201.3661298-1-marcel.hamer@windriver.com (mailing list archive)
State New
Delegated to: Kalle Valo
Headers show
Series brcmfmac: NULL pointer dereference on tx statistic update | expand

Commit Message

Marcel Hamer Jan. 9, 2025, 3:52 p.m. UTC
On removal of the device or unloading of the kernel module a potential
NULL pointer dereference occurs.

The following sequence deletes the interface:

  brcmf_detach()
    brcmf_remove_interface()
      brcmf_del_if()

Inside the brcmf_del_if() function the drvr->if2bss[ifidx] is updated to
BRCMF_BSSIDX_INVALID (-1) if the bsscfgidx matches.

After brcmf_remove_interface() call the brcmf_proto_detach() function is
called providing the following sequence:

  brcmf_detach()
    brcmf_proto_detach()
      brcmf_proto_msgbuf_detach()
        brcmf_flowring_detach()
          brcmf_msgbuf_delete_flowring()
            brcmf_msgbuf_remove_flowring()
              brcmf_flowring_delete()
                brcmf_get_ifp()
                brcmf_txfinalize()

Since brcmf_get_ip() can and actually will return NULL in this case the
call to brcmf_txfinalize() will result in a NULL pointer dereference
inside brcmf_txfinalize() when trying to update
ifp->ndev->stats.tx_errors.

This will only happen if a flowring still has an skb.

Cc: stable@vger.kernel.org
Signed-off-by: Marcel Hamer <marcel.hamer@windriver.com>
Link: https://lore.kernel.org/all/b519e746-ddfd-421f-d897-7620d229e4b2@gmail.com/
---
 drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Jonas Gorski Jan. 9, 2025, 7:33 p.m. UTC | #1
Hi,

On Thu, Jan 9, 2025 at 4:53 PM Marcel Hamer <marcel.hamer@windriver.com> wrote:
>
> On removal of the device or unloading of the kernel module a potential
> NULL pointer dereference occurs.
>
> The following sequence deletes the interface:
>
>   brcmf_detach()
>     brcmf_remove_interface()
>       brcmf_del_if()
>
> Inside the brcmf_del_if() function the drvr->if2bss[ifidx] is updated to
> BRCMF_BSSIDX_INVALID (-1) if the bsscfgidx matches.
>
> After brcmf_remove_interface() call the brcmf_proto_detach() function is
> called providing the following sequence:
>
>   brcmf_detach()
>     brcmf_proto_detach()
>       brcmf_proto_msgbuf_detach()
>         brcmf_flowring_detach()
>           brcmf_msgbuf_delete_flowring()
>             brcmf_msgbuf_remove_flowring()
>               brcmf_flowring_delete()
>                 brcmf_get_ifp()
>                 brcmf_txfinalize()
>
> Since brcmf_get_ip() can and actually will return NULL in this case the
> call to brcmf_txfinalize() will result in a NULL pointer dereference
> inside brcmf_txfinalize() when trying to update
> ifp->ndev->stats.tx_errors.
>
> This will only happen if a flowring still has an skb.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Marcel Hamer <marcel.hamer@windriver.com>
> Link: https://lore.kernel.org/all/b519e746-ddfd-421f-d897-7620d229e4b2@gmail.com/
> ---
>  drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
> index c3a57e30c855..cf731bc7ae24 100644
> --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
> +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
> @@ -549,7 +549,7 @@ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
>                         wake_up(&ifp->pend_8021x_wait);

Here is some additional potential ifp access, which happens if the
ethtype is ETH_P_PAE. Should this also be guarded? To me it looks it
might also break there, just with lower probability. Or is this
impossible to reach when detaching?

>         }
>
> -       if (!success)
> +       if (!success && ifp)
>                 ifp->ndev->stats.tx_errors++;
>
>         brcmu_pkt_buf_free_skb(txp);

Best Regards,
Jonas
diff mbox series

Patch

diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
index c3a57e30c855..cf731bc7ae24 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -549,7 +549,7 @@  void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
 			wake_up(&ifp->pend_8021x_wait);
 	}
 
-	if (!success)
+	if (!success && ifp)
 		ifp->ndev->stats.tx_errors++;
 
 	brcmu_pkt_buf_free_skb(txp);