From owner-svn-src-all@freebsd.org Wed Aug 16 19:40:08 2017 Return-Path: Delivered-To: svn-src-all@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 D75F1DCBBF3; Wed, 16 Aug 2017 19:40:08 +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 A1DAE6C6FD; Wed, 16 Aug 2017 19:40:08 +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 v7GJe7G7099849; Wed, 16 Aug 2017 19:40:07 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v7GJe7OI099848; Wed, 16 Aug 2017 19:40:07 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201708161940.v7GJe7OI099848@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Wed, 16 Aug 2017 19:40:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r322590 - head/sys/net X-SVN-Group: head X-SVN-Commit-Author: kp X-SVN-Commit-Paths: head/sys/net X-SVN-Commit-Revision: 322590 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Aug 2017 19:40:09 -0000 Author: kp Date: Wed Aug 16 19:40:07 2017 New Revision: 322590 URL: https://svnweb.freebsd.org/changeset/base/322590 Log: 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 MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D11782 Modified: head/sys/net/bpf.c Modified: head/sys/net/bpf.c ============================================================================== --- head/sys/net/bpf.c Wed Aug 16 18:55:39 2017 (r322589) +++ head/sys/net/bpf.c Wed Aug 16 19:40:07 2017 (r322590) @@ -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; } /*