svn commit: r291141 - head/sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Sat Nov 21 18:21:17 UTC 2015


Author: tuexen
Date: Sat Nov 21 18:21:16 2015
New Revision: 291141
URL: https://svnweb.freebsd.org/changeset/base/291141

Log:
  Fix the handling of IPSec policies in the SCTP stack. At least
  make sure they are not leaked...
  
  MFC after: 	1 week

Modified:
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_usrreq.c

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Sat Nov 21 16:46:59 2015	(r291140)
+++ head/sys/netinet/sctp_pcb.c	Sat Nov 21 18:21:16 2015	(r291141)
@@ -2495,14 +2495,7 @@ sctp_inpcb_alloc(struct socket *so, uint
 		return (ENOBUFS);
 	}
 #ifdef IPSEC
-	{
-		struct inpcbpolicy *pcb_sp = NULL;
-
-		error = ipsec_init_policy(so, &pcb_sp);
-		/* Arrange to share the policy */
-		inp->ip_inp.inp.inp_sp = pcb_sp;
-		((struct in6pcb *)(&inp->ip_inp.inp))->in6p_sp = pcb_sp;
-	}
+	error = ipsec_init_policy(so, &inp->ip_inp.inp.inp_sp);
 	if (error != 0) {
 		crfree(inp->ip_inp.inp.inp_cred);
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
@@ -2536,6 +2529,9 @@ sctp_inpcb_alloc(struct socket *so, uint
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EOPNOTSUPP);
 		so->so_pcb = NULL;
 		crfree(inp->ip_inp.inp.inp_cred);
+#ifdef IPSEC
+		ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
+#endif
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		return (EOPNOTSUPP);
 	}
@@ -2556,6 +2552,9 @@ sctp_inpcb_alloc(struct socket *so, uint
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
 		so->so_pcb = NULL;
 		crfree(inp->ip_inp.inp.inp_cred);
+#ifdef IPSEC
+		ipsec_delete_pcbpolicy(&inp->ip_inp.inp);
+#endif
 		SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
 		return (ENOBUFS);
 	}
@@ -3640,13 +3639,9 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
 	 * macro here since le_next will get freed as part of the
 	 * sctp_free_assoc() call.
 	 */
-	if (so) {
 #ifdef IPSEC
-		ipsec_delete_pcbpolicy(ip_pcb);
-#endif				/* IPSEC */
-
-		/* Unlocks not needed since the socket is gone now */
-	}
+	ipsec_delete_pcbpolicy(ip_pcb);
+#endif
 	if (ip_pcb->inp_options) {
 		(void)sctp_m_free(ip_pcb->inp_options);
 		ip_pcb->inp_options = 0;

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Sat Nov 21 16:46:59 2015	(r291140)
+++ head/sys/netinet/sctp_usrreq.c	Sat Nov 21 18:21:16 2015	(r291141)
@@ -487,11 +487,6 @@ sctp_attach(struct socket *so, int proto
 	int error;
 	uint32_t vrf_id = SCTP_DEFAULT_VRFID;
 
-#ifdef IPSEC
-	uint32_t flags;
-
-#endif
-
 	inp = (struct sctp_inpcb *)so->so_pcb;
 	if (inp != 0) {
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -513,34 +508,6 @@ sctp_attach(struct socket *so, int proto
 	ip_inp = &inp->ip_inp.inp;
 	ip_inp->inp_vflag |= INP_IPV4;
 	ip_inp->inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
-#ifdef IPSEC
-	error = ipsec_init_policy(so, &ip_inp->inp_sp);
-#ifdef SCTP_LOG_CLOSING
-	sctp_log_closing(inp, NULL, 17);
-#endif
-	if (error != 0) {
-try_again:
-		flags = inp->sctp_flags;
-		if (((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) &&
-		    (atomic_cmpset_int(&inp->sctp_flags, flags, (flags | SCTP_PCB_FLAGS_SOCKET_GONE | SCTP_PCB_FLAGS_CLOSE_IP)))) {
-#ifdef SCTP_LOG_CLOSING
-			sctp_log_closing(inp, NULL, 15);
-#endif
-			SCTP_INP_WUNLOCK(inp);
-			sctp_inpcb_free(inp, SCTP_FREE_SHOULD_USE_ABORT,
-			    SCTP_CALLED_AFTER_CMPSET_OFCLOSE);
-		} else {
-			flags = inp->sctp_flags;
-			if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
-				goto try_again;
-			} else {
-				SCTP_INP_WUNLOCK(inp);
-			}
-		}
-		so->so_pcb = NULL;
-		return (error);
-	}
-#endif
 	SCTP_INP_WUNLOCK(inp);
 	return (0);
 }


More information about the svn-src-all mailing list