netlink: fix potential llentry lock leak in newneigh handler

The netlink newneigh handler has the potential to leak the lock on
llentry objects in the kernel. This patch reconciles several paths
through the newneigh handler that could result in a lock leak.

MFC after:	1 week
Reviewed by:	markj, kp
Sponsored by:	Rubicon Communications, LLC ("Netgate")
Differential Revision:	https://reviews.freebsd.org/D42307
This commit is contained in:
R. Christian McDonald 2023-10-23 13:23:55 +02:00 committed by Kristof Provost
parent c36b3dbc99
commit ae2ca32781

View file

@ -436,17 +436,18 @@ rtnl_handle_newneigh(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *
struct llentry *lle_tmp = lla_lookup(llt, LLE_EXCLUSIVE, attrs.nda_dst);
if (lle_tmp != NULL) {
error = EEXIST;
if (hdr->nlmsg_flags & NLM_F_EXCL) {
LLE_WUNLOCK(lle_tmp);
lle_tmp = NULL;
} else if (hdr->nlmsg_flags & NLM_F_REPLACE) {
if (hdr->nlmsg_flags & NLM_F_REPLACE) {
error = EPERM;
if ((lle_tmp->la_flags & LLE_IFADDR) == 0) {
error = 0; /* success */
lltable_unlink_entry(llt, lle_tmp);
llentry_free(lle_tmp);
lle_tmp = NULL;
lltable_link_entry(llt, lle);
error = 0;
} else
error = EPERM;
}
}
if (lle_tmp)
LLE_WUNLOCK(lle_tmp);
} else {
if (hdr->nlmsg_flags & NLM_F_CREATE)
lltable_link_entry(llt, lle);
@ -456,14 +457,11 @@ rtnl_handle_newneigh(struct nlmsghdr *hdr, struct nlpcb *nlp, struct nl_pstate *
IF_AFDATA_WUNLOCK(attrs.nda_ifp);
if (error != 0) {
if (lle != NULL)
llentry_free(lle);
/* throw away the newly allocated llentry */
llentry_free(lle);
return (error);
}
if (lle_tmp != NULL)
llentry_free(lle_tmp);
/* XXX: We're inside epoch */
EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_RESOLVED);
LLE_WUNLOCK(lle);