untrusted comment: verify with openbsd-76-base.pub
RWTkuwn4mbq8ookopYlAsyjd/TeWJa9vwaalXjud7zJG9IHJnLtmArDex2ADPRv4q155qcTz2NOqVEN35mYYJV44Wk84l/KP7gE=

OpenBSD 7.6 errata 006, January 10, 2025:

Traffic sent over wg(4) could result in kernel crash.

Apply by doing:
    signify -Vep /etc/signify/openbsd-76-base.pub -x 006_wg.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/net/if_wg.c
===================================================================
RCS file: /cvs/src/sys/net/if_wg.c,v
diff -u -p -r1.38 if_wg.c
--- sys/net/if_wg.c	9 Apr 2024 12:53:08 -0000	1.38
+++ sys/net/if_wg.c	7 Jan 2025 09:23:09 -0000
@@ -860,11 +860,15 @@ wg_send_buf(struct wg_softc *sc, struct 
 {
 	struct mbuf	*m;
 	int		 ret = 0;
+	size_t		 mlen = len + max_hdr;
 
 retry:
 	m = m_gethdr(M_WAIT, MT_DATA);
-	m->m_len = 0;
-	m_copyback(m, 0, len, buf, M_WAIT);
+	if (mlen > MHLEN)
+		MCLGETL(m, M_WAIT, mlen);
+	m_align(m, len);
+	m->m_pkthdr.len = m->m_len = len;
+	memcpy(mtod(m, void *), buf, len);
 
 	/* As we're sending a handshake packet here, we want high priority */
 	m->m_pkthdr.pf.prio = IFQ_MAXPRIO;
@@ -1304,9 +1308,6 @@ wg_send_keepalive(void *_peer)
 		return;
 	}
 
-	m->m_len = 0;
-	m_calchdrlen(m);
-
 	t->t_peer = peer;
 	t->t_mbuf = NULL;
 	t->t_done = 0;
@@ -1508,9 +1509,10 @@ wg_encap(struct wg_softc *sc, struct mbu
 	t = wg_tag_get(m);
 	peer = t->t_peer;
 
-	plaintext_len = min(WG_PKT_WITH_PADDING(m->m_pkthdr.len), t->t_mtu);
+	plaintext_len = WG_PKT_WITH_PADDING(m->m_pkthdr.len);
 	padding_len = plaintext_len - m->m_pkthdr.len;
-	out_len = sizeof(struct wg_pkt_data) + plaintext_len + NOISE_AUTHTAG_LEN;
+	out_len = sizeof(struct wg_pkt_data) + plaintext_len +
+	    NOISE_AUTHTAG_LEN;
 
 	/*
 	 * For the time being we allocate a new packet with sufficient size to
@@ -1522,8 +1524,9 @@ wg_encap(struct wg_softc *sc, struct mbu
 	 * noise_remote_encrypt about mbufs, but we would need to sort out the
 	 * p_encap_queue situation first.
 	 */
-	if ((mc = m_clget(NULL, M_NOWAIT, out_len)) == NULL)
+	if ((mc = m_clget(NULL, M_NOWAIT, out_len + max_hdr)) == NULL)
 		goto error;
+	m_align(mc, out_len);
 
 	data = mtod(mc, struct wg_pkt_data *);
 	m_copydata(m, 0, m->m_pkthdr.len, data->buf);
@@ -1560,8 +1563,7 @@ wg_encap(struct wg_softc *sc, struct mbu
 
 	mc->m_pkthdr.ph_loopcnt = m->m_pkthdr.ph_loopcnt;
 	mc->m_flags &= ~(M_MCAST | M_BCAST);
-	mc->m_len = out_len;
-	m_calchdrlen(mc);
+	mc->m_pkthdr.len = mc->m_len = out_len;
 
 	/*
 	 * We would count ifc_opackets, ifc_obytes of m here, except if_snd
