Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 May 2019 11:13:03 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r347105 - stable/12/sys/netinet
Message-ID:  <201905041113.x44BD366035234@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Sat May  4 11:13:03 2019
New Revision: 347105
URL: https://svnweb.freebsd.org/changeset/base/347105

Log:
  MFC r344742:
  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.

Modified:
  stable/12/sys/netinet/sctp_pcb.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/12/sys/netinet/sctp_pcb.c	Sat May  4 11:11:03 2019	(r347104)
+++ stable/12/sys/netinet/sctp_pcb.c	Sat May  4 11:13:03 2019	(r347105)
@@ -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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201905041113.x44BD366035234>