in_lltable_alloc and in6 copy: Don't leak LLE in error path

Fix a memory leak in error conditions introduced in r292978.

Reported by:	Coverity
CIDs:		1347009, 1347010
Sponsored by:	EMC / Isilon Storage Division
This commit is contained in:
Conrad Meyer 2016-04-26 23:13:48 +00:00
parent 349ef43de4
commit 2769d06203
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=298675
2 changed files with 30 additions and 8 deletions

View File

@ -1004,6 +1004,17 @@ struct in_llentry {
/*
* Do actual deallocation of @lle.
*/
static void
in_lltable_destroy_lle_unlocked(struct llentry *lle)
{
LLE_LOCK_DESTROY(lle);
LLE_REQ_DESTROY(lle);
free(lle, M_LLTABLE);
}
/*
* Called by LLE_FREE_LOCKED when number of references
* drops to zero.
*/
@ -1012,9 +1023,7 @@ in_lltable_destroy_lle(struct llentry *lle)
{
LLE_WUNLOCK(lle);
LLE_LOCK_DESTROY(lle);
LLE_REQ_DESTROY(lle);
free(lle, M_LLTABLE);
in_lltable_destroy_lle_unlocked(lle);
}
static struct llentry *
@ -1277,8 +1286,10 @@ in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr
if ((flags & LLE_IFADDR) == LLE_IFADDR) {
linkhdrsize = LLE_MAX_LINKHDR;
if (lltable_calc_llheader(ifp, AF_INET, IF_LLADDR(ifp),
linkhdr, &linkhdrsize, &lladdr_off) != 0)
linkhdr, &linkhdrsize, &lladdr_off) != 0) {
in_lltable_destroy_lle_unlocked(lle);
return (NULL);
}
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
lladdr_off);
lle->la_flags |= LLE_STATIC;

View File

@ -2056,6 +2056,17 @@ struct in6_llentry {
/*
* Do actual deallocation of @lle.
*/
static void
in6_lltable_destroy_lle_unlocked(struct llentry *lle)
{
LLE_LOCK_DESTROY(lle);
LLE_REQ_DESTROY(lle);
free(lle, M_LLTABLE);
}
/*
* Called by LLE_FREE_LOCKED when number of references
* drops to zero.
*/
@ -2064,9 +2075,7 @@ in6_lltable_destroy_lle(struct llentry *lle)
{
LLE_WUNLOCK(lle);
LLE_LOCK_DESTROY(lle);
LLE_REQ_DESTROY(lle);
free(lle, M_LLTABLE);
in6_lltable_destroy_lle_unlocked(lle);
}
static struct llentry *
@ -2270,8 +2279,10 @@ in6_lltable_alloc(struct lltable *llt, u_int flags,
if ((flags & LLE_IFADDR) == LLE_IFADDR) {
linkhdrsize = LLE_MAX_LINKHDR;
if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp),
linkhdr, &linkhdrsize, &lladdr_off) != 0)
linkhdr, &linkhdrsize, &lladdr_off) != 0) {
in6_lltable_destroy_lle_unlocked(lle);
return (NULL);
}
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
lladdr_off);
lle->la_flags |= LLE_STATIC;