tech-kern archive

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

Re: Fix for kern/44310 (write to /dev/bpf truncates size_t to int)



I have a small addition to the previous which got lost in my
notes. I think that (m->m_pkthdr.len > ifp->if_mtu) check after
the bpf_movein() call is redundant.

Alexander Nasonov wrote:
> Hi,
> I have a fix for kern/44310 at the end of my post but first some
> commentary:
> ...
> -     if (len < hlen || len - hlen > mtu)
> +     if (len - hlen > mtu)
>               return (EMSGSIZE);

From this point, (len - hlen) <= mtu.

>
> -     if ((unsigned)len > MCLBYTES - align)
> +     if (len + align > MCLBYTES)
>               return (EIO);
>  
>       m = m_gethdr(M_WAIT, MT_DATA);
>       m->m_pkthdr.rcvif = 0;
> -     m->m_pkthdr.len = len - hlen;
> -     if (len > MHLEN - align) {
> +     m->m_pkthdr.len = (int)(len - hlen);
> +     if (len + align > MHLEN) {

m->m_pkthdr.len is <= mtu now and nothing changes it in the rest
of the function (my note tells me to check whether m_clget(m)
further down the function can change m_pkthdr.len but it doesn't
seem to change anything in m_pkthdr at all).

BTW, m_clget is not documented. If it's obsolete, shall it be
replaced with MCLGET macro? My patch below has a fix for this
as well.

Alex

$ cvs diff -U7 sys/net/bpf.c
Index: sys/net/bpf.c
===================================================================
RCS file: /cvsroot/src/sys/net/bpf.c,v
retrieving revision 1.162
diff -u -U 7 -r1.162 bpf.c
--- sys/net/bpf.c       22 Jan 2011 19:12:58 -0000      1.162
+++ sys/net/bpf.c       23 Jan 2011 12:34:09 -0000
@@ -264,15 +264,15 @@
        if (len + align > MCLBYTES)
                return (EIO);

        m = m_gethdr(M_WAIT, MT_DATA);
        m->m_pkthdr.rcvif = 0;
        m->m_pkthdr.len = (int)(len - hlen);
        if (len + align > MHLEN) {
-               m_clget(m, M_WAIT);
+               MCLGET(m, M_WAIT);
                if ((m->m_flags & M_EXT) == 0) {
                        error = ENOBUFS;
                        goto bad;
                }
        }

        /* Insure the data is properly aligned */
@@ -647,20 +647,14 @@
        error = bpf_movein(uio, (int)d->bd_bif->bif_dlt, ifp->if_mtu, &m,
                (struct sockaddr *) &dst);
        if (error) {
                KERNEL_UNLOCK_ONE(NULL);
                return (error);
        }

-       if (m->m_pkthdr.len > ifp->if_mtu) {
-               KERNEL_UNLOCK_ONE(NULL);
-               m_freem(m);
-               return (EMSGSIZE);
-       }
-
        if (d->bd_hdrcmplt)
                dst.ss_family = pseudo_AF_HDRCMPLT;

        if (d->bd_feedback) {
                mc = m_dup(m, 0, M_COPYALL, M_NOWAIT);
                if (mc != NULL)
                        mc->m_pkthdr.rcvif = ifp;



Home | Main Index | Thread Index | Old Index