In the new ifioctl order, tun_ioctl() can call itself through
ifioctl_common(). Since the first tun_ioctl() call already holds the simplelock, the second tun_ioctl() call will wait forever to acquire it: deadlock. To fix this, wait to acquire the lock until tuninit().
This commit is contained in:
parent
7892af0d0c
commit
67852fcbc2
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: if_tun.c,v 1.108 2008/11/07 00:20:13 dyoung Exp $ */
|
||||
/* $NetBSD: if_tun.c,v 1.109 2008/11/20 21:54:42 dyoung Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
|
||||
@ -15,7 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.108 2008/11/07 00:20:13 dyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_tun.c,v 1.109 2008/11/20 21:54:42 dyoung Exp $");
|
||||
|
||||
#include "opt_inet.h"
|
||||
|
||||
@ -388,6 +388,7 @@ tuninit(struct tun_softc *tp)
|
||||
|
||||
TUNDEBUG("%s: tuninit\n", ifp->if_xname);
|
||||
|
||||
simple_lock(&tp->tun_lock);
|
||||
ifp->if_flags |= IFF_UP | IFF_RUNNING;
|
||||
|
||||
tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR);
|
||||
@ -426,6 +427,7 @@ tuninit(struct tun_softc *tp)
|
||||
#endif /* INET6 */
|
||||
}
|
||||
|
||||
simple_unlock(&tp->tun_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -440,7 +442,6 @@ tun_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
||||
struct ifreq *ifr = data;
|
||||
|
||||
s = splnet();
|
||||
simple_lock(&tp->tun_lock);
|
||||
|
||||
switch (cmd) {
|
||||
case SIOCINITIFADDR:
|
||||
@ -487,7 +488,6 @@ tun_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
||||
error = ifioctl_common(ifp, cmd, data);
|
||||
}
|
||||
|
||||
simple_unlock(&tp->tun_lock);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user