In both if_tun and if_tap:
Do not do additional dev_ref() on the newly created interface in the if_clone create method [1]. This reference is not needed and never removed, causing struct cdevpriv leakage. Remove the setting of SI_CHEAPCLONE flag as well, since it is unused. For dev_clone handlers, create cdevs with the call make_dev_credf(MAKEDEV_REF) instead of calling make_dev() and then dev_ref(), to avoid a race. Call drain_dev_clone_events() at the module unload time after dev_clone handler is deinstalled. Submitted by: Mikolaj Golub <to.my.trociny gmail com> [1] MFC after: 1 week
This commit is contained in:
parent
f7255c488c
commit
22e62e7e6e
@ -192,10 +192,6 @@ tap_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
if (i) {
|
||||
dev = make_dev(&tap_cdevsw, unit | extra,
|
||||
UID_ROOT, GID_WHEEL, 0600, "%s%d", ifc->ifc_name, unit);
|
||||
if (dev != NULL) {
|
||||
dev_ref(dev);
|
||||
dev->si_flags |= SI_CHEAPCLONE;
|
||||
}
|
||||
}
|
||||
|
||||
tapcreate(dev);
|
||||
@ -300,6 +296,7 @@ tapmodevent(module_t mod, int type, void *data)
|
||||
EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
|
||||
if_clone_detach(&tap_cloner);
|
||||
if_clone_detach(&vmnet_cloner);
|
||||
drain_dev_clone_events();
|
||||
|
||||
mtx_lock(&tapmtx);
|
||||
while ((tp = SLIST_FIRST(&taphead)) != NULL) {
|
||||
@ -381,12 +378,8 @@ tapclone(void *arg, struct ucred *cred, char *name, int namelen, struct cdev **d
|
||||
name = devname;
|
||||
}
|
||||
|
||||
*dev = make_dev(&tap_cdevsw, unit | extra,
|
||||
UID_ROOT, GID_WHEEL, 0600, "%s", name);
|
||||
if (*dev != NULL) {
|
||||
dev_ref(*dev);
|
||||
(*dev)->si_flags |= SI_CHEAPCLONE;
|
||||
}
|
||||
*dev = make_dev_credf(MAKEDEV_REF, &tap_cdevsw, unit | extra,
|
||||
cred, UID_ROOT, GID_WHEEL, 0600, "%s", name);
|
||||
}
|
||||
|
||||
if_clone_create(name, namelen, NULL);
|
||||
|
@ -188,10 +188,6 @@ tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
||||
/* No preexisting struct cdev *, create one */
|
||||
dev = make_dev(&tun_cdevsw, unit,
|
||||
UID_UUCP, GID_DIALER, 0600, "%s%d", ifc->ifc_name, unit);
|
||||
if (dev != NULL) {
|
||||
dev_ref(dev);
|
||||
dev->si_flags |= SI_CHEAPCLONE;
|
||||
}
|
||||
}
|
||||
tuncreate(ifc->ifc_name, dev);
|
||||
|
||||
@ -237,12 +233,8 @@ tunclone(void *arg, struct ucred *cred, char *name, int namelen,
|
||||
name = devname;
|
||||
}
|
||||
/* No preexisting struct cdev *, create one */
|
||||
*dev = make_dev(&tun_cdevsw, u,
|
||||
*dev = make_dev_credf(MAKEDEV_REF, &tun_cdevsw, u, cred,
|
||||
UID_UUCP, GID_DIALER, 0600, "%s", name);
|
||||
if (*dev != NULL) {
|
||||
dev_ref(*dev);
|
||||
(*dev)->si_flags |= SI_CHEAPCLONE;
|
||||
}
|
||||
}
|
||||
|
||||
if_clone_create(name, namelen, NULL);
|
||||
@ -303,6 +295,7 @@ tunmodevent(module_t mod, int type, void *data)
|
||||
case MOD_UNLOAD:
|
||||
if_clone_detach(&tun_cloner);
|
||||
EVENTHANDLER_DEREGISTER(dev_clone, tag);
|
||||
drain_dev_clone_events();
|
||||
|
||||
mtx_lock(&tunmtx);
|
||||
while ((tp = TAILQ_FIRST(&tunhead)) != NULL) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user