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