Subject: kern/2005: [dM] tun control device ioctls critically broken
To: None <gnats-bugs@NetBSD.ORG>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 01/31/1996 17:16:45
>Number:         2005
>Category:       kern
>Synopsis:       [dM] tun control device ioctls critically broken
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Jan 31 17:35:01 1996
>Originator:     der Mouse
>Release:        -current sup as of Jan 30 early AM
	Any (found on NetBSD/sparc IPC)
	The cdevsw entry for the tun control device is initialized with
	cdev_bpftun_init(NTUN,tun), which among other things
	initializes the ioctl entry to tunioctl.  The problem is,
	tunioctl is the network device ioctl routine; tuncioctl is the
	control device ioctl routine.  This means that as soon as
	ioctl() is called on the special device, the tunioctl is called
	with arguments appropriate to tuncioctl, which provokes a panic
	in very short order.  (I marked this Priority: medium instead
	of high only because tun ioctls obviously aren't much used.)
	Do any ioctl handled by tuncioctl(), such as TUNGDEBUG, on a
	file descriptor for a tun control device.  Watch the fireworks
	when tunioctl() tries to indirect through its pointer first
	argument, which was passed as a dev_t suitable for tuncioctl
	rather than the struct ifnet * tunioctl wants.
	I just renamed tunioctl->tunnioctl and tuncioctl->tunioctl,
	rather than trying to frob the cdevsw initialization.  Here is
	an attempt at a patch for this; note that this is a hand-edit
	of my patch tree's patch to if_tun.c, and hence may be slightly
	wrong.  I think it's a valid patch, even if the line numbers
	are slightly off, but if patch doesn't like it, apply by hand,
	it's simple.  (The rest of the if_tun.c patch adds extra
	functionality which I haven't yet tested and hence don't feel
	ready to send in.)

--- OLD/sys/net/if_tun.c	Thu Jan  1 00:00:00 1970
+++ NEW/sys/net/if_tun.c	Thu Jan  1 00:00:00 1970
@@ -69,8 +69,8 @@
 	    struct rtentry *rt));
 int	tunread __P((dev_t, struct uio *));
 int	tunwrite __P((dev_t, struct uio *));
-int	tuncioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int	tunioctl __P((struct ifnet *, u_long, caddr_t));
+int	tunioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+int	tunnioctl __P((struct ifnet *, u_long, caddr_t));
 int	tunselect __P((dev_t, int));
 void	tunattach __P((int));
@@ -91,7 +91,7 @@
 		ifp->if_unit = i;
 		ifp->if_name = "tun";
 		ifp->if_mtu = TUNMTU;
-		ifp->if_ioctl = tunioctl;
+		ifp->if_ioctl = tunnioctl;
 		ifp->if_output = tunoutput;
 		ifp->if_flags = IFF_POINTOPOINT;
 		ifp->if_snd.ifq_maxlen = ifqmaxlen;
@@ -219,7 +227,7 @@
  * Process an ioctl request.
-tunioctl(ifp, cmd, data)
+tunnioctl(ifp, cmd, data)
 	struct ifnet *ifp;
 	u_long	cmd;
 	caddr_t	data;
@@ -328,7 +354,7 @@
  * the cdevsw interface is now pretty minimal.
-tuncioctl(dev, cmd, data, flag, p)
+tunioctl(dev, cmd, data, flag, p)
 	dev_t		dev;
 	u_long		cmd;
 	caddr_t		data;

					der Mouse