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) {