git: 9abf60f5cebf - stable/13 - netlink: fix potential llentry lock leak in newneigh handler

2 views
Skip to first unread message

Kristof Provost

unread,
Nov 1, 2023, 5:06:18 AM11/1/23
to src-com...@freebsd.org, dev-commi...@freebsd.org, dev-commits-...@freebsd.org
The branch stable/13 has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9abf60f5cebf1904959daacb4084113acc78a173

commit 9abf60f5cebf1904959daacb4084113acc78a173
Author: R. Christian McDonald <r...@rcm.sh>
AuthorDate: 2023-10-23 11:23:55 +0000
Commit: Kristof Provost <k...@FreeBSD.org>
CommitDate: 2023-10-31 08:08:44 +0000

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

(cherry picked from commit ae2ca32781a90abe987e128ca167ab400a87f369)
---
sys/netlink/route/neigh.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)

diff --git a/sys/netlink/route/neigh.c b/sys/netlink/route/neigh.c
index 140194b4ad32..dcb37313d0db 100644
--- a/sys/netlink/route/neigh.c
+++ b/sys/netlink/route/neigh.c
@@ -416,17 +416,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);
@@ -436,14 +437,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);

Reply all
Reply to author
Forward
0 new messages