From 9c5ca6f2476e7d7b08a0dfc4f72cce52a98d7cc3 Mon Sep 17 00:00:00 2001 From: Michael Tuexen Date: Mon, 8 Aug 2016 08:20:10 +0000 Subject: [PATCH] Fix a locking issue found by stress testing with tsctp. The inp read lock neeeds to be held when considering control->do_not_ref_stcb. MFC after: 3 days --- sys/netinet/sctputil.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index bebf5f0cde4..148b0478a1f 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -5497,20 +5497,16 @@ restart_nosblocks: } /* Clear the held length since there is something to read */ control->held_length = 0; - if (hold_rlock) { - SCTP_INP_READ_UNLOCK(inp); - hold_rlock = 0; - } found_one: /* * If we reach here, control has a some data for us to read off. * Note that stcb COULD be NULL. */ - control->some_taken++; - if (hold_sblock) { - SOCKBUF_UNLOCK(&so->so_rcv); - hold_sblock = 0; + if (hold_rlock == 0) { + hold_rlock = 1; + SCTP_INP_READ_LOCK(inp); } + control->some_taken++; stcb = control->stcb; if (stcb) { if ((control->do_not_ref_stcb == 0) && @@ -5684,6 +5680,14 @@ found_one: } #endif } + if (hold_rlock) { + SCTP_INP_READ_UNLOCK(inp); + hold_rlock = 0; + } + if (hold_sblock) { + SOCKBUF_UNLOCK(&so->so_rcv); + hold_sblock = 0; + } /* now copy out what data we can */ if (mp == NULL) { /* copy out each mbuf in the chain up to length */