git: 426682b05a4c - main - bpf: Fix the write filter for detached descriptors

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 26 Oct 2021 14:01:02 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=426682b05a4cf700c20d503516bfa07c043fecf8

commit 426682b05a4cf700c20d503516bfa07c043fecf8
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-10-26 13:57:27 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-10-26 14:00:39 +0000

    bpf: Fix the write filter for detached descriptors
    
    A BPF descriptor only has an associated interface descriptor once it is
    attached to an interface, e.g., with BIOCSETIF.  Avoid dereferencing a
    NULL pointer in filt_bpfwrite() if the BPF descriptor is not attached.
    
    Reviewed by:    ae
    Reported by:    syzbot+ae45d5166afe15a5a21d@syzkaller.appspotmail.com
    Fixes:  ded77e0237a8 ("Allow the BPF to be select for write.")
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D32561
---
 lib/libc/sys/kqueue.2 |  4 ++--
 sys/net/bpf.c         | 15 ++++++++++++---
 2 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/lib/libc/sys/kqueue.2 b/lib/libc/sys/kqueue.2
index 68929e973dc0..afa1dc5dcb4a 100644
--- a/lib/libc/sys/kqueue.2
+++ b/lib/libc/sys/kqueue.2
@@ -390,8 +390,8 @@ For eventfds,
 will contain the maximum value that can be added to the counter
 without blocking.
 .Pp
-For BPF devices, the filter always indicates that it is possible to
-write and
+For BPF devices, when the descriptor is attached to an interface the filter
+always indicates that it is possible to write and
 .Va data
 will contain the MTU size of the underlying interface.
 .It Dv EVFILT_EMPTY
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index ce7aba5a9bcd..b229dd81b127 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -763,6 +763,10 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
 		CK_LIST_INSERT_HEAD(&bp->bif_dlist, d, bd_next);
 
 	reset_d(d);
+
+	/* Trigger EVFILT_WRITE events. */
+	bpf_wakeup(d);
+
 	BPFD_UNLOCK(d);
 	bpf_bpfd_cnt++;
 
@@ -2229,11 +2233,16 @@ static int
 filt_bpfwrite(struct knote *kn, long hint)
 {
 	struct bpf_d *d = (struct bpf_d *)kn->kn_hook;
-	BPFD_LOCK_ASSERT(d);
 
-	kn->kn_data = d->bd_bif->bif_ifp->if_mtu;
+	BPFD_LOCK_ASSERT(d);
 
-	return (1);
+	if (d->bd_bif == NULL) {
+		kn->kn_data = 0;
+		return (0);
+	} else {
+		kn->kn_data = d->bd_bif->bif_ifp->if_mtu;
+		return (1);
+	}
 }
 
 #define	BPF_TSTAMP_NONE		0