From nobody Thu Jan 11 12:57:09 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4T9l7B0scCz55gT4; Thu, 11 Jan 2024 12:57:10 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4T9l7B0jGFz4CyM; Thu, 11 Jan 2024 12:57:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704977830; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WnUlnPwg/EfhxEdSxnafFVmiu7zw2it8erxRY0ZIDro=; b=plNRf4hHOwe31rdZi4vVW2qzd9tedaQrusz3myfHwBLBQmpNhUG4qSi1E7XmY3BLX5srLp idXOqr1fSdIIw57bahsR3W4vbcgrN1pyu/v8llCQF2b3jxvQsaBoqK4zvdTS9zRNTv+4tn YnmJ9e5odK99VXGpW5P61ZlwSu9UXdX0c4GakbSpRTUcDHX/ci1W2YwvzMLDLXOyf2cr+u HgDgR6ZC4e0HPdlXmN+PeizQ7qS+gzDEfqVD3cJlHVSx3ch5NruyWMmBQKHQC6U1b0O6a+ GvWYHTqWGXfjBqC/A9DmYufNA6UC2oYBOhiVl1BCCxUez+mE+PEZXwGIq6rCRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1704977830; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WnUlnPwg/EfhxEdSxnafFVmiu7zw2it8erxRY0ZIDro=; b=V4yAP0mL9euaO69Sam5Hnc1KP36m0NJuFGERtXsdQAVF27N2coz5wFktnGxccVmVl18a6A nvN3tylF70qAuSf/2SgYYQzXxxDmdSPSruYnr7sneGgegn6DNcgySufdZ4xSSTFmqMR68I 1jGk95ixWQjpH7fSIAFHEKEFZ17TgX/HenusZSC92CQgJFdn5DgF/6J+Kb9g5eqczeof3b oVp7bEUyyjm3VUw4yYuB5czdQ3Ek7xBV0A/d2nV4U4bBDZK0unZ/xGIskAFNV27GL1Z88x dXcsN+OzNVFocef8s+7uzwdhMp15uAoLH4VZ6uV6WBdFaDriK8G7H9f1KIJDtA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1704977830; a=rsa-sha256; cv=none; b=vuhoDBzO0BEM0rmWpHaKYmDPF3n2MYo1ByjgGIgS6ni+OrJcRaG2XiziyreqyG+70c2Ff7 GYTIa7NjsQ+/wt6XKZwRL/P1yPQVycZ1s4hfQsoV5z4IEuAlgcdH0/26aKGd1gQpyvYzbc Ync5yXJnOuozfbf3PV2/Cug8LKi1CIfjqeYFzRQIe8H5PKZTNfxsTS0FRkLhg5OuCbVfof kXI9nbyrQwePd6rO+NLx2Wo8mrEJDi6HdtmayifVBqDqBxqmUJabIMW6D+6rijRd37kVqO 0KFH+/VbGGo3/+9+6y4zxgZlhUP8MZR3fqvDWDy2fJL08Nf/Q9OOaSgNZvcjCQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4T9l796sqrzKMT; Thu, 11 Jan 2024 12:57:09 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 40BCv9Do054479; Thu, 11 Jan 2024 12:57:09 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 40BCv9Ev054476; Thu, 11 Jan 2024 12:57:09 GMT (envelope-from git) Date: Thu, 11 Jan 2024 12:57:09 GMT Message-Id: <202401111257.40BCv9Ev054476@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Michael Tuexen Subject: git: a8694dd1b951 - stable/13 - sctp: cleanup locking for notifications List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: tuexen X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: a8694dd1b95141ce2a058888e762aa950e3fa47d Auto-Submitted: auto-generated The branch stable/13 has been updated by tuexen: URL: https://cgit.FreeBSD.org/src/commit/?id=a8694dd1b95141ce2a058888e762aa950e3fa47d commit a8694dd1b95141ce2a058888e762aa950e3fa47d Author: Michael Tuexen AuthorDate: 2023-09-08 14:20:51 +0000 Commit: Michael Tuexen CommitDate: 2024-01-11 12:56:47 +0000 sctp: cleanup locking for notifications All notifications are now queued via sctp_ulp_notify(). Do the locking of the inp read lock there and validate this in all functions being used. This is one step in avoiding race conditions when closing the read end of an SCTP socket. (cherry picked from commit f9425b3a85e9e211b61e11ce8115bf73674bdf49) --- sys/netinet/sctp_auth.c | 12 ++--- sys/netinet/sctputil.c | 132 ++++++++++++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 57 deletions(-) diff --git a/sys/netinet/sctp_auth.c b/sys/netinet/sctp_auth.c index 3c1962233347..8bcb6d5243db 100644 --- a/sys/netinet/sctp_auth.c +++ b/sys/netinet/sctp_auth.c @@ -1706,13 +1706,9 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication, struct sctp_authkey_event *auth; struct sctp_queued_to_read *control; - if ((stcb == NULL) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { - /* If the socket is gone we are out of here */ - return; - } + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_AUTHEVNT)) /* event not enabled */ @@ -1757,7 +1753,7 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication, control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } /*- diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index b378a55250e0..e6121a1635b7 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -3147,10 +3147,11 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, ("sctp_notify_assoc_change: ABORT chunk provided for local termination")); KASSERT(!from_peer || !timedout, ("sctp_notify_assoc_change: timeouts can only be local")); - if (stcb == NULL) { - return; - } + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); inp = stcb->sctp_ep; + SCTP_INP_READ_LOCK_ASSERT(inp); + if (sctp_stcb_is_feature_on(inp, stcb, SCTP_PCB_FLAGS_RECVASSOCEVNT)) { notif_len = (unsigned int)sizeof(struct sctp_assoc_change); if (abort != NULL) { @@ -3231,7 +3232,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, control->tail_mbuf = m_notify; sctp_add_to_readq(inp, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } else { sctp_m_freem(m_notify); } @@ -3282,11 +3283,15 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state, struct sctp_paddr_change *spc; struct sctp_queued_to_read *control; - if ((stcb == NULL) || - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPADDREVNT)) { /* event not enabled */ return; } + m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_paddr_change), 0, M_NOWAIT, 1, MT_DATA); if (m_notify == NULL) return; @@ -3357,7 +3362,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state, control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3371,9 +3376,12 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, struct sctp_chunkhdr *chkhdr; int notifhdr_len, chk_len, chkhdr_len, padding_len, payload_len; - if ((stcb == NULL) || - (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && + sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { /* event not enabled */ return; } @@ -3486,7 +3494,7 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error, control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3499,12 +3507,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error, struct sctp_queued_to_read *control; int notifhdr_len; - if ((stcb == NULL) || - (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) && + sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { /* event not enabled */ return; } + if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) { notifhdr_len = sizeof(struct sctp_send_failed_event); } else { @@ -3582,7 +3594,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error, control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3592,8 +3604,11 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb, int so_locked) struct sctp_adaptation_event *sai; struct sctp_queued_to_read *control; - if ((stcb == NULL) || - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ADAPTATIONEVNT)) { /* event not enabled */ return; } @@ -3629,7 +3644,7 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb, int so_locked) control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3642,15 +3657,16 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error, struct sctp_queued_to_read *control; struct sockbuf *sb; - if ((stcb == NULL) || - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) { + KASSERT(aborted_control != NULL, ("aborted_control is NULL")); + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_PDAPIEVNT)) { /* event not enabled */ return; } - KASSERT(aborted_control != NULL, ("aborted_control is NULL")); - SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); - m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_pdapi_event), 0, M_NOWAIT, 1, MT_DATA); if (m_notify == NULL) /* no space left */ @@ -3703,6 +3719,10 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb, int so_locked) struct sctp_shutdown_event *sse; struct sctp_queued_to_read *control; + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + /* * For TCP model AND UDP connected sockets we will send an error up * when an SHUTDOWN completes @@ -3712,6 +3732,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb, int so_locked) /* mark socket closed for read/write and wakeup! */ socantsendmore(stcb->sctp_socket); } + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT)) { /* event not enabled */ return; @@ -3746,7 +3767,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb, int so_locked) control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3756,8 +3777,11 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb, int so_locked) struct sctp_sender_dry_event *event; struct sctp_queued_to_read *control; - if ((stcb == NULL) || - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_DRYEVNT)) { /* event not enabled */ return; } @@ -3793,7 +3817,7 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb, int so_locked) control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3803,13 +3827,10 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, int flag, int so_locked) struct sctp_queued_to_read *control; struct sctp_stream_change_event *stradd; - if ((stcb == NULL) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { - /* If the socket is gone we are out of here. */ - return; - } + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT)) { /* event not enabled */ return; @@ -3856,7 +3877,7 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, int flag, int so_locked) control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3866,13 +3887,10 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, int flag, int so_locked) struct sctp_queued_to_read *control; struct sctp_assoc_reset_event *strasoc; - if ((stcb == NULL) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || - (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || - (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET)) { - /* If the socket is gone we are out of here. */ - return; - } + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT)) { /* event not enabled */ return; @@ -3913,7 +3931,7 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, int flag, int so_locked) control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3925,8 +3943,11 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb, struct sctp_stream_reset_event *strreset; int len; - if ((stcb == NULL) || - (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT))) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_RESETEVNT)) { /* event not enabled */ return; } @@ -3977,7 +3998,7 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb, control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); + SCTP_READ_LOCK_HELD, so_locked); } static void @@ -3990,10 +4011,14 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, unsigned int notif_len; uint16_t chunk_len; - if ((stcb == NULL) || - sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) { + KASSERT(stcb != NULL, ("stcb == NULL")); + SCTP_TCB_LOCK_ASSERT(stcb); + SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); + + if (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVPEERERR)) { return; } + if (chunk != NULL) { chunk_len = ntohs(chunk->ch.chunk_length); /* @@ -4039,7 +4064,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, control->tail_mbuf = m_notify; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, 1, - SCTP_READ_LOCK_NOT_HELD, so_locked); + SCTP_READ_LOCK_HELD, so_locked); } else { sctp_m_freem(m_notify); } @@ -4068,9 +4093,15 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, return; } } + if (notification != SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION) { + SCTP_INP_READ_LOCK(inp); + } + SCTP_INP_READ_LOCK_ASSERT(inp); + if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ)) { + SCTP_INP_READ_UNLOCK(inp); return; } @@ -4218,6 +4249,9 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, __func__, notification, notification); break; } + if (notification != SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION) { + SCTP_INP_READ_UNLOCK(inp); + } } void