freebsd-dev/sys/netinet
Christian S.J. Peron 16d878cc99 Fix the following bpf(4) race condition which can result in a panic:
(1) bpf peer attaches to interface netif0
	(2) Packet is received by netif0
	(3) ifp->if_bpf pointer is checked and handed off to bpf
	(4) bpf peer detaches from netif0 resulting in ifp->if_bpf being
	    initialized to NULL.
	(5) ifp->if_bpf is dereferenced by bpf machinery
	(6) Kaboom

This race condition likely explains the various different kernel panics
reported around sending SIGINT to tcpdump or dhclient processes. But really
this race can result in kernel panics anywhere you have frequent bpf attach
and detach operations with high packet per second load.

Summary of changes:

- Remove the bpf interface's "driverp" member
- When we attach bpf interfaces, we now set the ifp->if_bpf member to the
  bpf interface structure. Once this is done, ifp->if_bpf should never be
  NULL. [1]
- Introduce bpf_peers_present function, an inline operation which will do
  a lockless read bpf peer list associated with the interface. It should
  be noted that the bpf code will pickup the bpf_interface lock before adding
  or removing bpf peers. This should serialize the access to the bpf descriptor
  list, removing the race.
- Expose the bpf_if structure in bpf.h so that the bpf_peers_present function
  can use it. This also removes the struct bpf_if; hack that was there.
- Adjust all consumers of the raw if_bpf structure to use bpf_peers_present

Now what happens is:

	(1) Packet is received by netif0
	(2) Check to see if bpf descriptor list is empty
	(3) Pickup the bpf interface lock
	(4) Hand packet off to process

From the attach/detach side:

	(1) Pickup the bpf interface lock
	(2) Add/remove from bpf descriptor list

Now that we are storing the bpf interface structure with the ifnet, there is
is no need to walk the bpf interface list to locate the correct bpf interface.
We now simply look up the interface, and initialize the pointer. This has a
nice side effect of changing a bpf interface attach operation from O(N) (where
N is the number of bpf interfaces), to O(1).

[1] From now on, we can no longer check ifp->if_bpf to tell us whether or
    not we have any bpf peers that might be interested in receiving packets.

