svn commit: r348303 - head/sys/net
Gleb Smirnoff
glebius at freebsd.org
Wed May 29 00:10:51 UTC 2019
Hi Andrey,
I made a different change to mitigate this panic: don't clear the pointer.
--- a/FreeBSD/sys/net/bpf.c
+++ b/FreeBSD/sys/net/bpf.c
@@ -857,7 +857,6 @@ bpf_detachd_locked(struct bpf_d *d, bool detached_ifp)
/* Save bd_writer value */
error = d->bd_writer;
ifp = bp->bif_ifp;
- d->bd_bif = NULL;
if (detached_ifp) {
/*
* Notify descriptor as it's detached, so that any
Since every bpf_d holds a reference on bpf_if until delayed free happens,
the the bpf_if is going to be valid.
This allows not to use epoch_wait and run fully async. The patch above is
a minimal patch: with NULL assignment removed, several more pieces of code
can be removed in bpf.c
Of course your patch also is going to work, but what do you think:
are there any landmines with fully async approach?
On Mon, May 27, 2019 at 12:41:41PM +0000, Andrey V. Elsukov wrote:
A> Author: ae
A> Date: Mon May 27 12:41:41 2019
A> New Revision: 348303
A> URL: https://svnweb.freebsd.org/changeset/base/348303
A>
A> Log:
A> Fix possible NULL pointer dereference.
A>
A> bpf_mtap() can invoke catchpacket() for already detached descriptor.
A> And this can lead to NULL pointer dereference, since bd_bif pointer
A> was reset to NULL in bpf_detachd_locked(). To avoid this, use
A> NET_EPOCH_WAIT() when descriptor is removed from interface's descriptors
A> list. After the wait it is safe to modify descriptor's content.
A>
A> Submitted by: kib
A> Reported by: slavash
A> MFC after: 1 week
A>
A> Modified:
A> head/sys/net/bpf.c
A>
A> Modified: head/sys/net/bpf.c
A> ==============================================================================
A> --- head/sys/net/bpf.c Mon May 27 06:37:23 2019 (r348302)
A> +++ head/sys/net/bpf.c Mon May 27 12:41:41 2019 (r348303)
A> @@ -850,10 +850,15 @@ bpf_detachd_locked(struct bpf_d *d, bool detached_ifp)
A> /* Check if descriptor is attached */
A> if ((bp = d->bd_bif) == NULL)
A> return;
A> + /*
A> + * Remove d from the interface's descriptor list.
A> + * And wait until bpf_[m]tap*() will finish their possible work
A> + * with descriptor.
A> + */
A> + CK_LIST_REMOVE(d, bd_next);
A> + NET_EPOCH_WAIT();
A>
A> BPFD_LOCK(d);
A> - /* Remove d from the interface's descriptor list. */
A> - CK_LIST_REMOVE(d, bd_next);
A> /* Save bd_writer value */
A> error = d->bd_writer;
A> ifp = bp->bif_ifp;
A>
--
Gleb Smirnoff
More information about the svn-src-all
mailing list