Date: Thu, 28 Feb 2013 19:10:35 +0000 From: Ed Maste <emaste@freebsd.org> To: freebsd-net@freebsd.org Subject: [PATCH] Handle PACKET_TAG_IPFORWARD and TIMEWAIT state Message-ID: <20130228191035.GA36576@sandvine.com>
index | next in thread | raw e-mail
[-- Attachment #1 --]
SVN rev 244157 introduced a fix for a crash in tcp_input() which would
occur in the case of a packet with a PACKET_TAG_IPFORWARD m_tag arriving
for a flow in TIMEWAIT. Such packets resulted in a goto findpcb an a
double free of the m_tag.
Unfortunately the fix causes the fwd_tag to be lost for any subsequent
trips through the pcb lookup code. The attached patch keeps the fwd_tag
around until finished with pcb lookup.
The #ifdef INET / INET6 is a bit torturous, but no worse than what was
there.
[-- Attachment #2 --]
Index: tcp_input.c
===================================================================
--- tcp_input.c (revision 247398)
+++ tcp_input.c (working copy)
@@ -768,6 +768,28 @@
} else
ti_locked = TI_UNLOCKED;
+ /*
+ * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
+ */
+#ifdef INET6
+ if (isipv6 && (m->m_flags & M_IP6_NEXTHOP)) {
+ m->m_flags &= ~M_IP6_NEXTHOP;
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ m_tag_unlink(m, fwd_tag);
+ }
+#ifdef INET
+ else if (!isipv6 && (m->m_flags & M_IP_NEXTHOP)) {
+#endif
+#elif defined(INET)
+ if (m->m_flags & M_IP_NEXTHOP) {
+#endif
+#if defined(INET)
+ m->m_flags &= ~M_IP_NEXTHOP;
+ fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
+ m_tag_unlink(m, fwd_tag);
+ }
+#endif
+
findpcb:
#ifdef INVARIANTS
if (ti_locked == TI_WLOCKED) {
@@ -777,23 +799,7 @@
}
#endif
- /*
- * Grab info from PACKET_TAG_IPFORWARD tag prepended to the chain.
- */
- if (
#ifdef INET6
- (isipv6 && (m->m_flags & M_IP6_NEXTHOP))
-#ifdef INET
- || (!isipv6 && (m->m_flags & M_IP_NEXTHOP))
-#endif
-#endif
-#if defined(INET) && !defined(INET6)
- (m->m_flags & M_IP_NEXTHOP)
-#endif
- )
- fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL);
-
-#ifdef INET6
if (isipv6 && fwd_tag != NULL) {
struct sockaddr_in6 *next_hop6;
@@ -817,10 +823,6 @@
th->th_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_WLOCKPCB, m->m_pkthdr.rcvif);
}
- /* Remove the tag from the packet. We don't need it anymore. */
- m_tag_delete(m, fwd_tag);
- m->m_flags &= ~M_IP6_NEXTHOP;
- fwd_tag = NULL;
} else if (isipv6) {
inp = in6_pcblookup_mbuf(&V_tcbinfo, &ip6->ip6_src,
th->th_sport, &ip6->ip6_dst, th->th_dport,
@@ -855,10 +857,6 @@
th->th_dport, INPLOOKUP_WILDCARD |
INPLOOKUP_WLOCKPCB, m->m_pkthdr.rcvif);
}
- /* Remove the tag from the packet. We don't need it anymore. */
- m_tag_delete(m, fwd_tag);
- m->m_flags &= ~M_IP_NEXTHOP;
- fwd_tag = NULL;
} else
inp = in_pcblookup_mbuf(&V_tcbinfo, ip->ip_src,
th->th_sport, ip->ip_dst, th->th_dport,
@@ -970,6 +968,8 @@
if (tcp_twcheck(inp, &to, th, m, tlen))
goto findpcb;
INP_INFO_WUNLOCK(&V_tcbinfo);
+ if (fwd_tag != NULL)
+ m_tag_free(fwd_tag);
return;
}
/*
@@ -1020,6 +1020,10 @@
}
INP_INFO_WLOCK_ASSERT(&V_tcbinfo);
}
+ if (fwd_tag) {
+ m_tag_free(fwd_tag);
+ fwd_tag = NULL;
+ }
#ifdef MAC
INP_WLOCK_ASSERT(inp);
@@ -1429,6 +1433,8 @@
drop:
INP_INFO_UNLOCK_ASSERT(&V_tcbinfo);
+ if (fwd_tag != NULL)
+ m_tag_free(fwd_tag);
if (s != NULL)
free(s, M_TCPLOG);
if (m != NULL)
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130228191035.GA36576>
