Fix SP refcount leak.

PCB SP cache acquires extra reference, when SP is stored in the cache.
Release this reference when PCB is destroyed in ipsec_delete_pcbpolicy().
In ipsec_copy_pcbpolicy() release reference to SP in case if sp_in or
sp_out are not NULL.

Reported by:	Slawa Olhovchenkov <slw at zxy spb ru>
MFC after:	1 week
This commit is contained in:
Andrey V. Elsukov 2017-04-26 00:34:05 +00:00
parent 773404ba35
commit 44c6ff8e2a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=317431

View File

@ -172,10 +172,10 @@ ipsec_delete_pcbpolicy(struct inpcb *inp)
if (inp->inp_sp == NULL)
return (0);
if (inp->inp_sp->flags & INP_INBOUND_POLICY)
if (inp->inp_sp->sp_in != NULL)
key_freesp(&inp->inp_sp->sp_in);
if (inp->inp_sp->flags & INP_OUTBOUND_POLICY)
if (inp->inp_sp->sp_out != NULL)
key_freesp(&inp->inp_sp->sp_out);
free(inp->inp_sp, M_IPSEC_INPCB);
@ -250,6 +250,8 @@ ipsec_copy_pcbpolicy(struct inpcb *old, struct inpcb *new)
if (sp == NULL)
return (ENOBUFS);
ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_INBOUND);
if (new->inp_sp->sp_in != NULL)
key_freesp(&new->inp_sp->sp_in);
new->inp_sp->sp_in = sp;
new->inp_sp->flags |= INP_INBOUND_POLICY;
}
@ -258,6 +260,8 @@ ipsec_copy_pcbpolicy(struct inpcb *old, struct inpcb *new)
if (sp == NULL)
return (ENOBUFS);
ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_OUTBOUND);
if (new->inp_sp->sp_out != NULL)
key_freesp(&new->inp_sp->sp_out);
new->inp_sp->sp_out = sp;
new->inp_sp->flags |= INP_OUTBOUND_POLICY;
}