CVSROOT:        /cvs
Module name:    src
Changes by:     sas...@cvs.openbsd.org  2019/10/21 17:02:05

Modified files:
        sys/net        : bpf.c bpfdesc.h 

Log message:
put bpfdesc reference counting back, revert change introduced in 1.175 as:
BPF: remove redundant reference counting of filedescriptors

Anton@ made problem crystal clear:
I've been looking into a similar bpf panic reported by syzkaller,
which looks somewhat related. The one reported by syzkaller is caused
by issuing ioctl(SIOCIFDESTROY) on the interface which the packet filter
is attached to. This will in turn invoke the following functions
expressed as an inverted stacktrace:
1. bpfsdetach()
2. vdevgone()
3. VOP_REVOKE()
4. vop_generic_revoke()
5. vgonel()
6. vclean(DOCLOSE)
7. VOP_CLOSE()
8. bpfclose()

Note that bpfclose() is called before changing the vnode type. In
bpfclose(), the `struct bpf_d` is immediately removed from the global
bpf_d_list list and might end up sleeping inside taskq_barrier(systq).
Since the bpf file descriptor (fd) is still present and valid, another
thread could perform an ioctl() on the fd only to fault since
bpfilter_lookup() will return NULL. The vnode is not locked in this path
either so it won't end up waiting on the ongoing vclean().

Steps to trigger the similar type of panic are straightforward, let there be
two processes running concurrently:

process A:
while true ; do ifconfig tun0 up ; ifconfig tun0 destroy ; done

process B:
while true ; do tcpdump -i tun0 ; done

panic happens within few secs (Dell PowerEdge 710)

OK @visa, OK @anton

Reply via email to