NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/51467 detaching USB network interface panics



On Sun, Nov 27, 2016 at 6:50 PM, Michael van Elst <mlelstv%serpens.de@localhost> wrote:
> The following reply was made to PR kern/51467; it has been noted by GNATS.
>
> From: Michael van Elst <mlelstv%serpens.de@localhost>
> To: gnats-bugs%netbsd.org@localhost
> Cc:
> Subject: Re: kern/51467 detaching USB network interface panics
> Date: Sun, 27 Nov 2016 10:45:27 +0100
>
>  nd6_purge() contains a hack:
>
>                          /*
>                           * Because if_detach() does *not* release prefixes
>                           * while purging addresses the reference count will
>                           * still be above zero. We therefore reset it to
>                           * make sure that the prefix really gets purged.
>                           */
>                          pr->ndpr_refcnt = 0;
>
>  followed by a call to prelist_remove(pr). This will free the prefix list
>  although it is still referenced by the interface.
>
>  It will also finally call pfxlist_onlink_check().
>
>          /*
>           * Changes on the prefix status might affect address status as well.
>           * Make sure that all addresses derived from an attached prefix are
>           * attached, and that all addresses derived from a detached prefix are
>           * detached.  Note, however, that a manually configured address should
>           * always be attached.
>           * The precise detection logic is same as the one for prefixes.
>           */
>
>  Here pfxlist_onlink_check uses the stale ia->ia6_ndpr reference
>  when calling find_pfxlist_reachable_router().
>
>  If the kernel is compiled with DEBUG (implies KMEM_POISON), this
>  leads to an immediate crash.

Thank you for the investigation. I can reproduce it now on an ATF test (t_ra)
by enabling KMEM_POISON by hand (it's never enabled on rump kernels).

The following patch fixes the panic. It restores the original behavior
of in6_purgeif changed by in6.c,v 1.203 and in6_ifattach.c,v 1.99.

Thanks,
  ozaki-r

diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c
index 2065d18..0eb8ddb 100644
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -809,15 +809,15 @@ void
 in6_ifdetach(struct ifnet *ifp)
 {

+       /* nuke any of IPv6 addresses we have */
+       if_purgeaddrs(ifp, AF_INET6, in6_purgeaddr);
+
        /* remove ip6_mrouter stuff */
        ip6_mrouter_detach(ifp);

        /* remove neighbor management table */
        nd6_purge(ifp, NULL);

-       /* nuke any of IPv6 addresses we have */
-       if_purgeaddrs(ifp, AF_INET6, in6_purgeaddr);
-
        /* cleanup multicast address kludge table, if there is any */
        in6_purgemkludge(ifp);


Home | Main Index | Thread Index | Old Index