git: 60b4ad4b6b56 - main - bpf: Zero pad bytes preceding BPF headers

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 20 Jun 2022 17:00:31 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=60b4ad4b6b561ac2d9129a3576a74db3607ad90c

commit 60b4ad4b6b561ac2d9129a3576a74db3607ad90c
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-06-20 16:03:37 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-06-20 16:48:13 +0000

    bpf: Zero pad bytes preceding BPF headers
    
    BPF headers are word-aligned when copied into the store buffer.  Ensure
    that pad bytes following the preceding packet are cleared.
    
    Reported by:    KMSAN
    MFC after:      1 week
    Sponsored by:   The FreeBSD Foundation
---
 sys/net/bpf.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index b229dd81b127..2a390c1e7d30 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -2536,6 +2536,7 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
     void (*cpfn)(struct bpf_d *, caddr_t, u_int, void *, u_int),
     struct bintime *bt)
 {
+	static char zeroes[BPF_ALIGNMENT];
 	struct bpf_xhdr hdr;
 #ifndef BURN_BRIDGES
 	struct bpf_hdr hdr_old;
@@ -2543,7 +2544,7 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
 	struct bpf_hdr32 hdr32_old;
 #endif
 #endif
-	int caplen, curlen, hdrlen, totlen;
+	int caplen, curlen, hdrlen, pad, totlen;
 	int do_wakeup = 0;
 	int do_timestamp;
 	int tstype;
@@ -2609,13 +2610,25 @@ catchpacket(struct bpf_d *d, u_char *pkt, u_int pktlen, u_int snaplen,
 		ROTATE_BUFFERS(d);
 		do_wakeup = 1;
 		curlen = 0;
-	} else if (d->bd_immediate || d->bd_state == BPF_TIMED_OUT)
-		/*
-		 * Immediate mode is set, or the read timeout has already
-		 * expired during a select call.  A packet arrived, so the
-		 * reader should be woken up.
-		 */
-		do_wakeup = 1;
+	} else {
+		if (d->bd_immediate || d->bd_state == BPF_TIMED_OUT) {
+			/*
+			 * Immediate mode is set, or the read timeout has
+			 * already expired during a select call.  A packet
+			 * arrived, so the reader should be woken up.
+			 */
+			do_wakeup = 1;
+		}
+		pad = curlen - d->bd_slen;
+		KASSERT(pad >= 0 && pad <= sizeof(zeroes),
+		    ("%s: invalid pad byte count %d", __func__, pad));
+		if (pad > 0) {
+			/* Zero pad bytes. */
+			bpf_append_bytes(d, d->bd_sbuf, d->bd_slen, zeroes,
+			    pad);
+		}
+	}
+
 	caplen = totlen - hdrlen;
 	tstype = d->bd_tstamp;
 	do_timestamp = tstype != BPF_T_NONE;