git: eff832ae7b24 - stable/14 - netlink: fix potential llentry lock leak in newneigh handler
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 01 Nov 2023 09:06:05 UTC
The branch stable/14 has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=eff832ae7b248c499464cad93c365a1594715e07 commit eff832ae7b248c499464cad93c365a1594715e07 Author: R. Christian McDonald <rcm@rcm.sh> AuthorDate: 2023-10-23 11:23:55 +0000 Commit: Kristof Provost <kp@FreeBSD.org> CommitDate: 2023-11-01 09:05:49 +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 9914e7febf57..5be0c1f9d91f 100644 --- a/sys/netlink/route/neigh.c +++ b/sys/netlink/route/neigh.c @@ -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);