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>
|
* Copyright (c) 1988, Julian Onions <jpo@cs.nott.ac.uk>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#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"
|
#include "opt_inet.h"
|
||||||
|
|
||||||
@ -388,6 +388,7 @@ tuninit(struct tun_softc *tp)
|
|||||||
|
|
||||||
TUNDEBUG("%s: tuninit\n", ifp->if_xname);
|
TUNDEBUG("%s: tuninit\n", ifp->if_xname);
|
||||||
|
|
||||||
|
simple_lock(&tp->tun_lock);
|
||||||
ifp->if_flags |= IFF_UP | IFF_RUNNING;
|
ifp->if_flags |= IFF_UP | IFF_RUNNING;
|
||||||
|
|
||||||
tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR);
|
tp->tun_flags &= ~(TUN_IASET|TUN_DSTADDR);
|
||||||
@ -426,6 +427,7 @@ tuninit(struct tun_softc *tp)
|
|||||||
#endif /* INET6 */
|
#endif /* INET6 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simple_unlock(&tp->tun_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,7 +442,6 @@ tun_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
|||||||
struct ifreq *ifr = data;
|
struct ifreq *ifr = data;
|
||||||
|
|
||||||
s = splnet();
|
s = splnet();
|
||||||
simple_lock(&tp->tun_lock);
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case SIOCINITIFADDR:
|
case SIOCINITIFADDR:
|
||||||
@ -487,7 +488,6 @@ tun_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
|||||||
error = ifioctl_common(ifp, cmd, data);
|
error = ifioctl_common(ifp, cmd, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
simple_unlock(&tp->tun_lock);
|
|
||||||
splx(s);
|
splx(s);
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user