From 15af8ae175af9bc83eef367977ee4a992af640bb Mon Sep 17 00:00:00 2001 From: jtl Date: Fri, 6 Apr 2018 16:48:11 +0000 Subject: [PATCH] Check that in_pcbfree() is only called once for each PCB. If that assumption is violated, "bad things" could follow. I believe such an assert would have detected some of the problems jch@ was chasing in PR 203175 (see r307551). We also use it in our internal TCP development efforts. And, in case a bug does slip through to released code, this change silently ignores subsequent calls to in_pcbfree(). Reviewed by: rrs Sponsored by: Netflix, Inc. Differential Revision: https://reviews.freebsd.org/D14990 --- sys/netinet/in_pcb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index e88207d15794..8545bd833a9c 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1288,6 +1288,13 @@ in_pcbfree(struct inpcb *inp) KASSERT(inp->inp_socket == NULL, ("%s: inp_socket != NULL", __func__)); + KASSERT((inp->inp_flags2 & INP_FREED) == 0, + ("%s: called twice for pcb %p", __func__, inp)); + if (inp->inp_flags2 & INP_FREED) { + INP_WUNLOCK(inp); + return; + } + #ifdef INVARIANTS if (pcbinfo == &V_tcbinfo) { INP_INFO_LOCK_ASSERT(pcbinfo);