The branch main has been updated by kp: URL: https://cgit.FreeBSD.org/src/commit/?id=23d8e956fbe29418d74b78d98a453fcec1ad16da
commit 23d8e956fbe29418d74b78d98a453fcec1ad16da Author: Kristof Provost <k...@freebsd.org> AuthorDate: 2025-05-22 08:25:55 +0000 Commit: Kristof Provost <k...@freebsd.org> CommitDate: 2025-05-27 09:47:43 +0000 icmp6: fix use-after-reference-release We release the reference to the in6_ifaddr but retain a pointer to it. Copy the address itself, rather than keeping the pointer to fix this. The previous version was actually safe, because ifa_free() uses an epoch callback to free it, so the pointer would have remained valid as long as we are in net_epoch. Change it to copying the address anyway because it is more obviously correct and will remain correct even if ifa_free() changes later. Sponsored by: Rubicon Communications, LLC ("Netgate") Differential Revision: https://reviews.freebsd.org/D50460 --- sys/netinet6/icmp6.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index eaf8514fd5cf..9ea640fd24c8 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2391,7 +2391,7 @@ void icmp6_redirect_output(struct mbuf *m0, struct nhop_object *nh) { struct ifnet *ifp; /* my outgoing interface */ - struct in6_addr *ifp_ll6; + struct in6_addr ifp_ll6; struct in6_addr *router_ll6; struct ip6_hdr *sip6; /* m0 as struct ip6_hdr */ struct mbuf *m = NULL; /* newly allocated one */ @@ -2461,8 +2461,7 @@ icmp6_redirect_output(struct mbuf *m0, struct nhop_object *nh) IN6_IFF_NOTREADY| IN6_IFF_ANYCAST)) == NULL) goto fail; - ifp_ll6 = &ia->ia_addr.sin6_addr; - /* XXXRW: reference released prematurely. */ + bcopy(&ia->ia_addr.sin6_addr, &ifp_ll6, sizeof(ifp_ll6)); ifa_free(&ia->ia_ifa); } @@ -2485,7 +2484,7 @@ icmp6_redirect_output(struct mbuf *m0, struct nhop_object *nh) ip6->ip6_nxt = IPPROTO_ICMPV6; ip6->ip6_hlim = 255; /* ip6->ip6_src must be linklocal addr for my outgoing if. */ - bcopy(ifp_ll6, &ip6->ip6_src, sizeof(struct in6_addr)); + bcopy(&ifp_ll6, &ip6->ip6_src, sizeof(struct in6_addr)); bcopy(&sip6->ip6_src, &ip6->ip6_dst, sizeof(struct in6_addr)); /* ND Redirect */