svn commit: r360727 - stable/11/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Thu May 7 00:50:51 UTC 2020
Author: tuexen
Date: Thu May 7 00:50:50 2020
New Revision: 360727
URL: https://svnweb.freebsd.org/changeset/base/360727
Log:
MFC r350626: Fix a locking issue in SCTP
Fix a locking issue in sctp_accept.
PR: 238520
Reported by: pho
Modified:
stable/11/sys/netinet/sctp_usrreq.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/11/sys/netinet/sctp_usrreq.c Thu May 7 00:44:15 2020 (r360726)
+++ stable/11/sys/netinet/sctp_usrreq.c Thu May 7 00:50:50 2020 (r360727)
@@ -7229,28 +7229,56 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (ECONNRESET);
}
- SCTP_INP_RLOCK(inp);
+ SCTP_INP_WLOCK(inp);
if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) {
- SCTP_INP_RUNLOCK(inp);
+ SCTP_INP_WUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EOPNOTSUPP);
return (EOPNOTSUPP);
}
if (so->so_state & SS_ISDISCONNECTED) {
- SCTP_INP_RUNLOCK(inp);
+ SCTP_INP_WUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ECONNABORTED);
return (ECONNABORTED);
}
stcb = LIST_FIRST(&inp->sctp_asoc_list);
if (stcb == NULL) {
- SCTP_INP_RUNLOCK(inp);
+ SCTP_INP_WUNLOCK(inp);
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
return (ECONNRESET);
}
SCTP_TCB_LOCK(stcb);
- SCTP_INP_RUNLOCK(inp);
store = stcb->asoc.primary_destination->ro._l_addr;
SCTP_CLEAR_SUBSTATE(stcb, SCTP_STATE_IN_ACCEPT_QUEUE);
- SCTP_TCB_UNLOCK(stcb);
+ /* Wake any delayed sleep action */
+ if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
+ inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
+ if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
+ inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
+ SOCKBUF_LOCK(&inp->sctp_socket->so_snd);
+ if (sowriteable(inp->sctp_socket)) {
+ sowwakeup_locked(inp->sctp_socket);
+ } else {
+ SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd);
+ }
+ }
+ if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
+ inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
+ SOCKBUF_LOCK(&inp->sctp_socket->so_rcv);
+ if (soreadable(inp->sctp_socket)) {
+ sctp_defered_wakeup_cnt++;
+ sorwakeup_locked(inp->sctp_socket);
+ } else {
+ SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv);
+ }
+ }
+ }
+ SCTP_INP_WUNLOCK(inp);
+ if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
+ sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
+ SCTP_FROM_SCTP_USRREQ + SCTP_LOC_19);
+ } else {
+ SCTP_TCB_UNLOCK(stcb);
+ }
switch (store.sa.sa_family) {
#ifdef INET
case AF_INET:
@@ -7291,40 +7319,6 @@ sctp_accept(struct socket *so, struct sockaddr **addr)
default:
/* TSNH */
break;
- }
- /* Wake any delayed sleep action */
- if (inp->sctp_flags & SCTP_PCB_FLAGS_DONT_WAKE) {
- SCTP_INP_WLOCK(inp);
- inp->sctp_flags &= ~SCTP_PCB_FLAGS_DONT_WAKE;
- if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEOUTPUT) {
- inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEOUTPUT;
- SCTP_INP_WUNLOCK(inp);
- SOCKBUF_LOCK(&inp->sctp_socket->so_snd);
- if (sowriteable(inp->sctp_socket)) {
- sowwakeup_locked(inp->sctp_socket);
- } else {
- SOCKBUF_UNLOCK(&inp->sctp_socket->so_snd);
- }
- SCTP_INP_WLOCK(inp);
- }
- if (inp->sctp_flags & SCTP_PCB_FLAGS_WAKEINPUT) {
- inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAKEINPUT;
- SCTP_INP_WUNLOCK(inp);
- SOCKBUF_LOCK(&inp->sctp_socket->so_rcv);
- if (soreadable(inp->sctp_socket)) {
- sctp_defered_wakeup_cnt++;
- sorwakeup_locked(inp->sctp_socket);
- } else {
- SOCKBUF_UNLOCK(&inp->sctp_socket->so_rcv);
- }
- SCTP_INP_WLOCK(inp);
- }
- SCTP_INP_WUNLOCK(inp);
- }
- if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
- SCTP_TCB_LOCK(stcb);
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC,
- SCTP_FROM_SCTP_USRREQ + SCTP_LOC_19);
}
return (0);
}
More information about the svn-src-stable-11
mailing list