NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/60491: arp creates state for invalid messages



> Date: Wed, 28 Oct 2026 15:59:31 +0100
> From: Manuel Bouyer <bouyer%antioche.eu.org@localhost>
> 
> On Wed, Oct 21, 2026 at 04:00:52PM +0200, Manuel Bouyer wrote:
> > [ 19315.4531276] --- interrupt ---
> > 
> > The change is:
> > -       KASSERT(op == ARPOP_REPLY || op == ARPOP_REQUEST);
> > +       KASSERTMSG(op == ARPOP_REPLY || op == ARPOP_REQUEST,
> > +           "op not REQUEST or REPLY: %d", op);
> > 
> > Looks like m_makewritable() may be at fault here.
> 
> [...]
> I didn't look closely enough at m_makewritable() to explain how we could end
> up in this situation.
> Anyway I don't think we can use mtod() on a mbuf whose len is 0, and it doens't
> looks like m_makewritable() garantees that the first mbuf will contain the
> whole arp header.

Yes, indeed it does not -- and it looks like you may have had some
experience with this class of bug before!

user:        dyoung <dyoung%NetBSD.org@localhost>
date:        Fri Jul 28 17:30:53 2006 +0000
files:       share/man/man9/mbuf.9
description:
Let there be no mistake, m_makewritable() does not guarantee that
the writable bytes [off, off+len) are consecutive.
...
+.Fn m_makewritable
+does
+.Em not
+guarantee that all
+.Fa len
+bytes at
+.Fa off 
+are consecutive.
...
user:        bouyer <bouyer%NetBSD.org@localhost>
date:        Sat May 27 13:35:20 2006 +0000
files:       sys/netinet/tcp_input.c
description:
Revert rev 1.241: calling m_makewritable() in tcp_input causes problems when
it has to change the mbuf chain. I experience hard hang on a Xen2 domU after
TCP connections have been closed, and a crash has been reported which may be
caused by this too.
...
-#if BYTE_ORDER == LITTLE_ENDIAN
-               if (__predict_false(m_makewritable(&m, toff,
-                   sizeof(struct tcphdr), M_DONTWAIT))) {
-                       m_freem(m);
-                       return;
-               }
-#endif
                ip = mtod(m, struct ip *);
...
user:        bouyer <bouyer%NetBSD.org@localhost>
date:        Thu May 25 21:49:19 2006 +0000
files:       sys/netinet/tcp_input.c
description:
If we're going to byteswap fields in the TCP header, make sure the mbuf
area is writable first.
...
+#if BYTE_ORDER == LITTLE_ENDIAN
+               if (__predict_false(m_makewritable(&m, toff,
+                   sizeof(struct tcphdr), M_DONTWAIT))) {
+                       m_freem(m);
+                       return;
+               }
+#endif
                ip = mtod(m, struct ip *);
...
user:        bouyer <bouyer%NetBSD.org@localhost>
date:        Thu May 25 21:33:12 2006 +0000
files:       sys/netinet/if_arp.c
description:
Make sure the mbuf is writable before trying to write to it.
...
+       if (__predict_false(m_makewritable(&m, 0, m->m_pkthdr.len, M_DONTWAIT)))
+               goto out;
        ah = mtod(m, struct arphdr *);
...

I have filed a new PR to track this class of bug separately:

PR kern/60985: m_makewritable woes
https://gnats.NetBSD.org/60985



Home | Main Index | Thread Index | Old Index