Date: Mon, 13 Feb 2017 11:37:52 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r313697 - in head/sys: netinet netinet6 Message-ID: <201702131137.v1DBbqKX012592@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Mon Feb 13 11:37:52 2017 New Revision: 313697 URL: https://svnweb.freebsd.org/changeset/base/313697 Log: Remove IPsec related PCB code from SCTP. The inpcb structure has inp_sp pointer that is initialized by ipsec_init_pcbpolicy() function. This pointer keeps strorage for IPsec security policies associated with a specific socket. An application can use IP_IPSEC_POLICY and IPV6_IPSEC_POLICY socket options to configure these security policies. Then ip[6]_output() uses inpcb pointer to specify that an outgoing packet is associated with some socket. And IPSEC_OUTPUT() method can use a security policy stored in the inp_sp. For inbound packet the protocol-specific input routine uses IPSEC_CHECK_POLICY() method to check that a packet conforms to inbound security policy configured in the inpcb. SCTP protocol doesn't specify inpcb for ip[6]_output() when it sends packets. Thus IPSEC_OUTPUT() method does not consider such packets as associated with some socket and can not apply security policies from inpcb, even if they are configured. Since IPSEC_CHECK_POLICY() method is called from protocol-specific input routine, it can specify inpcb pointer and associated with socket inbound policy will be checked. But there are two problems: 1. Such check is asymmetric, becasue we can not apply security policy from inpcb for outgoing packet. 2. IPSEC_CHECK_POLICY() expects that caller holds INPCB lock and access to inp_sp is protected. But for SCTP this is not correct, becasue SCTP uses own locks to protect inpcb. To fix these problems remove IPsec related PCB code from SCTP. This imply that IP_IPSEC_POLICY and IPV6_IPSEC_POLICY socket options will be not applicable to SCTP sockets. To be able correctly check inbound security policies for SCTP, mark its protocol header with the PR_LASTHDR flag. Reported by: tuexen Reviewed by: tuexen Differential Revision: https://reviews.freebsd.org/D9538 Modified: head/sys/netinet/in_proto.c head/sys/netinet/sctp_input.c head/sys/netinet/sctp_os_bsd.h head/sys/netinet/sctp_pcb.c head/sys/netinet6/in6_proto.c head/sys/netinet6/sctp6_usrreq.c Modified: head/sys/netinet/in_proto.c ============================================================================== --- head/sys/netinet/in_proto.c Mon Feb 13 09:04:38 2017 (r313696) +++ head/sys/netinet/in_proto.c Mon Feb 13 11:37:52 2017 (r313697) @@ -148,7 +148,7 @@ struct protosw inetsw[] = { .pr_type = SOCK_SEQPACKET, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, + .pr_flags = PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp_input, .pr_ctlinput = sctp_ctlinput, .pr_ctloutput = sctp_ctloutput, @@ -160,7 +160,7 @@ struct protosw inetsw[] = { .pr_type = SOCK_STREAM, .pr_domain = &inetdomain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp_input, .pr_ctlinput = sctp_ctlinput, .pr_ctloutput = sctp_ctloutput, Modified: head/sys/netinet/sctp_input.c ============================================================================== --- head/sys/netinet/sctp_input.c Mon Feb 13 09:04:38 2017 (r313696) +++ head/sys/netinet/sctp_input.c Mon Feb 13 11:37:52 2017 (r313697) @@ -5790,40 +5790,6 @@ sctp_common_input_processing(struct mbuf } else if (stcb == NULL) { inp_decr = inp; } -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - /*- - * I very much doubt any of the IPSEC stuff will work but I have no - * idea, so I will leave it in place. - */ - if (inp != NULL) { - switch (dst->sa_family) { -#ifdef INET - case AF_INET: - if (IPSEC_ENABLED(ipv4)) { - if (IPSEC_CHECK_POLICY(ipv4, m, - &inp->ip_inp.inp) != 0) { - SCTP_STAT_INCR(sctps_hdrops); - goto out; - } - } - break; -#endif -#ifdef INET6 - case AF_INET6: - if (IPSEC_ENABLED(ipv6)) { - if (IPSEC_CHECK_POLICY(ipv6, m, - &inp->ip_inp.inp) != 0) { - SCTP_STAT_INCR(sctps_hdrops); - goto out; - } - } - break; -#endif - default: - break; - } - } -#endif /* IPSEC */ SCTPDBG(SCTP_DEBUG_INPUT1, "Ok, Common input processing called, m:%p iphlen:%d offset:%d length:%d stcb:%p\n", (void *)m, iphlen, offset, length, (void *)stcb); if (stcb) { Modified: head/sys/netinet/sctp_os_bsd.h ============================================================================== --- head/sys/netinet/sctp_os_bsd.h Mon Feb 13 09:04:38 2017 (r313696) +++ head/sys/netinet/sctp_os_bsd.h Mon Feb 13 11:37:52 2017 (r313697) @@ -38,7 +38,6 @@ __FBSDID("$FreeBSD$"); /* * includes */ -#include "opt_ipsec.h" #include "opt_compat.h" #include "opt_inet6.h" #include "opt_inet.h" @@ -82,8 +81,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip_icmp.h> #include <netinet/icmp_var.h> -#include <netipsec/ipsec_support.h> - #ifdef INET6 #include <sys/domain.h> #include <netinet/ip6.h> @@ -94,7 +91,6 @@ __FBSDID("$FreeBSD$"); #include <netinet6/scope6_var.h> #endif /* INET6 */ - #include <netinet/ip_options.h> #include <crypto/sha1.h> Modified: head/sys/netinet/sctp_pcb.c ============================================================================== --- head/sys/netinet/sctp_pcb.c Mon Feb 13 09:04:38 2017 (r313696) +++ head/sys/netinet/sctp_pcb.c Mon Feb 13 11:37:52 2017 (r313697) @@ -2469,15 +2469,6 @@ sctp_inpcb_alloc(struct socket *so, uint SCTP_INP_INFO_WUNLOCK(); return (ENOBUFS); } -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - error = ipsec_init_pcbpolicy(&inp->ip_inp.inp); - if (error != 0) { - crfree(inp->ip_inp.inp.inp_cred); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); - SCTP_INP_INFO_WUNLOCK(); - return error; - } -#endif /* IPSEC */ SCTP_INCR_EP_COUNT(); inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl); SCTP_INP_INFO_WUNLOCK(); @@ -2504,9 +2495,6 @@ 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); -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - ipsec_delete_pcbpolicy(&inp->ip_inp.inp); -#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (EOPNOTSUPP); } @@ -2527,9 +2515,6 @@ 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); -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - ipsec_delete_pcbpolicy(&inp->ip_inp.inp); -#endif SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp); return (ENOBUFS); } @@ -3641,9 +3626,6 @@ sctp_inpcb_free(struct sctp_inpcb *inp, * macro here since le_next will get freed as part of the * sctp_free_assoc() call. */ -#if defined(IPSEC) || defined(IPSEC_SUPPORT) - 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/netinet6/in6_proto.c ============================================================================== --- head/sys/netinet6/in6_proto.c Mon Feb 13 09:04:38 2017 (r313696) +++ head/sys/netinet6/in6_proto.c Mon Feb 13 11:37:52 2017 (r313697) @@ -185,7 +185,7 @@ struct protosw inet6sw[] = { .pr_type = SOCK_SEQPACKET, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_WANTRCVD, + .pr_flags = PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp6_input, .pr_ctlinput = sctp6_ctlinput, .pr_ctloutput = sctp_ctloutput, @@ -199,7 +199,7 @@ struct protosw inet6sw[] = { .pr_type = SOCK_STREAM, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_SCTP, - .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD, + .pr_flags = PR_CONNREQUIRED|PR_WANTRCVD|PR_LASTHDR, .pr_input = sctp6_input, .pr_ctlinput = sctp6_ctlinput, .pr_ctloutput = sctp_ctloutput, Modified: head/sys/netinet6/sctp6_usrreq.c ============================================================================== --- head/sys/netinet6/sctp6_usrreq.c Mon Feb 13 09:04:38 2017 (r313696) +++ head/sys/netinet6/sctp6_usrreq.c Mon Feb 13 11:37:52 2017 (r313697) @@ -551,10 +551,6 @@ sctp6_attach(struct socket *so, int prot */ inp6->inp_ip_ttl = MODULE_GLOBAL(ip_defttl); #endif - /* - * Hmm what about the IPSEC stuff that is missing here but in - * sctp_attach()? - */ SCTP_INP_WUNLOCK(inp); return (0); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201702131137.v1DBbqKX012592>