Re: potential dereference of garbage pointer in brcmfmac USB driver

Arend van Spriel <[email protected]>
Newsgroups dev.linux.lists.brcm80211,org.kernel.vger.linux-wireless
Message-ID <[email protected]>
On 5/9/2025 6:41 PM, [email protected] wrote:
> A malicous USB device pretending to be a broadcom/brcm80211/brcmfmac
> wifi interface can generate a firmware signalling frame that causes
> brcmf_fws_hdrpull() to make skb->cb->reorder point into the frame
> data:
> 
>          signal_data = skb->data;
>          ...;
>                  data = signal_data + 2;
>                  ...;
>                  case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
>                          rd = (struct brcmf_skb_reorder_data *)skb->cb;
>                          rd->reorder = data;
> 
> Later on, brcmf_fws_rxreorder() pulls cur_idx out of the frame and
> uses it as an index without checking that it's in bounds (< rfi->maxIdx):
> 
>          reorder_data = ((struct brcmf_skb_reorder_data *)pkt->cb)->reorder;
>          ...;
>                  cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET];
>                  ...;
>                                  brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]);
> 
> I've attached a usbip-based demo that generates a frame with this content:
> 
>       0x20    0x00    0x00    0x0d    0x00    0x00    0x0e   0x0e
>       0x00    0x00    0x00    0x00    0x04    0x00    0x80   0x00
> 
> The 0x80 causes cur_idx to be 128.
> 
> # uname -a
> Linux ubuntu66 6.15.0-rc5-00136-g9c69f8884904 #19 SMP PREEMPT_DYNAMIC Fri May  9 11:51:44 EDT 2025 x86_64 x86_64 x86_64 GNU/Linux
> # cc usbbc3b.c
> # ./a.out
> ...
>   Oops: general protection fault, probably for non-canonical address 0xcccccc00746e6572: 0000 [#1] SMP PTI
>   CPU: 4 UID: 0 PID: 4818 Comm: vhci_rx Tainted: G        W           6.15.0-rc5-00136-g9c69f8884904 #19 PREEMPT(voluntary)
>   Tainted: [W]=WARN
>   Hardware name: FreeBSD BHYVE/BHYVE, BIOS 14.0 10/17/2021
>   RIP: 0010:brcmu_pkt_buf_free_skb+0x9/0x30
>   Code: 00 00 00 48 89 d8 5b 5d c3 cc cc cc cc 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa 48 85 ff 74 10 <48> 83 3f 00 75 0f be 02 00 00 00 e9 57 85 1f 00 c3 cc cc cc cc 90
>   RSP: 0018:ffffb3378075bd38 EFLAGS: 00010286
>   RAX: 0000000000000080 RBX: ffff9156068049c0 RCX: ffffb3378075bd00
>   RDX: ffffffffa8411808 RSI: ffffffffa7f44f90 RDI: cccccc00746e6572
>   RBP: ffffb3378075bdb0 R08: ffffffffa779c05b R09: ffff915602f7c8e0
>   R10: 0000000000000080 R11: 0000000000000004 R12: ffffb3378075bd60
>   R13: ffff9156025a9090 R14: 0000000000000080 R15: ffff915607cab840
>   FS:  0000000000000000(0000) GS:ffff9159869d6000(0000) knlGS:0000000000000000
>   CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>   CR2: 00007fbd5f8e8210 CR3: 0000000102e42002 CR4: 00000000003706f0
>   DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>   DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
>   Call Trace:
>    <TASK>
>    brcmf_fws_rxreorder+0x562/0x610
>    ? brcmf_rx_frame+0x8c/0x130
>    ? __pfx_brcmf_proto_bcdc_rxreorder+0x10/0x10
>    brcmf_rx_frame+0x8c/0x130
>    brcmf_usb_rx_complete+0xee/0x130
>    __usb_hcd_giveback_urb+0x8f/0x100
>    vhci_rx_loop+0x3fb/0x480
>    ? __pfx_vhci_rx_loop+0x10/0x10
>    kthread+0xf6/0x1f0
>    ? __pfx_kthread+0x10/0x10
>    ret_from_fork+0x2f/0x50
>    ? __pfx_kthread+0x10/0x10
>    ret_from_fork_asm+0x1a/0x30
>    </TASK>
>   Modules linked in:
>   ---[ end trace 0000000000000000 ]---
> 
> A gdb back-trace (on a different machine):
> 
> #0  brcmu_pkt_buf_free_skb (skb=0xa56b6b6b6b6b6b6b)
>      at drivers/net/wireless/broadcom/brcm80211/brcmutil/utils.c:34
> #1  0xffffffff809ea198 in brcmf_fws_rxreorder (ifp=<optimized out>,
>      pkt=0xffffffd602f58940)
>      at drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c:1751
> #2  0xffffffff809e809a in brcmf_proto_bcdc_rxreorder (ifp=<optimized out>,
>      skb=<optimized out>)
>      at drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c:403
> #3  0xffffffff809e309e in brcmf_proto_rxreorder (skb=0xffffffd602f58940,
>      ifp=<optimized out>)
>      at drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h:114
> #4  brcmf_rx_frame (dev=<optimized out>, skb=skb@entry=0xffffffd602f58940,
>      handle_event=handle_event@entry=true, inirq=inirq@entry=true)
>      at drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c:510
> #5  0xffffffff809f5b2e in brcmf_usb_rx_complete (urb=0xffffffd6038041c0)
>      at drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:528
> #6  0xffffffff80b3f292 in __usb_hcd_giveback_urb (
>      urb=urb@entry=0xffffffd6038041c0) at drivers/usb/core/hcd.c:1650
> #7  0xffffffff80b3f3d0 in usb_hcd_giveback_urb (
>      hcd=hcd@entry=0xffffffd603dbc000, urb=urb@entry=0xffffffd6038041c0,
>      status=<optimized out>) at drivers/usb/core/hcd.c:1734
> #8  0xffffffff80be9fa2 in vhci_recv_ret_submit (pdu=0xffffffc6002f3dd8,
>      vdev=0xffffffd603dbc2d0) at drivers/usb/usbip/vhci_rx.c:107

Hi Robert,

Thanks for notifying us about this issue. Will come up with a patch and 
give proper attribution for this.

Regards,
Arend
Regards,
Arend
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.