From dd91d8448665dd31df5be7341756394293c6e36c Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 8 Apr 2022 11:46:19 -0400 Subject: [PATCH] net: Fix LLE lock leaks Historically, lltable_try_set_entry_addr() would release the LLE lock upon failure. After some refactoring, it no longer does so, but consumers were not adjusted accordingly. Also fix a leak that can occur if lltable_calc_llheader() fails in the ARP code, but I suspect that such a failure can only occur due to a code bug. Reviewed by: bz, melifaro Reported by: pho Fixes: 0b79b007ebfc ("[lltable] Restructure nd6 code.") MFC after: 3 days Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D34831 --- sys/netinet/if_ether.c | 8 ++++++-- sys/netinet6/nd6_nbr.c | 4 +--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index f54df993793..fd0423858bb 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -1228,16 +1228,20 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp /* Calculate full link prepend to use in lle */ linkhdrsize = sizeof(linkhdr); if (lltable_calc_llheader(ifp, AF_INET, ar_sha(ah), linkhdr, - &linkhdrsize, &lladdr_off) != 0) + &linkhdrsize, &lladdr_off) != 0) { + LLE_WUNLOCK(la); return; + } /* Check if something has changed */ if (memcmp(la->r_linkdata, linkhdr, linkhdrsize) != 0 || (la->la_flags & LLE_VALID) == 0) { /* Try to perform LLE update */ if (lltable_try_set_entry_addr(ifp, la, linkhdr, linkhdrsize, - lladdr_off) == 0) + lladdr_off) == 0) { + LLE_WUNLOCK(la); return; + } /* Clear fast path feedback request if set */ llentry_mark_used(la); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 0c6dd9e0361..3a56964f8eb 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -855,10 +855,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) linkhdr, &linkhdrsize, &lladdr_off) != 0) goto freeit; if (lltable_try_set_entry_addr(ifp, ln, linkhdr, - linkhdrsize, lladdr_off) == 0) { - ln = NULL; + linkhdrsize, lladdr_off) == 0) goto freeit; - } EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED); } -- 2.45.0