On Mon, Oct 28, 2024 at 09:55:53PM +0000, Stuart Henderson wrote:
> On 2024/10/29 00:11, Vitaliy Makkoveev wrote:
> > > - Set up vio(4) interfaces with -tcplro and enable wg(4) interfaces as
> > >  usual (In my case, I'm routing IPv4 and IPv6 traffic through wg(4)
> > >  tunnel).
> > 
> > So, problem lays in vio(4).
> 
> Or perhaps that is a trigger but the problem is elsewhere.
> 
> bentley@ saw similar wg(4) problems on a machine with just em(4):
> 
> em0 at pci0 dev 31 function 6 "Intel I219-V" rev 0x21: msi, address 
> 94:c6:91:a3:6d:8a
> 
> Now, if I looked at the right files, only ix(4) vm(4) vio(4) have LRO -
> em(4) does not.
> 
> We do support TSO on some em(4). Though, while I am not certain, I don't
> think we do on I219-V... Anthony, do you still have that machine available?
> Can you do an "ifconfig em hwfeatures" please so we can be sure?
> 
> My best guess from the information I have (I don't think it's possible
> to map from a dmesg attach line to a mac_type without more information -
> the pci id isn't printed) is that it's an em_pch_spt which doesn't do
> TSO...
> 

People should try the following diff. It cleans up some of the mbuf
handling and a possible buffer overflow in wg_encap that could be the
cause of the pool corruption.

-- 
:wq Claudio

Index: net/if_wg.c
===================================================================
RCS file: /cvs/src/sys/net/if_wg.c,v
diff -u -p -r1.38 if_wg.c
--- net/if_wg.c 9 Apr 2024 12:53:08 -0000       1.38
+++ net/if_wg.c 29 Oct 2024 15:46:02 -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

Reply via email to