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.
This commit is contained in:
parent
850de3d9a9
commit
a6d7586724
|
@ -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(). */
|
||||
|
||||
|
|
|
@ -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 = 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;
|
||||
}
|
||||
|
|
|
@ -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, int, void *);
|
|||
#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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, int, void *);
|
|||
#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_ */
|
||||
|
|
Loading…
Reference in New Issue