aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-09-01 14:27:51 +0000
committerMark Johnston <markj@FreeBSD.org>2021-09-08 12:40:33 +0000
commitd30602a2b4952571ca4dcf302422cd86f4bfaa6a (patch)
treedf8abadd06fb533179f24931e3964b59d3f8f1b8
parent2d0d1d6e07bcaf7f25a4d2944170e1ec26c15d78 (diff)
downloadsrc-d30602a2b4952571ca4dcf302422cd86f4bfaa6a.tar.gz
src-d30602a2b4952571ca4dcf302422cd86f4bfaa6a.zip
sctp: Hold association locks across socket wakeups when freeing
At this point we do not hold the inpcb lock, so the only thing holding the socket reference live is the TCB lock, which needs to be acquired by sctp_inpcb_free() in order to destroy associations. Defer the unlock to until after we dereference the socket reference. Reported by: syzbot+1d0f2c4675de76a4cf1e@syzkaller.appspotmail.com Reported by: syzbot+fabee77954fe69d3a5ad@syzkaller.appspotmail.com Reviewed by: tuexen Sponsored by: The FreeBSD Foundation (cherry picked from commit d35be50f57797a400ff68a37777405029bf9730a)
-rw-r--r--sys/netinet/sctp_pcb.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 12f2d5d7fb76..fc3cd79c5d87 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -4785,8 +4785,6 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
sctp_timer_start(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL);
}
- SCTP_TCB_SEND_UNLOCK(stcb);
- SCTP_TCB_UNLOCK(stcb);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) ||
(inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE))
/* nothing around */
@@ -4796,6 +4794,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
sctp_sorwakeup(inp, so);
sctp_sowwakeup(inp, so);
}
+ SCTP_TCB_SEND_UNLOCK(stcb);
+ SCTP_TCB_UNLOCK(stcb);
#ifdef SCTP_LOG_CLOSING
sctp_log_closing(inp, stcb, 9);