Race condition in ip6_getpmtu (actually gif)?
Craig Boston
craig at olyun.gank.org
Thu Jan 26 18:10:49 PST 2006
On Thu, Jan 26, 2006 at 08:05:28PM -0600, Craig Boston wrote:
> Attached is a quick hack...
Whoops, patch _actually_ attached this time.
-------------- next part --------------
=== net/if_gif.c
==================================================================
--- net/if_gif.c (/vendor/sys) (revision 292)
+++ net/if_gif.c (/gif6) (revision 292)
@@ -154,6 +154,8 @@
return (ENOSPC);
}
+ mtx_init(&sc->gif_ro_mtx, "gif_ro_mtx", NULL, MTX_DEF);
+
GIF2IFP(sc)->if_softc = sc;
if_initname(GIF2IFP(sc), ifc->ifc_name, unit);
@@ -227,6 +229,7 @@
mtx_lock(&gif_mtx);
LIST_REMOVE(sc, gif_list);
mtx_unlock(&gif_mtx);
+ mtx_destroy(&sc->gif_ro_mtx);
gif_destroy(sc);
}
=== net/if_gif.h
==================================================================
--- net/if_gif.h (/vendor/sys) (revision 292)
+++ net/if_gif.h (/gif6) (revision 292)
@@ -65,6 +65,7 @@
struct route_in6 gifscr_ro6; /* xxx */
#endif
} gifsc_gifscr;
+ struct mtx gif_ro_mtx;
int gif_flags;
const struct encaptab *encap_cookie4;
const struct encaptab *encap_cookie6;
=== netinet6/in6_gif.c
==================================================================
--- netinet6/in6_gif.c (/vendor/sys) (revision 292)
+++ netinet6/in6_gif.c (/gif6) (revision 292)
@@ -195,25 +195,30 @@
dst->sin6_family = sin6_dst->sin6_family;
dst->sin6_len = sizeof(struct sockaddr_in6);
dst->sin6_addr = sin6_dst->sin6_addr;
+ mtx_lock(&sc->gif_ro_mtx);
if (sc->gif_ro6.ro_rt) {
RTFREE(sc->gif_ro6.ro_rt);
sc->gif_ro6.ro_rt = NULL;
}
+ mtx_unlock(&sc->gif_ro_mtx);
#if 0
GIF2IFP(sc)->if_mtu = GIF_MTU;
#endif
}
+ mtx_lock(&sc->gif_ro_mtx);
if (sc->gif_ro6.ro_rt == NULL) {
rtalloc((struct route *)&sc->gif_ro6);
if (sc->gif_ro6.ro_rt == NULL) {
m_freem(m);
+ mtx_unlock(&sc->gif_ro_mtx);
return ENETUNREACH;
}
/* if it constitutes infinite encapsulation, punt. */
if (sc->gif_ro.ro_rt->rt_ifp == ifp) {
m_freem(m);
+ mtx_unlock(&sc->gif_ro_mtx);
return ENETUNREACH; /*XXX*/
}
#if 0
@@ -238,6 +243,7 @@
RTFREE(sc->gif_ro6.ro_rt);
sc->gif_ro6.ro_rt = NULL;
}
+ mtx_unlock(&sc->gif_ro_mtx);
return (error);
}
More information about the freebsd-net
mailing list