Date: Sun, 14 Jul 2019 12:04:39 +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: r349986 - in head/sys: netinet netinet6 Message-ID: <201907141204.x6EC4ddc072095@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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+08a486f7e6966f1c3cfb@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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201907141204.x6EC4ddc072095>