summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_timewait.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2004-11-23 16:23:13 +0000
committerrwatson <rwatson@FreeBSD.org>2004-11-23 16:23:13 +0000
commit93fe353ec5725020e33859a4dcde70dd9c0334f3 (patch)
treeb67ae46e3a46c39c67d0c18cfa67d7950a7ab0a6 /sys/netinet/tcp_timewait.c
parent32947f494f39ebc1429459b4beb89f1c642abe0a (diff)
downloadFreeBSD-src-93fe353ec5725020e33859a4dcde70dd9c0334f3.zip
FreeBSD-src-93fe353ec5725020e33859a4dcde70dd9c0334f3.tar.gz
Assert the inpcb lock in tcp_twstart(), which does both read-modify-write
on the tcpcb, but also calls into tcp_close() and tcp_twrespond(). Annotate that tcp_twrecycleable() requires the inpcb lock because it does a series of non-atomic reads of the tcpcb, but is currently called without the inpcb lock by the caller. This is a bug. Assert the inpcb lock in tcp_twclose() as it performs a read-modify-write of the timewait structure/inpcb, and calls in_pcbdetach() which requires the lock. Assert the inpcb lock in tcp_twrespond(), as it performs multiple non-atomic reads of the tcptw and inpcb structures, as well as calling mac_create_mbuf_from_inpcb(), tcpip_fillheaders(), which require the inpcb lock. MFC after: 2 weeks
Diffstat (limited to 'sys/netinet/tcp_timewait.c')
-rw-r--r--sys/netinet/tcp_timewait.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/sys/netinet/tcp_timewait.c b/sys/netinet/tcp_timewait.c
index e3fcdf1..8064f2b 100644
--- a/sys/netinet/tcp_timewait.c
+++ b/sys/netinet/tcp_timewait.c
@@ -1624,6 +1624,8 @@ tcp_twstart(tp)
int tw_time, acknow;
struct socket *so;
+ INP_LOCK_ASSERT(tp->t_inpcb);
+
tw = uma_zalloc(tcptw_zone, M_NOWAIT);
if (tw == NULL) {
tw = tcp_timer_2msl_tw(1);
@@ -1694,6 +1696,10 @@ tcp_twstart(tp)
* Determine if the ISN we will generate has advanced beyond the last
* sequence number used by the previous connection. If so, indicate
* that it is safe to recycle this tw socket by returning 1.
+ *
+ * XXXRW: This function should assert the inpcb lock as it does multiple
+ * non-atomic reads from the tcptw, but is currently * called without it from
+ * in_pcb.c:in_pcblookup_local().
*/
int
tcp_twrecycleable(struct tcptw *tw)
@@ -1716,6 +1722,8 @@ tcp_twclose(struct tcptw *tw, int reuse)
struct inpcb *inp;
inp = tw->tw_inpcb;
+ INP_LOCK_ASSERT(inp);
+
tw->tw_inpcb = NULL;
tcp_timer_2msl_stop(tw);
inp->inp_ppcb = NULL;
@@ -1749,6 +1757,8 @@ tcp_twrespond(struct tcptw *tw, int flags)
int isipv6 = inp->inp_inc.inc_isipv6;
#endif
+ INP_LOCK_ASSERT(inp);
+
m = m_gethdr(M_DONTWAIT, MT_HEADER);
if (m == NULL)
return (ENOBUFS);
OpenPOWER on IntegriCloud