Date: Fri, 18 Jun 2010 09:01:44 +0000 (UTC) From: Michael Tuexen <tuexen@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r209289 - head/sys/netinet Message-ID: <201006180901.o5I91iHY009107@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: tuexen Date: Fri Jun 18 09:01:44 2010 New Revision: 209289 URL: http://svn.freebsd.org/changeset/base/209289 Log: Fix a rece condition in the shutdown handling. The race condition resulted in a panic. MFC after: 3 days Modified: head/sys/netinet/sctp.h head/sys/netinet/sctp_usrreq.c head/sys/netinet/sctputil.c Modified: head/sys/netinet/sctp.h ============================================================================== --- head/sys/netinet/sctp.h Fri Jun 18 08:51:20 2010 (r209288) +++ head/sys/netinet/sctp.h Fri Jun 18 09:01:44 2010 (r209289) @@ -442,6 +442,7 @@ struct sctp_error_unrecognized_chunk { #define SCTP_PCB_FLAGS_BLOCKING_IO 0x08000000 #define SCTP_PCB_FLAGS_SOCKET_GONE 0x10000000 #define SCTP_PCB_FLAGS_SOCKET_ALLGONE 0x20000000 +#define SCTP_PCB_FLAGS_SOCKET_CANT_READ 0x40000000 /* flags to copy to new PCB */ #define SCTP_PCB_COPY_FLAGS (SCTP_PCB_FLAGS_BOUNDALL|\ SCTP_PCB_FLAGS_WAKEINPUT|\ Modified: head/sys/netinet/sctp_usrreq.c ============================================================================== --- head/sys/netinet/sctp_usrreq.c Fri Jun 18 08:51:20 2010 (r209288) +++ head/sys/netinet/sctp_usrreq.c Fri Jun 18 09:01:44 2010 (r209289) @@ -947,11 +947,30 @@ sctp_flush(struct socket *so, int how) * they will not be able to read the data, the socket will block * that from happening. */ + struct sctp_inpcb *inp; + + inp = (struct sctp_inpcb *)so->so_pcb; + if (inp == NULL) { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + return EINVAL; + } + SCTP_INP_RLOCK(inp); + /* For the 1 to many model this does nothing */ + if (inp->sctp_flags & SCTP_PCB_FLAGS_UDPTYPE) { + SCTP_INP_RUNLOCK(inp); + return (0); + } + SCTP_INP_RUNLOCK(inp); if ((how == PRU_FLUSH_RD) || (how == PRU_FLUSH_RDWR)) { /* * First make sure the sb will be happy, we don't use these * except maybe the count */ + SCTP_INP_WLOCK(inp); + SCTP_INP_READ_LOCK(inp); + inp->sctp_flags |= SCTP_PCB_FLAGS_SOCKET_CANT_READ; + SCTP_INP_READ_UNLOCK(inp); + SCTP_INP_WUNLOCK(inp); so->so_rcv.sb_cc = 0; so->so_rcv.sb_mbcnt = 0; so->so_rcv.sb_mb = NULL; Modified: head/sys/netinet/sctputil.c ============================================================================== --- head/sys/netinet/sctputil.c Fri Jun 18 08:51:20 2010 (r209288) +++ head/sys/netinet/sctputil.c Fri Jun 18 09:01:44 2010 (r209289) @@ -3185,6 +3185,9 @@ sctp_notify_partial_delivery_indication( /* event not enabled */ return; } + if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { + return; + } m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_DONTWAIT, 1, MT_DATA); if (m_notify == NULL) /* no space left */ @@ -4365,6 +4368,17 @@ sctp_add_to_readq(struct sctp_inpcb *inp } if (inp_read_lock_held == 0) SCTP_INP_READ_LOCK(inp); + if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { + sctp_free_remote_addr(control->whoFrom); + if (control->data) { + sctp_m_freem(control->data); + control->data = NULL; + } + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), control); + if (inp_read_lock_held == 0) + SCTP_INP_READ_UNLOCK(inp); + return; + } if (!(control->spec_flags & M_NOTIFICATION)) { atomic_add_int(&inp->total_recvs, 1); if (!control->do_not_ref_stcb) { @@ -4405,6 +4419,8 @@ sctp_add_to_readq(struct sctp_inpcb *inp control->tail_mbuf = prev; } else { /* Everything got collapsed out?? */ + sctp_free_remote_addr(control->whoFrom); + SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), control); if (inp_read_lock_held == 0) SCTP_INP_READ_UNLOCK(inp); return; @@ -4477,6 +4493,10 @@ get_out: } return (-1); } + if (inp && (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) { + SCTP_INP_READ_UNLOCK(inp); + return 0; + } if (control->end_added) { /* huh this one is complete? */ goto get_out;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006180901.o5I91iHY009107>