Fix the handling of IPSec policies in the SCTP stack. At least
make sure they are not leaked... MFC after: 1 week
This commit is contained in:
parent
e5d23883bf
commit
3bf2363dca
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=291141
@ -2495,14 +2495,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);
|
||||
@ -2536,6 +2529,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);
|
||||
}
|
||||
@ -2556,6 +2552,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);
|
||||
}
|
||||
@ -3640,13 +3639,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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user