summaryrefslogtreecommitdiffstats
path: root/sys/netgraph/ng_base.c
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2001-01-24 21:29:57 +0000
committerjulian <julian@FreeBSD.org>2001-01-24 21:29:57 +0000
commit222035d6b123a02eab80f14e5165f2cf38dfda82 (patch)
tree0c56ce5f5bf42809a788da2c890b5a9b55f49e15 /sys/netgraph/ng_base.c
parent43df074e7c5ac8d62a9cdc1e1506fea5e1ae0151 (diff)
downloadFreeBSD-src-222035d6b123a02eab80f14e5165f2cf38dfda82.zip
FreeBSD-src-222035d6b123a02eab80f14e5165f2cf38dfda82.tar.gz
Don't crash the kernel if the user tries to load a netgraph
module with the wrong version number.
Diffstat (limited to 'sys/netgraph/ng_base.c')
-rw-r--r--sys/netgraph/ng_base.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/netgraph/ng_base.c b/sys/netgraph/ng_base.c
index 8b14e90..78b4aaa 100644
--- a/sys/netgraph/ng_base.c
+++ b/sys/netgraph/ng_base.c
@@ -1142,11 +1142,11 @@ ng_newtype(struct ng_type *tp)
return (EEXIST);
}
- tp->refs = 0;
/* Link in new type */
mtx_enter(&ng_typelist_mtx, MTX_DEF);
LIST_INSERT_HEAD(&ng_typelist, tp, types);
+ tp->refs = 1; /* first ref is linked list */
mtx_exit(&ng_typelist_mtx, MTX_DEF);
return (0);
}
@@ -2678,7 +2678,7 @@ ng_generic_msg(node_p here, item_p item, hook_p lasthook)
break;
}
strncpy(tp->type_name, type->name, NG_TYPELEN);
- tp->numnodes = type->refs;
+ tp->numnodes = type->refs - 1; /* don't count list */
tl->numtypes++;
}
mtx_exit(&ng_typelist_mtx, MTX_DEF);
@@ -2909,6 +2909,7 @@ ng_mod_event(module_t mod, int event, void *data)
if (type->mod_event != NULL)
if ((error = (*type->mod_event)(mod, event, data))) {
mtx_enter(&ng_typelist_mtx, MTX_DEF);
+ type->refs--; /* undo it */
LIST_REMOVE(type, types);
mtx_exit(&ng_typelist_mtx, MTX_DEF);
}
@@ -2917,9 +2918,14 @@ ng_mod_event(module_t mod, int event, void *data)
case MOD_UNLOAD:
s = splnet();
- if (type->refs != 0) /* make sure no nodes exist! */
+ if (type->refs > 1) { /* make sure no nodes exist! */
error = EBUSY;
- else {
+ } else {
+ if (type->refs == 0) {
+ /* failed load, nothing to undo */
+ splx(s);
+ break;
+ }
if (type->mod_event != NULL) { /* check with type */
error = (*type->mod_event)(mod, event, data);
if (error != 0) { /* type refuses.. */
OpenPOWER on IntegriCloud