diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-03-17 01:12:09 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-03-17 01:12:09 +0000 |
commit | 131892ca17e9e6a23bd98f9bef05d035b36d2790 (patch) | |
tree | 4feb979a3e8301da340cd358c13b67adee8d0070 /sys/net/if_tun.c | |
parent | 90c4d019f1c1199a2e583bd63284144eb0c858e5 (diff) | |
download | FreeBSD-src-131892ca17e9e6a23bd98f9bef05d035b36d2790.zip FreeBSD-src-131892ca17e9e6a23bd98f9bef05d035b36d2790.tar.gz |
Remove tun_proc; replace with tun_pid. tun_proc pointer may be stale
as the process that opens tun_softc can exit before the file
descriptor is closed.
Taiwan experience provided by: keichii
Crashing breakers provided by: Chia-liang Kao <clkao@clkao.org>
Diffstat (limited to 'sys/net/if_tun.c')
-rw-r--r-- | sys/net/if_tun.c | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/sys/net/if_tun.c b/sys/net/if_tun.c index 78aa654..2579b93 100644 --- a/sys/net/if_tun.c +++ b/sys/net/if_tun.c @@ -71,7 +71,14 @@ struct tun_softc { #define TUN_READY (TUN_OPEN | TUN_INITED) - struct proc *tun_proc; /* Owning process */ + /* + * XXXRW: tun_pid is used to exclusively lock /dev/tun. Is this + * actually needed? Can we just return EBUSY if already open? + * Problem is that this involved inherent races when a tun device + * is handed off from one process to another, as opposed to just + * being slightly stale informationally. + */ + pid_t tun_pid; /* owning pid */ struct ifnet tun_if; /* the interface */ struct sigio *tun_sigio; /* information for async I/O */ struct selinfo tun_rsel; /* read select */ @@ -237,9 +244,9 @@ tunopen(dev_t dev, int flag, int mode, struct thread *td) tp = dev->si_drv1; } - if (tp->tun_proc != NULL && tp->tun_proc != td->td_proc) + if (tp->tun_pid != 0 && tp->tun_pid != td->td_proc->p_pid) return (EBUSY); - tp->tun_proc = td->td_proc; + tp->tun_pid = td->td_proc->p_pid; tp->tun_flags |= TUN_OPEN; ifp = &tp->tun_if; @@ -263,7 +270,7 @@ tunclose(dev_t dev, int foo, int bar, struct thread *td) ifp = &tp->tun_if; tp->tun_flags &= ~TUN_OPEN; - tp->tun_proc = NULL; + tp->tun_pid = 0; /* * junk all pending output @@ -346,9 +353,9 @@ tunifioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch(cmd) { case SIOCGIFSTATUS: ifs = (struct ifstat *)data; - if (tp->tun_proc) + if (tp->tun_pid) sprintf(ifs->ascii + strlen(ifs->ascii), - "\tOpened by PID %d\n", tp->tun_proc->p_pid); + "\tOpened by PID %d\n", tp->tun_pid); break; case SIOCSIFADDR: error = tuninit(ifp); @@ -535,7 +542,7 @@ tunioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct thread *td) } break; case TUNSIFPID: - tp->tun_proc = curthread->td_proc; + tp->tun_pid = curthread->td_proc->p_pid; break; case FIONBIO: break; |