DF-0296 / fix.diff
diff --git a/sys/netgraph/netgraph/ng_base.c b/sys/netgraph/netgraph/ng_base.c --- a/sys/netgraph/netgraph/ng_base.c +++ b/sys/netgraph/netgraph/ng_base.c @@ -694,6 +694,19 @@ } /* + * DF-0296: Take a reference on a hook so it (and its peer) cannot be + * freed while the caller dereferences hook->peer->node. Callers MUST + * call ng_unref_hook() when done. + */ +void +ng_ref_hook(hook_p hook) +{ + crit_enter(); + hook->refs++; + crit_exit(); +} + +/* * Add an unconnected hook to a node. Only used internally. */ static int @@ -1138,15 +1151,24 @@ hook = ng_findhook(node, segment); /* Can't get there from here... */ - if (hook == NULL - || hook->peer == NULL + if (hook == NULL) { + TRAP_ERROR; + return (ENOENT); + } + /* DF-0296: Take a reference so the peer hook/node cannot be + * freed by ng_destroy_hook() while we dereference peer->node. + */ + ng_ref_hook(hook); + if (hook->peer == NULL || (hook->flags & HK_INVALID) != 0) { + ng_unref_hook(hook); TRAP_ERROR; return (ENOENT); } /* Hop on over to the next node */ node = hook->peer->node; + ng_unref_hook(hook); } /* If node somehow missing, fail here (probably this is not needed) */ |