tech-net archive

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

potential mbuf corruption



net/netinet/tcp-input.c

-------------------------------
int
syn_cache_respond(struct syn_cache *sc, struct mbuf *m)
{
#ifdef INET6
        struct rtentry *rt;
#endif
        struct route *ro;
        u_int8_t *optp;
        int optlen, error;
        u_int16_t tlen;
        struct ip *ip = NULL;
#ifdef INET6
        struct ip6_hdr *ip6 = NULL;
#endif
        struct tcpcb *tp = NULL;
        struct tcphdr *th;
        u_int hlen;
        struct socket *so;

        ro = &sc->sc_route;
        switch (sc->sc_src.sa.sa_family) {
        case AF_INET:
                hlen = sizeof(struct ip);
                break;
#ifdef INET6
        case AF_INET6:
                hlen = sizeof(struct ip6_hdr);
                break;
#endif
        default:
                if (m)
                        m_freem(m);
                return (EAFNOSUPPORT);
        }

        /* Compute the size of the TCP options. */
        optlen = 4 + (sc->sc_request_r_scale != 15 ? 4 : 0) +
            ((sc->sc_flags & SCF_SACK_PERMIT) ? (TCPOLEN_SACK_PERMITTED + 2) : 
0) +
#ifdef TCP_SIGNATURE
            ((sc->sc_flags & SCF_SIGNATURE) ? (TCPOLEN_SIGNATURE + 2) : 0) +
#endif
            ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0);

        tlen = hlen + sizeof(struct tcphdr) + optlen;

        /*
         * Create the IP+TCP header from scratch.
         */
        if (m)
                m_freem(m);
#ifdef DIAGNOSTIC
        if (max_linkhdr + tlen > MCLBYTES)
                return (ENOBUFS);
#endif
        MGETHDR(m, M_DONTWAIT, MT_DATA);
        if (m && tlen > MHLEN) {
                MCLGET(m, M_DONTWAIT);
                if ((m->m_flags & M_EXT) == 0) {
                        m_freem(m);
                        m = NULL;
                }
        }
        if (m == NULL)
                return (ENOBUFS);
        MCLAIM(m, &tcp_tx_mowner);

        /* Fixup the mbuf. */
        m->m_data += max_linkhdr;
        m->m_len = m->m_pkthdr.len = tlen;
--------------------------------

wrong check
        if (m && tlen > MHLEN) {
should be
        if (m && (tlen + max_linkhdr) > MHLEN) {


Home | Main Index | Thread Index | Old Index