Author: avos
Date: Tue Sep  6 06:40:59 2016
New Revision: 305465
URL: https://svnweb.freebsd.org/changeset/base/305465

Log:
  rum: fix frame length checks in Rx path.
  
  Split usbd_xfer_status() check:
  - Check xfer length: must be longer, than Rx descriptor size.
  - Check frame size: must be shorter than xfer length.
  - Discard too short frames.
  
  Tested with WUSB54GC, STA/MONITOR modes.

Modified:
  head/sys/dev/usb/wlan/if_rum.c

Modified: head/sys/dev/usb/wlan/if_rum.c
==============================================================================
--- head/sys/dev/usb/wlan/if_rum.c      Tue Sep  6 06:26:24 2016        
(r305464)
+++ head/sys/dev/usb/wlan/if_rum.c      Tue Sep  6 06:40:59 2016        
(r305465)
@@ -1151,7 +1151,7 @@ rum_bulk_read_callback(struct usb_xfer *
 
                DPRINTFN(15, "rx done, actlen=%d\n", len);
 
-               if (len < (int)(RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) {
+               if (len < RT2573_RX_DESC_SIZE) {
                        DPRINTF("%s: xfer too short %d\n",
                            device_get_nameunit(sc->sc_dev), len);
                        counter_u64_add(ic->ic_ierrors, 1);
@@ -1165,6 +1165,20 @@ rum_bulk_read_callback(struct usb_xfer *
                rssi = rum_get_rssi(sc, sc->sc_rx_desc.rssi);
                flags = le32toh(sc->sc_rx_desc.flags);
                sc->last_rx_flags = flags;
+               if (len < ((flags >> 16) & 0xfff)) {
+                       DPRINTFN(5, "%s: frame is truncated from %d to %d "
+                           "bytes\n", device_get_nameunit(sc->sc_dev),
+                           (flags >> 16) & 0xfff, len);
+                       counter_u64_add(ic->ic_ierrors, 1);
+                       goto tr_setup;
+               }
+               len = (flags >> 16) & 0xfff;
+               if (len < sizeof(struct ieee80211_frame_ack)) {
+                       DPRINTFN(5, "%s: frame too short %d\n",
+                           device_get_nameunit(sc->sc_dev), len);
+                       counter_u64_add(ic->ic_ierrors, 1);
+                       goto tr_setup;
+               }
                if (flags & RT2573_RX_CRC_ERROR) {
                        /*
                         * This should not happen since we did not
@@ -1210,7 +1224,7 @@ rum_bulk_read_callback(struct usb_xfer *
                }
 
                /* finalize mbuf */
-               m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;
+               m->m_pkthdr.len = m->m_len = len;
 
                if (ieee80211_radiotap_active(ic)) {
                        struct rum_rx_radiotap_header *tap = &sc->sc_rxtap;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to