⬢ DragonFlyBSD Kernel Audit
DF-3418 / fix.diff
← back to finding ↓ download raw
--- a/sys/netinet6/in6_ifattach.c
+++ b/sys/netinet6/in6_ifattach.c
@@ -838,15 +838,19 @@ in6_ifdetach_dispatch(netmsg_t nmsg)
 	/* remove route to link-local allnodes multicast (ff02::1) */
 	bzero(&sin6, sizeof(sin6));
 	sin6.sin6_len = sizeof(struct sockaddr_in6);
 	sin6.sin6_family = AF_INET6;
 	sin6.sin6_addr = kin6addr_linklocal_allnodes;
 	sin6.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
 	rt = rtpurelookup((struct sockaddr *)&sin6);
-	if (rt != NULL && rt->rt_ifp == ifp) {
-		--rt->rt_refcnt;
+	if (rt != NULL) {
+		if (rt->rt_ifp == ifp) {
+			--rt->rt_refcnt;
+		} else {
+			/* not ours: drop the reference taken by the lookup */
+			rtfree(rt);
+			rt = NULL;
+		}
+	}
+	if (rt != NULL && rt->rt_ifp == ifp) {
 		rtrequest(RTM_DELETE, (struct sockaddr *)rt_key(rt),
 		    rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
 	}
 
 	lwkt_replymsg(lmsg, 0);