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 */

Reply via email to