Author: tuexen
Date: Sun Jul 14 12:04:39 2019
New Revision: 349986
URL: https://svnweb.freebsd.org/changeset/base/349986

Log:
  When calling sctp_initialize_auth_params(), the inp must have at
  least a read lock. To avoid more complex locking dances, just
  call it in sctp_aloc_assoc() when the write lock is still held.
  
  Reported by:          syzbot+08a486f7e6966f1c3...@syzkaller.appspotmail.com
  MFC after:            1 week

Modified:
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet6/sctp6_usrreq.c

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Sun Jul 14 05:41:43 2019        
(r349985)
+++ head/sys/netinet/sctp_input.c       Sun Jul 14 12:04:39 2019        
(r349986)
@@ -2155,8 +2155,8 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, in
            ntohl(initack_cp->init.initiate_tag), vrf_id,
            ntohs(initack_cp->init.num_outbound_streams),
            port,
-           (struct thread *)NULL
-           );
+           (struct thread *)NULL,
+           SCTP_DONT_INITIALIZE_AUTH_PARAMS);
        if (stcb == NULL) {
                struct mbuf *op_err;
 

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c      Sun Jul 14 05:41:43 2019        
(r349985)
+++ head/sys/netinet/sctp_output.c      Sun Jul 14 12:04:39 2019        
(r349986)
@@ -12769,7 +12769,8 @@ sctp_lower_sosend(struct socket *so,
                        stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
                            inp->sctp_ep.pre_open_stream_count,
                            inp->sctp_ep.port,
-                           p);
+                           p,
+                           SCTP_INITIALIZE_AUTH_PARAMS);
                        if (stcb == NULL) {
                                /* Error is setup for us in the call */
                                goto out_unlocked;
@@ -12797,9 +12798,6 @@ sctp_lower_sosend(struct socket *so,
                        asoc = &stcb->asoc;
                        SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
                        (void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
-
-                       /* initialize authentication params for the assoc */
-                       sctp_initialize_auth_params(inp, stcb);
 
                        if (control) {
                                if (sctp_process_cmsgs_for_init(stcb, control, 
&error)) {

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c Sun Jul 14 05:41:43 2019        (r349985)
+++ head/sys/netinet/sctp_pcb.c Sun Jul 14 12:04:39 2019        (r349986)
@@ -4190,8 +4190,8 @@ struct sctp_tcb *
 sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
     int *error, uint32_t override_tag, uint32_t vrf_id,
     uint16_t o_streams, uint16_t port,
-    struct thread *p
-)
+    struct thread *p,
+    int initialize_auth_params)
 {
        /* note the p argument is only valid in unbound sockets */
 
@@ -4420,6 +4420,9 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockadd
                head = &inp->sctp_tcbhash[SCTP_PCBHASH_ALLADDR(stcb->rport,
                    inp->sctp_hashmark)];
                LIST_INSERT_HEAD(head, stcb, sctp_tcbhash);
+       }
+       if (initialize_auth_params == SCTP_INITIALIZE_AUTH_PARAMS) {
+               sctp_initialize_auth_params(inp, stcb);
        }
        SCTP_INP_WUNLOCK(inp);
        SCTPDBG(SCTP_DEBUG_PCB1, "Association %p now allocated\n", (void 
*)stcb);

Modified: head/sys/netinet/sctp_pcb.h
==============================================================================
--- head/sys/netinet/sctp_pcb.h Sun Jul 14 05:41:43 2019        (r349985)
+++ head/sys/netinet/sctp_pcb.h Sun Jul 14 12:04:39 2019        (r349986)
@@ -578,9 +578,13 @@ int sctp_is_address_on_local_host(struct sockaddr *add
 
 void sctp_inpcb_free(struct sctp_inpcb *, int, int);
 
+#define SCTP_DONT_INITIALIZE_AUTH_PARAMS       0
+#define SCTP_INITIALIZE_AUTH_PARAMS            1
+
 struct sctp_tcb *
 sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
-    int *, uint32_t, uint32_t, uint16_t, uint16_t, struct thread *);
+    int *, uint32_t, uint32_t, uint16_t, uint16_t, struct thread *,
+    int);
 
 int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
 

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c      Sun Jul 14 05:41:43 2019        
(r349985)
+++ head/sys/netinet/sctp_usrreq.c      Sun Jul 14 12:04:39 2019        
(r349986)
@@ -1443,8 +1443,8 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb
        stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id,
            inp->sctp_ep.pre_open_stream_count,
            inp->sctp_ep.port,
-           (struct thread *)p
-           );
+           (struct thread *)p,
+           SCTP_INITIALIZE_AUTH_PARAMS);
        if (stcb == NULL) {
                /* Gak! no memory */
                goto out_now;
@@ -1480,9 +1480,6 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb
        a_id = (sctp_assoc_t *)optval;
        *a_id = sctp_get_associd(stcb);
 
-       /* initialize authentication parameters for the assoc */
-       sctp_initialize_auth_params(inp, stcb);
-
        if (delay) {
                /* doing delayed connection */
                stcb->asoc.delayed_connection = 1;
@@ -7025,7 +7022,8 @@ sctp_connect(struct socket *so, struct sockaddr *addr,
        /* We are GOOD to go */
        stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
            inp->sctp_ep.pre_open_stream_count,
-           inp->sctp_ep.port, p);
+           inp->sctp_ep.port, p,
+           SCTP_INITIALIZE_AUTH_PARAMS);
        if (stcb == NULL) {
                /* Gak! no memory */
                goto out_now;
@@ -7037,9 +7035,6 @@ sctp_connect(struct socket *so, struct sockaddr *addr,
        }
        SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
        (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
-
-       /* initialize authentication parameters for the assoc */
-       sctp_initialize_auth_params(inp, stcb);
 
        sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
        SCTP_TCB_UNLOCK(stcb);

Modified: head/sys/netinet6/sctp6_usrreq.c
==============================================================================
--- head/sys/netinet6/sctp6_usrreq.c    Sun Jul 14 05:41:43 2019        
(r349985)
+++ head/sys/netinet6/sctp6_usrreq.c    Sun Jul 14 12:04:39 2019        
(r349986)
@@ -908,7 +908,8 @@ sctp6_connect(struct socket *so, struct sockaddr *addr
        /* We are GOOD to go */
        stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
            inp->sctp_ep.pre_open_stream_count,
-           inp->sctp_ep.port, p);
+           inp->sctp_ep.port, p,
+           SCTP_INITIALIZE_AUTH_PARAMS);
        SCTP_ASOC_CREATE_UNLOCK(inp);
        if (stcb == NULL) {
                /* Gak! no memory */
@@ -921,10 +922,6 @@ sctp6_connect(struct socket *so, struct sockaddr *addr
        }
        SCTP_SET_STATE(stcb, SCTP_STATE_COOKIE_WAIT);
        (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
-
-       /* initialize authentication parameters for the assoc */
-       sctp_initialize_auth_params(inp, stcb);
-
        sctp_send_initiate(inp, stcb, SCTP_SO_LOCKED);
        SCTP_TCB_UNLOCK(stcb);
        return (error);
_______________________________________________
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