From owner-cvs-all@FreeBSD.ORG Fri Jun 2 20:01:05 2006 Return-Path: X-Original-To: cvs-all@FreeBSD.org Delivered-To: cvs-all@FreeBSD.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 88EB616A4D8; Fri, 2 Jun 2006 20:01:05 +0000 (UTC) (envelope-from csjp@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4341843D4C; Fri, 2 Jun 2006 20:01:05 +0000 (GMT) (envelope-from csjp@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k52JxXSC022149; Fri, 2 Jun 2006 19:59:33 GMT (envelope-from csjp@repoman.freebsd.org) Received: (from csjp@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k52JxXlr022148; Fri, 2 Jun 2006 19:59:33 GMT (envelope-from csjp) Message-Id: <200606021959.k52JxXlr022148@repoman.freebsd.org> From: "Christian S.J. Peron" Date: Fri, 2 Jun 2006 19:59:33 +0000 (UTC) To: src-committers@FreeBSD.org, cvs-src@FreeBSD.org, cvs-all@FreeBSD.org X-FreeBSD-CVS-Branch: HEAD Cc: Subject: cvs commit: src/sys/dev/ath if_ath.c src/sys/dev/ipw if_ipw.c src/sys/dev/iwi if_iwi.c src/sys/dev/ral rt2560.c rt2661.c src/sys/dev/usb if_ural.c src/sys/dev/wi if_wi.c src/sys/net bpf.c bpf.h bpfdesc.h if_disc.c if_gif.c if_gre.c if_loop.c if_sl.c ... X-BeenThere: cvs-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: CVS commit messages for the entire tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Jun 2006 20:01:07 -0000 csjp 2006-06-02 19:59:33 UTC FreeBSD src repository Modified files: sys/dev/ath if_ath.c sys/dev/ipw if_ipw.c sys/dev/iwi if_iwi.c sys/dev/ral rt2560.c rt2661.c sys/dev/usb if_ural.c sys/dev/wi if_wi.c sys/net bpf.c bpf.h bpfdesc.h if_disc.c if_gif.c if_gre.c if_loop.c if_sl.c if_stf.c if_tun.c sys/net80211 ieee80211_input.c sys/netinet ip_carp.c ip_gre.c Log: 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 Revision Changes Path 1.145 +4 -3 src/sys/dev/ath/if_ath.c 1.20 +2 -2 src/sys/dev/ipw/if_ipw.c 1.37 +2 -2 src/sys/dev/iwi/if_iwi.c 1.5 +7 -7 src/sys/dev/ral/rt2560.c 1.6 +3 -3 src/sys/dev/ral/rt2661.c 1.39 +3 -3 src/sys/dev/usb/if_ural.c 1.196 +3 -3 src/sys/dev/wi/if_wi.c 1.166 +24 -71 src/sys/net/bpf.c 1.41 +22 -4 src/sys/net/bpf.h 1.34 +0 -13 src/sys/net/bpfdesc.h 1.52 +1 -1 src/sys/net/if_disc.c 1.60 +2 -4 src/sys/net/if_gif.c 1.42 +1 -1 src/sys/net/if_gre.c 1.109 +1 -1 src/sys/net/if_loop.c 1.132 +4 -4 src/sys/net/if_sl.c 1.54 +2 -2 src/sys/net/if_stf.c 1.155 +1 -1 src/sys/net/if_tun.c 1.91 +4 -4 src/sys/net80211/ieee80211_input.c 1.40 +1 -1 src/sys/netinet/ip_carp.c 1.24 +2 -2 src/sys/netinet/ip_gre.c