Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 6 Sep 2016 06:40:59 +0000 (UTC)
From:      Andriy Voskoboinyk <avos@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r305465 - head/sys/dev/usb/wlan
Message-ID:  <201609060640.u866exUK095618@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609060640.u866exUK095618>