net: Fix memory leaks in lltable_calc_llheader() error paths

Also convert raw epoch_call() calls to lltable_free_entry() calls, no
functional change intended.  There's no need to asynchronously free the
LLEs in that case to begin with, but we might as well use the lltable
interfaces consistently.

Noticed by code inspection; I believe lltable_calc_llheader() failures
do not generally happen in practice.

Reviewed by:	bz
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D34832
This commit is contained in:
Mark Johnston 2022-04-08 11:47:25 -04:00
parent dd91d84486
commit 990a6d18b0
4 changed files with 8 additions and 4 deletions

View File

@ -926,8 +926,10 @@ lla_rt_output(struct rt_msghdr *rtm, struct rt_addrinfo *info)
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, dst->sa_family, LLADDR(dl),
linkhdr, &linkhdrsize, &lladdr_off) != 0)
linkhdr, &linkhdrsize, &lladdr_off) != 0) {
lltable_free_entry(llt, lle);
return (EINVAL);
}
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
lladdr_off);
if ((rtm->rtm_flags & RTF_ANNOUNCE))

View File

@ -1563,7 +1563,7 @@ in_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr
linkhdrsize = LLE_MAX_LINKHDR;
if (lltable_calc_llheader(ifp, AF_INET, IF_LLADDR(ifp),
linkhdr, &linkhdrsize, &lladdr_off) != 0) {
NET_EPOCH_CALL(in_lltable_destroy_lle_unlocked, &lle->lle_epoch_ctx);
in_lltable_free_entry(llt, lle);
return (NULL);
}
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,

View File

@ -2325,7 +2325,7 @@ in6_lltable_alloc(struct lltable *llt, u_int flags,
linkhdrsize = LLE_MAX_LINKHDR;
if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp),
linkhdr, &linkhdrsize, &lladdr_off) != 0) {
NET_EPOCH_CALL(in6_lltable_destroy_lle_unlocked, &lle->lle_epoch_ctx);
in6_lltable_free_entry(llt, lle);
return (NULL);
}
lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,

View File

@ -2036,8 +2036,10 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr,
if (lladdr != NULL) {
linkhdrsize = sizeof(linkhdr);
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
linkhdr, &linkhdrsize, &lladdr_off) != 0)
linkhdr, &linkhdrsize, &lladdr_off) != 0) {
lltable_free_entry(LLTABLE6(ifp), ln);
return;
}
lltable_set_entry_addr(ifp, ln, linkhdr, linkhdrsize,
lladdr_off);
}