Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys fix: gif(4) receive side race
details: https://anonhg.NetBSD.org/src/rev/ff57253b00ac
branches: trunk
changeset: 346260:ff57253b00ac
user: knakahara <knakahara%NetBSD.org@localhost>
date: Mon Jul 04 04:22:47 2016 +0000
description:
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.
diffstat:
sys/net/if_gif.c | 26 +++++++++++++++++++++++---
sys/netinet/in_gif.c | 20 +++++++++++++++-----
sys/netinet/in_gif.h | 3 ++-
sys/netinet6/in6_gif.c | 18 ++++++++++++++----
sys/netinet6/in6_gif.h | 3 ++-
5 files changed, 56 insertions(+), 14 deletions(-)
diffs (168 lines):
diff -r 5de874748480 -r ff57253b00ac sys/net/if_gif.c
--- a/sys/net/if_gif.c Mon Jul 04 04:20:14 2016 +0000
+++ b/sys/net/if_gif.c Mon Jul 04 04:22:47 2016 +0000
@@ -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 @@
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(). */
diff -r 5de874748480 -r ff57253b00ac sys/netinet/in_gif.c
--- a/sys/netinet/in_gif.c Mon Jul 04 04:20:14 2016 +0000
+++ b/sys/netinet/in_gif.c Mon Jul 04 04:22:47 2016 +0000
@@ -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 @@
{
int error;
- error = encap_detach(sc->encap_cookie4);
- if (error == 0)
- sc->encap_cookie4 = NULL;
+ 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;
+
+ return error;
+}
diff -r 5de874748480 -r ff57253b00ac sys/netinet/in_gif.h
--- a/sys/netinet/in_gif.h Mon Jul 04 04:20:14 2016 +0000
+++ b/sys/netinet/in_gif.h Mon Jul 04 04:22:47 2016 +0000
@@ -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 @@
#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_ */
diff -r 5de874748480 -r ff57253b00ac sys/netinet6/in6_gif.c
--- a/sys/netinet6/in6_gif.c Mon Jul 04 04:20:14 2016 +0000
+++ b/sys/netinet6/in6_gif.c Mon Jul 04 04:22:47 2016 +0000
@@ -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 @@
{
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;
}
diff -r 5de874748480 -r ff57253b00ac sys/netinet6/in6_gif.h
--- a/sys/netinet6/in6_gif.h Mon Jul 04 04:20:14 2016 +0000
+++ b/sys/netinet6/in6_gif.h Mon Jul 04 04:22:47 2016 +0000
@@ -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 @@
#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_ */
Home |
Main Index |
Thread Index |
Old Index