git: c7cc79dba23d - stable/13 - sctp: improve locking

From: Michael Tuexen <tuexen_at_FreeBSD.org>
Date: Wed, 01 Feb 2023 22:40:47 UTC
The branch stable/13 has been updated by tuexen:

URL: https://cgit.FreeBSD.org/src/commit/?id=c7cc79dba23dc7d3b8ee3afd1b0ee2726653f2eb

commit c7cc79dba23dc7d3b8ee3afd1b0ee2726653f2eb
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2022-04-15 11:58:45 +0000
Commit:     Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2023-02-01 22:40:21 +0000

    sctp: improve locking
    
    Hold a refcount while giving up an stcp lock. This issue was
    found by running syzkaller.
    
    (cherry picked from commit e0127ea4c6b50a5bf239482d8a99ae418174aee5)
---
 sys/netinet/sctp_input.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 8b6a6446f486..eb4ad6de12f1 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -2326,15 +2326,22 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
 	/*
 	 * compute the signature/digest for the cookie
 	 */
-	ep = &(*inp_p)->sctp_ep;
-	l_inp = *inp_p;
-	if (l_stcb) {
+	if (l_stcb != NULL) {
+		atomic_add_int(&l_stcb->asoc.refcnt, 1);
 		SCTP_TCB_UNLOCK(l_stcb);
 	}
+	l_inp = *inp_p;
 	SCTP_INP_RLOCK(l_inp);
-	if (l_stcb) {
+	if (l_stcb != NULL) {
 		SCTP_TCB_LOCK(l_stcb);
+		atomic_subtract_int(&l_stcb->asoc.refcnt, 1);
 	}
+	if (l_inp->sctp_flags & (SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_SOCKET_ALLGONE)) {
+		SCTP_INP_RUNLOCK(l_inp);
+		sctp_m_freem(m_sig);
+		return (NULL);
+	}
+	ep = &(*inp_p)->sctp_ep;
 	/* which cookie is it? */
 	if ((cookie->time_entered.tv_sec < (long)ep->time_of_secret_change) &&
 	    (ep->current_secret_number != ep->last_secret_number)) {