Module Name: src Committed By: knakahara Date: Mon Jul 4 04:22:48 UTC 2016
Modified Files: src/sys/net: if_gif.c src/sys/netinet: in_gif.c in_gif.h src/sys/netinet6: in6_gif.c in6_gif.h Log Message: fix: gif(4) receive side race A panic cause in rn_match() called by encap[46]_lookup(). The reason is that gif(4) does not suspend receive packet processing in spite of suspending transmit packet processing while anyone is doing gif(4) ioctl. To generate a diff of this commit: cvs rdiff -u -r1.115 -r1.116 src/sys/net/if_gif.c cvs rdiff -u -r1.77 -r1.78 src/sys/netinet/in_gif.c cvs rdiff -u -r1.15 -r1.16 src/sys/netinet/in_gif.h cvs rdiff -u -r1.76 -r1.77 src/sys/netinet6/in6_gif.c cvs rdiff -u -r1.14 -r1.15 src/sys/netinet6/in6_gif.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_gif.c diff -u src/sys/net/if_gif.c:1.115 src/sys/net/if_gif.c:1.116 --- src/sys/net/if_gif.c:1.115 Mon Jul 4 04:17:25 2016 +++ src/sys/net/if_gif.c Mon Jul 4 04:22:47 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: if_gif.c,v 1.115 2016/07/04 04:17:25 knakahara Exp $ */ +/* $NetBSD: if_gif.c,v 1.116 2016/07/04 04:22:47 knakahara Exp $ */ /* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.115 2016/07/04 04:17:25 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.116 2016/07/04 04:22:47 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -782,9 +782,29 @@ gif_encap_detach(struct gif_softc *sc) static void gif_encap_pause(struct gif_softc *sc) { - struct ifnet *ifp = &sc->gif_if; + struct ifnet *ifp; uint64_t where; + if (sc == NULL || sc->gif_psrc == NULL) + return; + + ifp = &sc->gif_if; + if ((ifp->if_flags & IFF_RUNNING) == 0) + return; + + switch (sc->gif_psrc->sa_family) { +#ifdef INET + case AF_INET: + (void)in_gif_pause(sc); + break; +#endif +#ifdef INET6 + case AF_INET6: + (void)in6_gif_pause(sc); + break; +#endif + } + ifp->if_flags &= ~IFF_RUNNING; /* membar_sync() is done in xc_broadcast(). */ Index: src/sys/netinet/in_gif.c diff -u src/sys/netinet/in_gif.c:1.77 src/sys/netinet/in_gif.c:1.78 --- src/sys/netinet/in_gif.c:1.77 Mon Jul 4 04:14:47 2016 +++ src/sys/netinet/in_gif.c Mon Jul 4 04:22:47 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: in_gif.c,v 1.77 2016/07/04 04:14:47 knakahara Exp $ */ +/* $NetBSD: in_gif.c,v 1.78 2016/07/04 04:22:47 knakahara Exp $ */ /* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.77 2016/07/04 04:14:47 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.78 2016/07/04 04:22:47 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -390,11 +390,21 @@ in_gif_detach(struct gif_softc *sc) { int error; + error = in_gif_pause(sc); + + rtcache_free(&sc->gif_ro); + + return error; +} + +int +in_gif_pause(struct gif_softc *sc) +{ + int error; + error = encap_detach(sc->encap_cookie4); if (error == 0) sc->encap_cookie4 = NULL; - rtcache_free(&sc->gif_ro); - return error; } Index: src/sys/netinet/in_gif.h diff -u src/sys/netinet/in_gif.h:1.15 src/sys/netinet/in_gif.h:1.16 --- src/sys/netinet/in_gif.h:1.15 Tue Jan 26 06:00:10 2016 +++ src/sys/netinet/in_gif.h Mon Jul 4 04:22:47 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: in_gif.h,v 1.15 2016/01/26 06:00:10 knakahara Exp $ */ +/* $NetBSD: in_gif.h,v 1.16 2016/07/04 04:22:47 knakahara Exp $ */ /* $KAME: in_gif.h,v 1.6 2001/07/25 00:55:48 itojun Exp $ */ /* @@ -45,5 +45,6 @@ int gif_encapcheck4(struct mbuf *, int, #endif int in_gif_attach(struct gif_softc *); int in_gif_detach(struct gif_softc *); +int in_gif_pause(struct gif_softc *); #endif /* !_NETINET_IN_GIF_H_ */ Index: src/sys/netinet6/in6_gif.c diff -u src/sys/netinet6/in6_gif.c:1.76 src/sys/netinet6/in6_gif.c:1.77 --- src/sys/netinet6/in6_gif.c:1.76 Mon Jul 4 04:14:47 2016 +++ src/sys/netinet6/in6_gif.c Mon Jul 4 04:22:47 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_gif.c,v 1.76 2016/07/04 04:14:47 knakahara Exp $ */ +/* $NetBSD: in6_gif.c,v 1.77 2016/07/04 04:22:47 knakahara Exp $ */ /* $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.76 2016/07/04 04:14:47 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.77 2016/07/04 04:22:47 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -391,12 +391,22 @@ in6_gif_detach(struct gif_softc *sc) { int error; + error = in6_gif_pause(sc); + + rtcache_free(&sc->gif_ro); + + return error; +} + +int +in6_gif_pause(struct gif_softc *sc) +{ + int error; + error = encap_detach(sc->encap_cookie6); if (error == 0) sc->encap_cookie6 = NULL; - rtcache_free(&sc->gif_ro); - return error; } Index: src/sys/netinet6/in6_gif.h diff -u src/sys/netinet6/in6_gif.h:1.14 src/sys/netinet6/in6_gif.h:1.15 --- src/sys/netinet6/in6_gif.h:1.14 Fri Feb 26 07:35:17 2016 +++ src/sys/netinet6/in6_gif.h Mon Jul 4 04:22:47 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_gif.h,v 1.14 2016/02/26 07:35:17 knakahara Exp $ */ +/* $NetBSD: in6_gif.h,v 1.15 2016/07/04 04:22:47 knakahara Exp $ */ /* $KAME: in6_gif.h,v 1.7 2001/07/26 06:53:16 jinmei Exp $ */ /* @@ -45,6 +45,7 @@ int gif_encapcheck6(struct mbuf *, int, #endif int in6_gif_attach(struct gif_softc *); int in6_gif_detach(struct gif_softc *); +int in6_gif_pause(struct gif_softc *); void *in6_gif_ctlinput(int, const struct sockaddr *, void *, void *); #endif /* !_NETINET6_IN6_GIF_H_ */