In collaboration with:	sam@
MFC after:	1 month
2006-06-02 19:59:33 +00:00
..
libalias
accf_data.c
accf_http.c
icmp6.h
icmp_var.h
if_atm.c
if_atm.h
if_ether.c Further refine the bridge hack in the arp code. Only do the special arp 2006-03-07 21:40:44 +00:00
if_ether.h
igmp_var.h
igmp.c
igmp.h
in_cksum.c
in_gif.c Add some initial locking to gif(4). It doesn't covers the whole driver, 2006-01-30 08:39:09 +00:00
in_gif.h
in_pcb.c Minor restyling and cleanup around ipport_tick(). 2006-06-02 08:18:27 +00:00
in_pcb.h Abstract inpcb drop logic, previously just setting of INP_DROPPED in TCP, 2006-04-25 11:17:35 +00:00
in_proto.c Add RFC 3378 EtherIP support. This change makes it possible to add gif 2005-12-21 21:29:45 +00:00
in_rmx.c
in_systm.h
in_var.h Return mbuf pointer or NULL from ip_fastforward() as the mbuf pointer 2006-01-18 14:24:39 +00:00
in.c In in_control() remove the temporary in_ifaddr structure from the 2006-01-24 16:19:31 +00:00
in.h Fix a long-standing limitation in IPv4 multicast group membership. 2006-05-14 14:22:49 +00:00
ip6.h
ip_carp.c Fix the following bpf(4) race condition which can result in a panic: 2006-06-02 19:59:33 +00:00
ip_carp.h o Introduce carp_multicast_cleanup(), which removes and frees 2006-03-21 14:29:48 +00:00
ip_divert.c Allow for nmbclusters and maxsockets to be increased via sysctl. 2006-04-21 09:25:40 +00:00
ip_divert.h
ip_dummynet.c Obey opt_inet6.h in kernel build directory. 2006-02-20 12:30:32 +00:00
ip_dummynet.h When sending a packet from dummynet, indicate that we're forwarding 2006-02-14 06:36:39 +00:00
ip_ecn.c
ip_ecn.h
ip_encap.c
ip_encap.h
ip_fastfwd.c Merge rev. 1.240 of ip_output.c, so that IPFIREWALL_FORWARD_EXTENDED 2006-04-18 09:20:16 +00:00
ip_fw2.c Implement internal (i.e. inside kernel) packet tagging using mbuf_tags(9). 2006-05-24 13:09:55 +00:00
ip_fw_pfil.c Reintroduce net.inet6.ip6.fw.enable sysctl to dis/enable the ipv6 processing 2006-05-12 04:41:27 +00:00
ip_fw.h Implement internal (i.e. inside kernel) packet tagging using mbuf_tags(9). 2006-05-24 13:09:55 +00:00
ip_gre.c Fix the following bpf(4) race condition which can result in a panic: 2006-06-02 19:59:33 +00:00
ip_gre.h Fix stack corruptions on amd64. 2006-01-21 10:44:34 +00:00
ip_icmp.c Add descriptions for the sysctls: 2006-03-20 21:44:12 +00:00
ip_icmp.h
ip_id.c
ip_input.c Reintroduce net.inet6.ip6.fw.enable sysctl to dis/enable the ipv6 processing 2006-05-12 04:41:27 +00:00
ip_ipsec.c Make sure the ip data pointer is correct before touching it again 2006-05-05 07:31:03 +00:00
ip_ipsec.h Move the IPSEC related code blocks to their own file to unclutter 2006-02-01 13:55:03 +00:00
ip_mroute.c Initialize the new members of struct ip_moptions as 2006-05-18 19:51:08 +00:00
ip_mroute.h Brain-o (use standard int types now). 2006-02-01 06:15:37 +00:00
ip_options.c
ip_options.h
ip_output.c o Add missed error check: in ip_ctloutput() sooptcopyin() returns a 2006-05-21 17:52:08 +00:00
ip_var.h Fix a long-standing limitation in IPv4 multicast group membership. 2006-05-14 14:22:49 +00:00
ip.h
ipprotosw.h
pim_var.h
pim.h
raw_ip.c o In udp|rip_disconnect() acquire a socket lock before the socket 2006-05-21 19:28:46 +00:00
tcp_debug.c
tcp_debug.h
tcp_fsm.h
tcp_hostcache.c
tcp_input.c Allow for nmbclusters and maxsockets to be increased via sysctl. 2006-04-21 09:25:40 +00:00
tcp_output.c This patch fixes the problem where the current TCP code can not handle 2006-02-23 21:14:34 +00:00
tcp_reass.c Allow for nmbclusters and maxsockets to be increased via sysctl. 2006-04-21 09:25:40 +00:00
tcp_sack.c Eliminate debug code that catches bugs in the hinting of sack variables 2006-04-06 17:21:16 +00:00
tcp_seq.h
tcp_subr.c Abstract inpcb drop logic, previously just setting of INP_DROPPED in TCP, 2006-04-25 11:17:35 +00:00
tcp_syncache.c Change soabort() from returning int to returning void, since all 2006-03-16 07:03:14 +00:00
tcp_timer.c - Backout one line from 1.78. The tp can be freed by tcp_drop(). 2006-05-16 10:51:26 +00:00
tcp_timer.h Have TCP Inflight disable itself if the RTT is below a certain 2006-02-16 19:38:07 +00:00
tcp_timewait.c Abstract inpcb drop logic, previously just setting of INP_DROPPED in TCP, 2006-04-25 11:17:35 +00:00
tcp_usrreq.c Instead of calling tcp_usr_detach() from tcp_usr_abort(), break out 2006-04-24 08:20:02 +00:00
tcp_var.h Update TCP for infrastructural changes to the socket/pcb refcount model, 2006-04-01 16:36:36 +00:00
tcp.h Add missing TH_PUSH to the TH_FLAGS enumeration. 2006-02-18 16:50:08 +00:00
tcpip.h
udp_usrreq.c o In udp|rip_disconnect() acquire a socket lock before the socket 2006-05-21 19:28:46 +00:00
udp_var.h
udp.h