Subject: bin/37550: fstat(1) not reporting open descriptors properly
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <mmondor@pulsar-zone.net>
List: netbsd-bugs
Date: 12/16/2007 16:40:00
>Number:         37550
>Category:       bin
>Synopsis:       fstat(1) not reporting open descriptors properly
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Dec 16 16:40:00 +0000 2007
>Originator:     Matthew Mondor
>Release:        NetBSD 4.99.42
>Organization:
>Environment:
System: NetBSD sat.xisop 4.99.42 NetBSD 4.99.42 (GENERIC_LAPTOP_MM) #1: Fri Dec 14 00:35:33 EST 2007  root@sat.xisop:/usr/obj/sys/arch/i386/compile/GENERIC_LAPTOP_MM i386
Architecture: i386
Machine: i386
>Description:
	The fstat(1) utility appears to not show all descriptors while
	our procfs's /<proc>/fd/ directory can show them.  The descriptors
	which it omits in my case are opened instances of tap(4) via
        the /dev/tap cloning device.  Since pts(4) descriptors are shown,
	it might possibly be specific to tap(4) or a few other cloning
	devices, this has to be further investigated.

	Example:
 --- (pts/6) root@sat.xisop # ps axl | grep tap-bridge
   1  4489  5048     0  90 -10  752   952 select   S<   ?      0:05.02 tap-bridge -i fxp0 -a 192.168.1.12 -n 255.255.255.0
   0  5048     1   169  90 -10  752   584 pause    I<s  ?      0:00.00 tap-bridge -i fxp0 -a 192.168.1.12 -n 255.255.255.0
1000 14825   564     0  85   0 1796  2636 select   I+   ttyp2  0:03.29 vim tap-bridge.c
 --- (pts/6) root@sat.xisop # fstat -p 4489
USER     CMD          PID   FD MOUNT       INUM MODE         SZ|DV R/W
daemon   tap-bridge  4489   wd /              2 drwxr-xr-x     512 r
daemon   tap-bridge  4489    0 /         493931 crw-rw-rw-   1251,292468 rw
daemon   tap-bridge  4489    1 /         493931 crw-rw-rw-   1251,292468 rw
daemon   tap-bridge  4489    2 /dev/pts      15 crw--w----   ttyp6 rw
daemon   tap-bridge  4489    3* internet dgram udp c0d69618 *:0
daemon   tap-bridge  4489    7 /         757404 prw-rw----       0 w
 --- (pts/6) root@sat.xisop # fstat -p 5048
USER     CMD          PID   FD MOUNT       INUM MODE         SZ|DV R/W
root     tap-bridge  5048   wd /              2 drwxr-xr-x     512 r
root     tap-bridge  5048    0 /         493931 crw-rw-rw-   1251,292468 rw
root     tap-bridge  5048    1 /         493931 crw-rw-rw-   1251,292468 rw
root     tap-bridge  5048    2 /dev/pts      15 crw--w----   ttyp6 rw
root     tap-bridge  5048    3* internet dgram udp c0d69618 *:0
 --- (pts/6) root@sat.xisop # ls -l /emul/linux/proc/4489/fd/
total 0
crw-rw-rw-  1 root     wheel   2, 2 Dec 16 03:36 0
crw-rw-rw-  1 root     wheel   2, 2 Dec 16 03:36 1
crw--w----  1 mmondor  tty     5, 6 Dec 16 11:08 2
srw-------  1 root     wheel      0 Dec 16 11:08 3
lr-xr-xr-x  1 root     wheel      0 Dec 16 11:08 4 -> [misc]
lr-xr-xr-x  1 root     wheel      0 Dec 16 11:08 5 -> [misc]
prw-rw----  1 root     daemon     0 Dec 16 11:08 7
 --- (pts/6) root@sat.xisop # ls -l /emul/linux/proc/5048/fd/
total 0
crw-rw-rw-  1 root     wheel  2, 2 Dec 16 03:36 0
crw-rw-rw-  1 root     wheel  2, 2 Dec 16 03:36 1
crw--w----  1 mmondor  tty    5, 6 Dec 16 11:08 2
srw-------  1 root     wheel     0 Dec 16 11:08 3
lr-xr-xr-x  1 root     wheel     0 Dec 16 11:08 4 -> [misc]
lr-xr-xr-x  1 root     wheel     0 Dec 16 11:08 5 -> [misc]
 --- (pts/6) root@sat.xisop #

>How-To-Repeat:
	Write a small program opening /dev/tap and look at its descriptors
	via fstat(1) and procfs.

	The code with which I first noticed this is an experimental userland
	layer 2 bridge called tap-bridge which may be found at:

	http://cvs.pulsar-zone.net/cgi-bin/cvsweb.cgi/mmondor/tests/tap/
	(cvs -z3 -d:pserver:anoncvs@cvs.pulsar-zone.net:/cvsroot \
		co mmondor/tests/tap mmondor/mmsoftware/mmlib)

	cd mmondor/tests/tap && gmake
	su
	gmake install && mkfifo /tmp/tap-filter.log && \
		chgrp daemon /tmp/tap-filter.log && \
		chmod g+w /tmp/tap-filter.log

	In another tty cat /tmp/tap-filter.log or whatever to read from fifo
	which the tap-logger.so module will write to.

	ifconfig <ethernetiface> 0.0.0.0
	/etc/rc.d/network stop
	tap-bridge -i <ethernetiface> -a <lanipaddress> -n <netmask>

	where <lanipaddress> and <netmask> would normally be the values set
	to <ethernetiface>, but these will be set on a tap(4), bridged
        through another tap(4) in userland software, which in turn will be
	bridged to <ethernetiface> via bridge(4) (automatically created and
	configured).  Set default route if necessary with:

	route add default <gatewayipaddress>

	To exit and restore original configuration:
	kill $(cat /var/run/tap-bridge.pid)
	/etc/rc.d/network restart

>Fix: