From 6be00a6c237c502c8dfb52e570f12a0c0b195aff Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 5 Sep 2008 17:03:15 +0000 Subject: [PATCH] Fix a crash on access to TAP's owning thread. The owning thread can go away with the descriptor still open, for example if the opening process forks into a background daemon and the foreground process exits. Use the SIGIO mechanic to record the owning thread so we can detect if the process goes away. --- sys/net/tap/if_tap.c | 18 +++++++++++------- sys/net/tap/if_tapvar.h | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/sys/net/tap/if_tap.c b/sys/net/tap/if_tap.c index 0fa9828677..c085fdad29 100644 --- a/sys/net/tap/if_tap.c +++ b/sys/net/tap/if_tap.c @@ -32,7 +32,7 @@ /* * $FreeBSD: src/sys/net/if_tap.c,v 1.3.2.3 2002/04/14 21:41:48 luigi Exp $ - * $DragonFly: src/sys/net/tap/if_tap.c,v 1.40 2008/05/18 05:12:08 sephe Exp $ + * $DragonFly: src/sys/net/tap/if_tap.c,v 1.41 2008/09/05 17:03:15 dillon Exp $ * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $ */ @@ -291,7 +291,8 @@ tapopen(struct dev_open_args *ap) bcopy(tp->arpcom.ac_enaddr, tp->ether_addr, sizeof(tp->ether_addr)); - tp->tap_td = curthread; + if (curthread->td_proc) + fsetown(curthread->td_proc->p_pid, &tp->tap_sigtd); tp->tap_flags |= TAP_OPEN; taprefcnt ++; @@ -343,10 +344,12 @@ tapclose(struct dev_close_args *ap) rt_ifannouncemsg(ifp, IFAN_DEPARTURE); funsetown(tp->tap_sigio); + tp->tap_sigio = NULL; selwakeup(&tp->tap_rsel); tp->tap_flags &= ~TAP_OPEN; - tp->tap_td = NULL; + funsetown(tp->tap_sigtd); + tp->tap_sigtd = NULL; taprefcnt --; if (taprefcnt < 0) { @@ -434,16 +437,17 @@ tapifioctl(struct ifnet *ifp, u_long cmd, caddr_t data, struct ucred *cr) case SIOCGIFSTATUS: ifs = (struct ifstat *)data; dummy = strlen(ifs->ascii); - if (tp->tap_td != NULL && dummy < sizeof(ifs->ascii)) { - if (tp->tap_td->td_proc) { + if ((tp->tap_flags & TAP_OPEN) && + dummy < sizeof(ifs->ascii)) { + if (tp->tap_sigtd && tp->tap_sigtd->sio_proc) { ksnprintf(ifs->ascii + dummy, sizeof(ifs->ascii) - dummy, "\tOpened by pid %d\n", - (int)tp->tap_td->td_proc->p_pid); + (int)tp->tap_sigtd->sio_proc->p_pid); } else { ksnprintf(ifs->ascii + dummy, sizeof(ifs->ascii) - dummy, - "\tOpened by td %p\n", tp->tap_td); + "\tOpened by \n"); } } break; diff --git a/sys/net/tap/if_tapvar.h b/sys/net/tap/if_tapvar.h index dcaecfe9aa..2cd173e44e 100644 --- a/sys/net/tap/if_tapvar.h +++ b/sys/net/tap/if_tapvar.h @@ -35,7 +35,7 @@ /* * $FreeBSD: src/sys/net/if_tapvar.h,v 1.3.2.1 2000/07/27 13:57:05 nsayer Exp $ - * $DragonFly: src/sys/net/tap/if_tapvar.h,v 1.5 2008/05/18 05:12:08 sephe Exp $ + * $DragonFly: src/sys/net/tap/if_tapvar.h,v 1.6 2008/09/05 17:03:15 dillon Exp $ * $Id: if_tapvar.h,v 0.6 2000/07/11 02:16:08 max Exp $ */ @@ -57,7 +57,7 @@ struct tap_softc { u_int8_t ether_addr[ETHER_ADDR_LEN]; /* ether addr of the remote side */ - struct thread *tap_td; /* thread of process to open */ + struct sigio *tap_sigtd; /* track process owning tap */ struct sigio *tap_sigio; /* information for async I/O */ struct selinfo tap_rsel; /* read select */ struct ifqueue tap_devq; -- 2.41.0