aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-10-26 13:57:27 +0000
committerMark Johnston <markj@FreeBSD.org>2021-10-26 14:00:39 +0000
commit426682b05a4cf700c20d503516bfa07c043fecf8 (patch)
tree8c88974402b7b56e9a6e16f7726d22b6f7170b7e
parentc0cf36bc0210c4d74f626b944b4c7036cb01df5d (diff)
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
-rw-r--r--lib/libc/sys/kqueue.24
-rw-r--r--sys/net/bpf.c15
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