diff options
author | tuexen <tuexen@FreeBSD.org> | 2016-01-16 18:20:47 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2016-01-16 18:20:47 +0000 |
commit | 9ca478ea2ce51a41938d67e7c9dc96f440f4240b (patch) | |
tree | 0a3e890b7910918223fbc6ea3e966f86182d371d /sys/netinet | |
parent | 2c71b0cb5af8629f8475e0296321fdf9e26c9d33 (diff) | |
download | FreeBSD-src-9ca478ea2ce51a41938d67e7c9dc96f440f4240b.zip FreeBSD-src-9ca478ea2ce51a41938d67e7c9dc96f440f4240b.tar.gz |
MFC r291141:
Fix the handling of IPSec policies in the SCTP stack. At least
make sure they are not leaked...
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/sctp_pcb.c | 23 | ||||
-rw-r--r-- | sys/netinet/sctp_usrreq.c | 33 |
2 files changed, 9 insertions, 47 deletions
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c index 0d28453..0715dd60 100644 --- a/sys/netinet/sctp_pcb.c +++ b/sys/netinet/sctp_pcb.c @@ -2499,14 +2499,7 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) 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); @@ -2540,6 +2533,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) 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); } @@ -2560,6 +2556,9 @@ sctp_inpcb_alloc(struct socket *so, uint32_t vrf_id) 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); } @@ -3644,13 +3643,9 @@ sctp_inpcb_free(struct sctp_inpcb *inp, int immediate, int from) * 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; diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c index fa816c1..6a474e3 100644 --- a/sys/netinet/sctp_usrreq.c +++ b/sys/netinet/sctp_usrreq.c @@ -487,11 +487,6 @@ sctp_attach(struct socket *so, int proto SCTP_UNUSED, struct thread *p SCTP_UNUS 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 SCTP_UNUSED, struct thread *p SCTP_UNUS 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); } |