Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Oct 2019 02:57:01 +0000 (UTC)
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r353159 - releng/12.1/sys/net
Message-ID:  <201910070257.x972v1s5050851@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Mon Oct  7 02:57:00 2019
New Revision: 353159
URL: https://svnweb.freebsd.org/changeset/base/353159

Log:
  MFS r353157: tuntap(4): loosen up tunclose restrictions
  
  Realistically, this cannot work. We don't allow the tun to be opened twice,
  so it must be done via fd passing, fork, dup, some mechanism like these.
  Applications demonstrably do not enforce strict ordering when they're
  handing off tun devices, so the parent closing before the child will easily
  leave the tun/tap device in a bad state where it can't be destroyed and a
  confused user because they did nothing wrong.
  
  Concede that we can't leave the tun/tap device in this kind of state because
  of software not playing the TUNSIFPID game, but it is still good to find and
  fix this kind of thing to keep ifconfig(8) up-to-date and help ensure good
  discipline in tun handling.
  
  Approved by:	re (gjb)

Modified:
  releng/12.1/sys/net/if_tun.c
Directory Properties:
  releng/12.1/   (props changed)

Modified: releng/12.1/sys/net/if_tun.c
==============================================================================
--- releng/12.1/sys/net/if_tun.c	Mon Oct  7 02:36:42 2019	(r353158)
+++ releng/12.1/sys/net/if_tun.c	Mon Oct  7 02:57:00 2019	(r353159)
@@ -32,6 +32,7 @@
 #include <sys/filio.h>
 #include <sys/sockio.h>
 #include <sys/sx.h>
+#include <sys/syslog.h>
 #include <sys/ttycom.h>
 #include <sys/poll.h>
 #include <sys/selinfo.h>
@@ -493,22 +494,28 @@ tunopen(struct cdev *dev, int flag, int mode, struct t
 static	int
 tunclose(struct cdev *dev, int foo, int bar, struct thread *td)
 {
+	struct proc *p;
 	struct tun_softc *tp;
 	struct ifnet *ifp;
 
+	p = td->td_proc;
 	tp = dev->si_drv1;
 	ifp = TUN2IFP(tp);
 
 	mtx_lock(&tp->tun_mtx);
+
 	/*
-	 * Simply close the device if this isn't the controlling process.  This
-	 * may happen if, for instance, the tunnel has been handed off to
-	 * another process.  The original controller should be able to close it
-	 * without putting us into an inconsistent state.
+	 * Realistically, we can't be obstinate here.  This only means that the
+	 * tuntap device was closed out of order, and the last closer wasn't the
+	 * controller.  These are still good to know about, though, as software
+	 * should avoid multiple processes with a tuntap device open and
+	 * ill-defined transfer of control (e.g., handoff, TUNSIFPID, close in
+	 * parent).
 	 */
-	if (td->td_proc->p_pid != tp->tun_pid) {
-		mtx_unlock(&tp->tun_mtx);
-		return (0);
+	if (p->p_pid != tp->tun_pid) {
+		log(LOG_INFO,
+		    "pid %d (%s), %s: tun/tap protocol violation, non-controlling process closed last.\n",
+		    p->p_pid, p->p_comm, dev->si_name);
 	}
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201910070257.x972v1s5050851>