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

Reply via email to