diff options
author | Mark Johnston <markj@FreeBSD.org> | 2021-10-26 13:57:27 +0000 |
---|---|---|
committer | Mark Johnston <markj@FreeBSD.org> | 2021-10-26 14:00:39 +0000 |
commit | 426682b05a4cf700c20d503516bfa07c043fecf8 (patch) | |
tree | 8c88974402b7b56e9a6e16f7726d22b6f7170b7e | |
parent | c0cf36bc0210c4d74f626b944b4c7036cb01df5d (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.2 | 4 | ||||
-rw-r--r-- | 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 |