From owner-svn-src-stable-11@freebsd.org Wed Aug 30 21:18:58 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 200ECE0A5E0; Wed, 30 Aug 2017 21:18:58 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id DE1E48056E; Wed, 30 Aug 2017 21:18:57 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v7ULIuL1035748; Wed, 30 Aug 2017 21:18:56 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7ULIuwf035747; Wed, 30 Aug 2017 21:18:56 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201708302118.v7ULIuwf035747@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Wed, 30 Aug 2017 21:18:56 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r323034 - stable/11/sys/net X-SVN-Group: stable-11 X-SVN-Commit-Author: kp X-SVN-Commit-Paths: stable/11/sys/net X-SVN-Commit-Revision: 323034 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Aug 2017 21:18:58 -0000 Author: kp Date: Wed Aug 30 21:18:56 2017 New Revision: 323034 URL: https://svnweb.freebsd.org/changeset/base/323034 Log: MFC r322590: bpf: Fix incorrect cleanup Cleaning up a bpf_if is a two stage process. We first move it to the bpf_freelist (in bpfdetach()) and only later do we actually free it (in bpf_ifdetach()). We cannot set the ifp->if_bpf to NULL from bpf_ifdetach() because it's possible that the ifnet has already gone away, or that it has been assigned a new bpf_if. This can lead to a struct ifnet which is up, but has if_bpf set to NULL, which will panic when we try to send the next packet. Keep track of the pointer to the bpf_if (because it's not always ifp->if_bpf), and NULL it immediately in bpfdetach(). PR: 213896 Differential Revision: https://reviews.freebsd.org/D11782 Modified: stable/11/sys/net/bpf.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/net/bpf.c ============================================================================== --- stable/11/sys/net/bpf.c Wed Aug 30 21:18:43 2017 (r323033) +++ stable/11/sys/net/bpf.c Wed Aug 30 21:18:56 2017 (r323034) @@ -106,6 +106,7 @@ struct bpf_if { struct rwlock bif_lock; /* interface lock */ LIST_HEAD(, bpf_d) bif_wlist; /* writer-only list */ int bif_flags; /* Interface flags */ + struct bpf_if **bif_bpf; /* Pointer to pointer to us */ }; CTASSERT(offsetof(struct bpf_if, bif_ext) == 0); @@ -2563,6 +2564,7 @@ bpfattach2(struct ifnet *ifp, u_int dlt, u_int hdrlen, bp->bif_dlt = dlt; rw_init(&bp->bif_lock, "bpf interface lock"); KASSERT(*driverp == NULL, ("bpfattach2: driverp already initialized")); + bp->bif_bpf = driverp; *driverp = bp; BPF_LOCK(); @@ -2633,6 +2635,7 @@ bpfdetach(struct ifnet *ifp) */ BPFIF_WLOCK(bp); bp->bif_flags |= BPFIF_FLAG_DYING; + *bp->bif_bpf = NULL; BPFIF_WUNLOCK(bp); CTR4(KTR_NET, "%s: sheduling free for encap %d (%p) for if %p", @@ -2702,13 +2705,6 @@ bpf_ifdetach(void *arg __unused, struct ifnet *ifp) nmatched++; } BPF_UNLOCK(); - - /* - * Note that we cannot zero other pointers to - * custom DLTs possibly used by given interface. - */ - if (nmatched != 0) - ifp->if_bpf = NULL; } /*