Module Name:    src
Committed By:   maxv
Date:           Thu Jun 21 16:53:10 UTC 2018

Modified Files:
        src/sys/net80211: ieee80211_input.c

Log Message:
Fix use-after-free, m_cat can free m.


To generate a diff of this commit:
cvs rdiff -u -r1.111 -r1.112 src/sys/net80211/ieee80211_input.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net80211/ieee80211_input.c
diff -u src/sys/net80211/ieee80211_input.c:1.111 src/sys/net80211/ieee80211_input.c:1.112
--- src/sys/net80211/ieee80211_input.c:1.111	Tue May  8 07:02:07 2018
+++ src/sys/net80211/ieee80211_input.c	Thu Jun 21 16:53:10 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ieee80211_input.c,v 1.111 2018/05/08 07:02:07 maxv Exp $	*/
+/*	$NetBSD: ieee80211_input.c,v 1.112 2018/06/21 16:53:10 maxv Exp $	*/
 
 /*
  * Copyright (c) 2001 Atsushi Onoe
@@ -37,7 +37,7 @@
 __FBSDID("$FreeBSD: src/sys/net80211/ieee80211_input.c,v 1.81 2005/08/10 16:22:29 sam Exp $");
 #endif
 #ifdef __NetBSD__
-__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.111 2018/05/08 07:02:07 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ieee80211_input.c,v 1.112 2018/06/21 16:53:10 maxv Exp $");
 #endif
 
 #ifdef _KERNEL_OPT
@@ -762,14 +762,15 @@ ieee80211_defrag(struct ieee80211com *ic
 {
 	struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
 	struct ieee80211_frame *lwh;
-	u_int16_t rxseq;
+	u_int16_t rxseq, iseq;
 	u_int8_t fragno;
 	const u_int8_t more_frag = wh->i_fc[1] & IEEE80211_FC1_MORE_FRAG;
 	struct mbuf *mfrag;
 
 	IASSERT(!IEEE80211_IS_MULTICAST(wh->i_addr1), ("multicast fragm?"));
 
-	rxseq = le16toh(*(u_int16_t *)wh->i_seq);
+	iseq = *(u_int16_t *)wh->i_seq;
+	rxseq = le16toh(iseq);
 	fragno = rxseq & IEEE80211_SEQ_FRAG_MASK;
 
 	/* Quick way out, if there's nothing to defragment */
@@ -827,16 +828,19 @@ ieee80211_defrag(struct ieee80211com *ic
 		}
 		mfrag = m;
 	} else {
+		int mlen;
+
 		/* Strip header and concatenate */
 		m_adj(m, hdrspace);
+		mlen = m->m_pkthdr.len;
 		m_cat(mfrag, m);
 
 		/* NB: m_cat doesn't update the packet header */
-		mfrag->m_pkthdr.len += m->m_pkthdr.len;
+		mfrag->m_pkthdr.len += mlen;
 
 		/* track last seqnum and fragno */
 		lwh = mtod(mfrag, struct ieee80211_frame *);
-		*(u_int16_t *)lwh->i_seq = *(u_int16_t *)wh->i_seq;
+		*(u_int16_t *)lwh->i_seq = iseq;
 	}
 
 	if (more_frag) {

Reply via email to