Interface auto-cloning bug or feature?

Maksim Yevmenkin maksim.yevmenkin at gmail.com
Fri Sep 19 22:51:34 UTC 2008


On Fri, Sep 19, 2008 at 3:43 PM, Maksim Yevmenkin
<maksim.yevmenkin at gmail.com> wrote:
> [....]
>
>>> That what has caused me to look into this issue. You can find patch for
>>> security/vpnc to prevent unbounded interface cloning here:
>>>
>>> http://sobomax.sippysoft.com/~sobomax/vpnc.diff
>>>
>> Ok, the patch prevents interface cloning, but I think it doesn't solve
>> the actual problem.
>> Let's wait for Maksim :)
>
> ok, how about attached patch. i put it together *very* quickly and
> only gave it a light testing. its for tap(4), because i could compile
> it as a module and tun(4) is compiled into kernel by default, but the
> idea should identical for tun(4). should be even simpler for tun(4)
> because it does not have to deal with 2 kind of devices (i.e. tap and
> vmnet). give it a try, and see if it works. please try both cloning
> paths, i.e.
>
> 1) cat /dev/tap (/dev/vmnet) with and/or without unit number
>
> and
>
> 2) ifconfig tapX (vmnetX) create/destroy
>
> in the mean time i will prepare something similar for tun(4).

attached is similar patch for tun(4). i only made sure it compiles :)
rebuilding kernel now...

thanks,
max
-------------- next part --------------
--- if_tun.c.orig	2008-06-20 16:45:07.000000000 -0700
+++ if_tun.c	2008-09-19 15:47:55.000000000 -0700
@@ -129,6 +129,7 @@
 		    struct rtentry *rt);
 static void	tunstart(struct ifnet *);
 
+static int	tun_clone_lookup(struct cdev **);
 static int	tun_clone_create(struct if_clone *, int, caddr_t);
 static void	tun_clone_destroy(struct ifnet *);
 
@@ -174,6 +175,28 @@
 };
 
 static int
+tun_clone_lookup(struct cdev **dev)
+{
+	struct tun_softc *tp;
+
+	mtx_lock(&tunmtx);
+	TAILQ_FOREACH(tp, &tunhead, tun_list) {
+		mtx_lock(&tp->tun_mtx);
+		if ((tp->tun_flags & TUN_OPEN) == 0) {
+			*dev = tp->tun_dev;
+			mtx_unlock(&tp->tun_mtx);
+			mtx_unlock(&tunmtx);
+
+			return (1);
+		}
+		mtx_unlock(&tp->tun_mtx);
+	}
+	mtx_unlock(&tunmtx);
+
+	return (0);
+}
+
+static int
 tun_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 {
 	struct cdev *dev;
@@ -213,6 +236,11 @@
 		return;
 
 	if (strcmp(name, TUNNAME) == 0) {
+		if (tun_clone_lookup(dev)) {
+			dev_ref(*dev);
+			return;
+		}
+
 		u = -1;
 	} else if (dev_stdclone(name, NULL, TUNNAME, &u) != 1)
 		return;	/* Don't recognise the name */


More information about the freebsd-current mailing list