diff options
author | wpaul <wpaul@FreeBSD.org> | 1999-07-04 14:40:22 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 1999-07-04 14:40:22 +0000 |
commit | 288aade3988789e6689bea72fa6552aa19747d68 (patch) | |
tree | a8dc9ff6959b4d485c79bf23bd46ba2b8aea8e17 /sys | |
parent | 84d49b35c9328adf6a221dd5c28ffebf154a2a4f (diff) | |
download | FreeBSD-src-288aade3988789e6689bea72fa6552aa19747d68.zip FreeBSD-src-288aade3988789e6689bea72fa6552aa19747d68.tar.gz |
Patch the WaveLAN/IEEE driver to detect and reject oversized received
frames (or just insane received packet lengths generated due to errors
reading from the NIC's internal buffers). Anything too large to fit
safely into an mbuf cluster buffer is discarded and an error logged.
I have not observed this problem with my own cards, but on user has
reported it and adding the sanity test seems reasonable in any case.
Problem noted and patch provided by: Per Andersson <per@cdg.chalmers.se>
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/wi/if_wi.c | 21 | ||||
-rw-r--r-- | sys/i386/isa/if_wi.c | 21 |
2 files changed, 38 insertions, 4 deletions
diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 0a95152..5b1ba03c 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_wi.c,v 1.55 1999/06/06 16:41:44 wpaul Exp $ + * $Id: if_wi.c,v 1.56 1999/07/04 14:35:23 wpaul Exp $ */ /* @@ -116,7 +116,7 @@ #if !defined(lint) static const char rcsid[] = - "$Id: if_wi.c,v 1.55 1999/06/06 16:41:44 wpaul Exp $"; + "$Id: if_wi.c,v 1.56 1999/07/04 14:35:23 wpaul Exp $"; #endif static struct wi_softc wi_softc[NWI]; @@ -415,6 +415,14 @@ static void wi_rxeof(sc) if (rx_frame.wi_status == WI_STAT_1042 || rx_frame.wi_status == WI_STAT_TUNNEL || rx_frame.wi_status == WI_STAT_WMP_MSG) { + if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { + printf("wi%d: oversized packet received " + "(wi_dat_len=%d, wi_status=0x%x)\n", sc->wi_unit, + rx_frame.wi_dat_len, rx_frame.wi_status); + m_freem(m); + ifp->if_ierrors++; + return; + } m->m_pkthdr.len = m->m_len = rx_frame.wi_dat_len + WI_SNAPHDR_LEN; @@ -433,6 +441,15 @@ static void wi_rxeof(sc) return; } } else { + if((rx_frame.wi_dat_len + + sizeof(struct ether_header)) > MCLBYTES) { + printf("wi%d: oversized packet received " + "(wi_dat_len=%d, wi_status=0x%x)\n", sc->wi_unit, + rx_frame.wi_dat_len, rx_frame.wi_status); + m_freem(m); + ifp->if_ierrors++; + return; + } m->m_pkthdr.len = m->m_len = rx_frame.wi_dat_len + sizeof(struct ether_header); diff --git a/sys/i386/isa/if_wi.c b/sys/i386/isa/if_wi.c index 0a95152..5b1ba03c 100644 --- a/sys/i386/isa/if_wi.c +++ b/sys/i386/isa/if_wi.c @@ -29,7 +29,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: if_wi.c,v 1.55 1999/06/06 16:41:44 wpaul Exp $ + * $Id: if_wi.c,v 1.56 1999/07/04 14:35:23 wpaul Exp $ */ /* @@ -116,7 +116,7 @@ #if !defined(lint) static const char rcsid[] = - "$Id: if_wi.c,v 1.55 1999/06/06 16:41:44 wpaul Exp $"; + "$Id: if_wi.c,v 1.56 1999/07/04 14:35:23 wpaul Exp $"; #endif static struct wi_softc wi_softc[NWI]; @@ -415,6 +415,14 @@ static void wi_rxeof(sc) if (rx_frame.wi_status == WI_STAT_1042 || rx_frame.wi_status == WI_STAT_TUNNEL || rx_frame.wi_status == WI_STAT_WMP_MSG) { + if((rx_frame.wi_dat_len + WI_SNAPHDR_LEN) > MCLBYTES) { + printf("wi%d: oversized packet received " + "(wi_dat_len=%d, wi_status=0x%x)\n", sc->wi_unit, + rx_frame.wi_dat_len, rx_frame.wi_status); + m_freem(m); + ifp->if_ierrors++; + return; + } m->m_pkthdr.len = m->m_len = rx_frame.wi_dat_len + WI_SNAPHDR_LEN; @@ -433,6 +441,15 @@ static void wi_rxeof(sc) return; } } else { + if((rx_frame.wi_dat_len + + sizeof(struct ether_header)) > MCLBYTES) { + printf("wi%d: oversized packet received " + "(wi_dat_len=%d, wi_status=0x%x)\n", sc->wi_unit, + rx_frame.wi_dat_len, rx_frame.wi_status); + m_freem(m); + ifp->if_ierrors++; + return; + } m->m_pkthdr.len = m->m_len = rx_frame.wi_dat_len + sizeof(struct ether_header); |