FreeBSD Bugzilla – Attachment 184119 Details for
Bug 220076
[patch] [panic] [netgraph] repeatable kernel panic due to a race in ng_iface(4)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
protect ng_iface private data with rmlock
ng_iface.c.diff (text/plain), 3.98 KB, created by
Eugene Grosbein
on 2017-07-06 11:17:34 UTC
(
hide
)
Description:
protect ng_iface private data with rmlock
Filename:
MIME Type:
Creator:
Eugene Grosbein
Created:
2017-07-06 11:17:34 UTC
Size:
3.98 KB
patch
obsolete
>--- sys/netgraph/ng_iface.c.orig 2017-06-19 19:57:23.302960000 +0700 >+++ sys/netgraph/ng_iface.c 2017-07-06 17:24:41.007278000 +0700 >@@ -64,6 +64,7 @@ > #include <sys/errno.h> > #include <sys/proc.h> > #include <sys/random.h> >+#include <sys/rmlock.h> > #include <sys/sockio.h> > #include <sys/socket.h> > #include <sys/syslog.h> >@@ -112,9 +113,15 @@ struct ng_iface_private { > int unit; /* Interface unit number */ > node_p node; /* Our netgraph node */ > hook_p hooks[NUM_FAMILIES]; /* Hook for each address family */ >+ struct rmlock lock; /* Protect private data changes */ > }; > typedef struct ng_iface_private *priv_p; > >+#define PRIV_RLOCK(priv, t) rm_rlock(&priv->lock, t) >+#define PRIV_RUNLOCK(priv, t) rm_runlock(&priv->lock, t) >+#define PRIV_WLOCK(priv) rm_wlock(&priv->lock) >+#define PRIV_WUNLOCK(priv) rm_wunlock(&priv->lock) >+ > /* Interface methods */ > static void ng_iface_start(struct ifnet *ifp); > static int ng_iface_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); >@@ -134,6 +141,7 @@ static ng_constructor_t ng_iface_constru > static ng_rcvmsg_t ng_iface_rcvmsg; > static ng_shutdown_t ng_iface_shutdown; > static ng_newhook_t ng_iface_newhook; >+static ng_findhook_t ng_iface_findhook; > static ng_rcvdata_t ng_iface_rcvdata; > static ng_disconnect_t ng_iface_disconnect; > >@@ -185,6 +193,7 @@ static struct ng_type typestruct = { > .rcvmsg = ng_iface_rcvmsg, > .shutdown = ng_iface_shutdown, > .newhook = ng_iface_newhook, >+ .findhook = ng_iface_findhook, > .rcvdata = ng_iface_rcvdata, > .disconnect = ng_iface_disconnect, > .cmdlist = ng_iface_cmds, >@@ -431,6 +440,7 @@ ng_iface_bpftap(struct ifnet *ifp, struc > static int > ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa) > { >+ struct rm_priotracker priv_tracker; > const priv_p priv = (priv_p) ifp->if_softc; > const iffam_p iffam = get_iffam_from_af(sa); > int error; >@@ -448,7 +458,9 @@ ng_iface_send(struct ifnet *ifp, struct > > /* Send packet. If hook is not connected, mbuf will get freed. */ > NG_OUTBOUND_THREAD_REF(); >+ PRIV_RLOCK(priv, &priv_tracker); > NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m); >+ PRIV_RUNLOCK(priv, &priv_tracker); > NG_OUTBOUND_THREAD_UNREF(); > > /* Update stats. */ >@@ -516,6 +528,8 @@ ng_iface_constructor(node_p node) > return (ENOMEM); > } > >+ rm_init(&priv->lock, "ng_iface private rmlock"); >+ > /* Link them together */ > ifp->if_softc = priv; > priv->ifp = ifp; >@@ -562,19 +576,45 @@ static int > ng_iface_newhook(node_p node, hook_p hook, const char *name) > { > const iffam_p iffam = get_iffam_from_name(name); >+ const priv_p priv = NG_NODE_PRIVATE(node); > hook_p *hookptr; > > if (iffam == NULL) > return (EPFNOSUPPORT); >- hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam); >- if (*hookptr != NULL) >+ PRIV_WLOCK(priv); >+ hookptr = get_hook_from_iffam(priv, iffam); >+ if (*hookptr != NULL) { >+ PRIV_WUNLOCK(priv); > return (EISCONN); >+ } > *hookptr = hook; > NG_HOOK_HI_STACK(hook); > NG_HOOK_SET_TO_INBOUND(hook); >+ PRIV_WUNLOCK(priv); > return (0); > } > >+/* Look up hook by name */ >+static hook_p >+ng_iface_findhook(node_p node, const char *name) >+{ >+ struct rm_priotracker priv_tracker; >+ const iffam_p iffam = get_iffam_from_name(name); >+ const priv_p priv = NG_NODE_PRIVATE(node); >+ hook_p *hookptr; >+ >+ if (iffam == NULL) >+ return (NULL); >+ PRIV_RLOCK(priv, &priv_tracker); >+ hookptr = get_hook_from_iffam(priv, iffam); >+ if (*hookptr && NG_HOOK_IS_VALID(*hookptr)) { >+ PRIV_RUNLOCK(priv, &priv_tracker); >+ return (*hookptr); >+ } >+ PRIV_RUNLOCK(priv, &priv_tracker); >+ return (NULL); >+} >+ > /* > * Receive a control message > */ >@@ -730,6 +770,7 @@ ng_iface_shutdown(node_p node) > CURVNET_RESTORE(); > priv->ifp = NULL; > free_unr(V_ng_iface_unit, priv->unit); >+ rm_destroy(&priv->lock); > free(priv, M_NETGRAPH_IFACE); > NG_NODE_SET_PRIVATE(node, NULL); > NG_NODE_UNREF(node); >@@ -748,7 +789,9 @@ ng_iface_disconnect(hook_p hook) > > if (iffam == NULL) > panic("%s", __func__); >+ PRIV_WLOCK(priv); > *get_hook_from_iffam(priv, iffam) = NULL; >+ PRIV_WUNLOCK(priv); > return (0); > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 220076
:
183566
|
183625
|
183627
|
184119
|
186781