summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2010-10-14 18:31:40 +0000
committeryongari <yongari@FreeBSD.org>2010-10-14 18:31:40 +0000
commit92023f4cc9e471aa4ad6bf4362c248d8f173e46a (patch)
treea0e4e25c77486cf23be8641eed71e4b366b6078f /sys/dev
parenta4ebafd9602a429881d9def23f17e029dcc762ce (diff)
downloadFreeBSD-src-92023f4cc9e471aa4ad6bf4362c248d8f173e46a.zip
FreeBSD-src-92023f4cc9e471aa4ad6bf4362c248d8f173e46a.tar.gz
Make sure to not use stale ip/tcp header pointers. The ip/tcp
header parser uses m_pullup(9) to get access to mbuf chain. m_pullup(9) can allocate new mbuf chain and free old one if the space left in the mbuf chain is not enough to hold requested contiguous bytes. Previously drivers can use stale ip/tcp header pointer if m_pullup(9) returned new mbuf chain. Reported by: Andrew Boyer (aboyer <> averesystems dot com) MFC after: 10 days
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/age/if_age.c1
-rw-r--r--sys/dev/alc/if_alc.c2
-rw-r--r--sys/dev/ale/if_ale.c1
-rw-r--r--sys/dev/bce/if_bce.c2
-rw-r--r--sys/dev/bge/if_bge.c2
-rw-r--r--sys/dev/fxp/if_fxp.c2
-rw-r--r--sys/dev/jme/if_jme.c3
-rw-r--r--sys/dev/sge/if_sge.c2
8 files changed, 14 insertions, 1 deletions
diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c
index 99c3c43..cd593ff 100644
--- a/sys/dev/age/if_age.c
+++ b/sys/dev/age/if_age.c
@@ -1565,6 +1565,7 @@ age_encap(struct age_softc *sc, struct mbuf **m_head)
*m_head = NULL;
return (ENOBUFS);
}
+ ip = (struct ip *)(mtod(m, char *) + ip_off);
tcp = (struct tcphdr *)(mtod(m, char *) + poff);
/*
* L1 requires IP/TCP header size and offset as
diff --git a/sys/dev/alc/if_alc.c b/sys/dev/alc/if_alc.c
index 10061f3..1550571 100644
--- a/sys/dev/alc/if_alc.c
+++ b/sys/dev/alc/if_alc.c
@@ -2104,6 +2104,8 @@ alc_encap(struct alc_softc *sc, struct mbuf **m_head)
* Reset IP checksum and recompute TCP pseudo
* checksum as NDIS specification said.
*/
+ ip = (struct ip *)(mtod(m, char *) + ip_off);
+ tcp = (struct tcphdr *)(mtod(m, char *) + poff);
ip->ip_sum = 0;
tcp->th_sum = in_pseudo(ip->ip_src.s_addr,
ip->ip_dst.s_addr, htons(IPPROTO_TCP));
diff --git a/sys/dev/ale/if_ale.c b/sys/dev/ale/if_ale.c
index ea6b53b..eea2175 100644
--- a/sys/dev/ale/if_ale.c
+++ b/sys/dev/ale/if_ale.c
@@ -1677,6 +1677,7 @@ ale_encap(struct ale_softc *sc, struct mbuf **m_head)
*m_head = NULL;
return (ENOBUFS);
}
+ ip = (struct ip *)(mtod(m, char *) + ip_off);
tcp = (struct tcphdr *)(mtod(m, char *) + poff);
m = m_pullup(m, poff + (tcp->th_off << 2));
if (m == NULL) {
diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c
index 5cc8157..9d098cc 100644
--- a/sys/dev/bce/if_bce.c
+++ b/sys/dev/bce/if_bce.c
@@ -6736,6 +6736,7 @@ bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
}
/* Get the TCP header length in bytes (min 20) */
+ ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
tcp_hlen = (th->th_off << 2);
@@ -6748,6 +6749,7 @@ bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
}
/* IP header length and checksum will be calc'd by hardware */
+ ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
ip_len = ip->ip_len;
ip->ip_len = 0;
ip->ip_sum = 0;
diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c
index e6c0e0e..5381e3b 100644
--- a/sys/dev/bge/if_bge.c
+++ b/sys/dev/bge/if_bge.c
@@ -4097,9 +4097,11 @@ bge_setup_tso(struct bge_softc *sc, struct mbuf *m, uint16_t *mss)
* checksum. These checksum computed by upper stack should be 0.
*/
*mss = m->m_pkthdr.tso_segsz;
+ ip = (struct ip *)(mtod(m, char *) + sizeof(struct ether_header));
ip->ip_sum = 0;
ip->ip_len = htons(*mss + (ip->ip_hl << 2) + (tcp->th_off << 2));
/* Clear pseudo checksum computed by TCP stack. */
+ tcp = (struct tcphdr *)(mtod(m, char *) + poff);
tcp->th_sum = 0;
/*
* Broadcom controllers uses different descriptor format for
diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c
index 079ecc1..6904d9a 100644
--- a/sys/dev/fxp/if_fxp.c
+++ b/sys/dev/fxp/if_fxp.c
@@ -1454,6 +1454,8 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head)
* Since 82550/82551 doesn't modify IP length and pseudo
* checksum in the first frame driver should compute it.
*/
+ ip = (struct ip *)(mtod(m, char *) + ip_off);
+ tcp = (struct tcphdr *)(mtod(m, char *) + poff);
ip->ip_sum = 0;
ip->ip_len = htons(m->m_pkthdr.tso_segsz + (ip->ip_hl << 2) +
(tcp->th_off << 2));
diff --git a/sys/dev/jme/if_jme.c b/sys/dev/jme/if_jme.c
index 4bfffa3..12cc06b 100644
--- a/sys/dev/jme/if_jme.c
+++ b/sys/dev/jme/if_jme.c
@@ -1657,11 +1657,12 @@ jme_encap(struct jme_softc *sc, struct mbuf **m_head)
*m_head = NULL;
return (ENOBUFS);
}
- tcp = (struct tcphdr *)(mtod(m, char *) + poff);
/*
* Reset IP checksum and recompute TCP pseudo
* checksum that NDIS specification requires.
*/
+ ip = (struct ip *)(mtod(m, char *) + ip_off);
+ tcp = (struct tcphdr *)(mtod(m, char *) + poff);
ip->ip_sum = 0;
if (poff + (tcp->th_off << 2) == m->m_pkthdr.len) {
tcp->th_sum = in_pseudo(ip->ip_src.s_addr,
diff --git a/sys/dev/sge/if_sge.c b/sys/dev/sge/if_sge.c
index e294edd..e727d05 100644
--- a/sys/dev/sge/if_sge.c
+++ b/sys/dev/sge/if_sge.c
@@ -1457,7 +1457,9 @@ sge_encap(struct sge_softc *sc, struct mbuf **m_head)
* Reset IP checksum and recompute TCP pseudo
* checksum that NDIS specification requires.
*/
+ ip = (struct ip *)(mtod(m, char *) + ip_off);
ip->ip_sum = 0;
+ tcp = (struct tcphdr *)(mtod(m, char *) + poff);
tcp->th_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
htons(IPPROTO_TCP));
*m_head = m;
OpenPOWER on IntegriCloud