Author: tuexen
Date: Sun Mar  3 19:55:06 2019
New Revision: 344742
URL: https://svnweb.freebsd.org/changeset/base/344742

Log:
  Allocate an assocition id and register the stcb with holding the lock.
  This avoids a race where stcbs can be found, which are not completely
  initialized.
  
  This was found by running syzkaller.
  
  MFC after:            3 days

Modified:
  head/sys/netinet/sctp_pcb.c

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Sun Mar  3 18:57:48 2019        (r344741)
+++ head/sys/netinet/sctp_pcb.c Sun Mar  3 19:55:06 2019        (r344742)
@@ -4157,11 +4157,9 @@ sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sc
        struct sctpasochead *head;
        struct sctp_tcb *lstcb;
 
-       SCTP_INP_WLOCK(inp);
 try_again:
        if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
                /* TSNH */
-               SCTP_INP_WUNLOCK(inp);
                return (0);
        }
        /*
@@ -4180,8 +4178,7 @@ try_again:
        head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, 
inp->hashasocidmark)];
        LIST_INSERT_HEAD(head, stcb, sctp_tcbasocidhash);
        stcb->asoc.in_asocid_hash = 1;
-       SCTP_INP_WUNLOCK(inp);
-       return id;
+       return (id);
 }
 
 /*
@@ -4344,7 +4341,6 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockadd
        memset(stcb, 0, sizeof(*stcb));
        asoc = &stcb->asoc;
 
-       asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
        SCTP_TCB_LOCK_INIT(stcb);
        SCTP_TCB_SEND_LOCK_INIT(stcb);
        stcb->rport = rport;
@@ -4355,7 +4351,6 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockadd
                /* failed */
                SCTP_TCB_LOCK_DESTROY(stcb);
                SCTP_TCB_SEND_LOCK_DESTROY(stcb);
-               LIST_REMOVE(stcb, sctp_tcbasocidhash);
                SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
                SCTP_DECR_ASOC_COUNT();
                *error = err;
@@ -4368,7 +4363,6 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockadd
                /* inpcb freed while alloc going on */
                SCTP_TCB_LOCK_DESTROY(stcb);
                SCTP_TCB_SEND_LOCK_DESTROY(stcb);
-               LIST_REMOVE(stcb, sctp_tcbasocidhash);
                SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
                SCTP_INP_WUNLOCK(inp);
                SCTP_INP_INFO_WUNLOCK();
@@ -4379,6 +4373,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockadd
        }
        SCTP_TCB_LOCK(stcb);
 
+       asoc->assoc_id = sctp_aloc_a_assoc_id(inp, stcb);
        /* now that my_vtag is set, add it to the hash */
        head = 
&SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, 
SCTP_BASE_INFO(hashasocmark))];
        /* put it in the bucket in the vtag hash of assoc's for the system */
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to