tun(4)/tap(4) function tun_dev_write() is checking for the wrong size for
the mbuf packet header. We must check against MHLEN (the mbuf header data
storage size) and not MINCLSIZE (smallest amount of data of a cluster).

For the curious:
MGETHDR() calls m_gethdr() which uses mbpool to get the mbuf data
storage. mbpool is initialized at mbinit() which sets the members
allocation size to MSIZE.

- MSIZE is "256";
- MLEN is "(MSIZE - sizeof(struct m_hdr))"
- MHLEN is "(MLEN - sizeof(pkthdr))";
- MINCLSIZE is "MHLEN + MLEN + 1";

ok?

Index: sys/net/if_tun.c
===================================================================
RCS file: /home/obsdcvs/src/sys/net/if_tun.c,v
retrieving revision 1.169
diff -u -p -r1.169 if_tun.c
--- sys/net/if_tun.c    4 Sep 2016 15:46:39 -0000       1.169
+++ sys/net/if_tun.c    24 Oct 2016 07:43:03 -0000
@@ -895,7 +895,7 @@ tun_dev_write(struct tun_softc *tp, stru
        if (m == NULL)
                return (ENOBUFS);
        mlen = MHLEN;
-       if (uio->uio_resid >= MINCLSIZE) {
+       if (uio->uio_resid >= MHLEN) {
                MCLGET(m, M_DONTWAIT);
                if (!(m->m_flags & M_EXT)) {
                        m_free(m);
@@ -926,7 +926,7 @@ tun_dev_write(struct tun_softc *tp, stru
                                break;
                        }
                        mlen = MLEN;
-                       if (uio->uio_resid >= MINCLSIZE) {
+                       if (uio->uio_resid >= MHLEN) {
                                MCLGET(m, M_DONTWAIT);
                                if (!(m->m_flags & M_EXT)) {
                                        error = ENOBUFS;

Reply via email to