ipfw tcpopt_match and m_pullup()
Karim Fodil-Lemelin
kfl at xiplink.com
Wed Mar 23 18:51:40 UTC 2011
Hi,
This is something that came up at work. While the ipfw code make sure
the tcp header is contiguous in ipfw_chck by calling PULLUP_TO, the code
does not guarantee 'contiguousity' of the TCP option space.
This means that code that walks the option space in ipfw (namely
tcpopts_match) could be falling off the edge of the mbuf container and
lead to all sorts of problems. Following is a patch that fixed the
problem for us and hopefully this gets pushed in this form or another to
the freebsd tree for others to benefit.
Best regards,
Karim.
#svn diff
Index: ip_fw2.c
===================================================================
--- ip_fw2.c (revision 218930)
+++ ip_fw2.c (working copy)
@@ -949,6 +949,11 @@
case IPPROTO_TCP:
PULLUP_TO(hlen, ulp, struct tcphdr);
+ /* kfl: check 'contiguousity' of the
option space */
+ if (m->m_len < (hlen + (TCP(ulp)->th_off
<< 2))) {
+ if ((m = m_pullup(m,
hlen+(TCP(ulp)->th_off << 2))) == NULL)
+ goto pullup_failed;
+ }
dst_port = TCP(ulp)->th_dport;
src_port = TCP(ulp)->th_sport;
/* save flags for dynamic rules */
@@ -1117,6 +1122,11 @@
switch (proto) {
case IPPROTO_TCP:
PULLUP_TO(hlen, ulp, struct tcphdr);
+ /* kfl: check 'contiguousity' of the
option space */
+ if (m->m_len < (hlen + (TCP(ulp)->th_off
<< 2))) {
+ if ((m = m_pullup(m,
hlen+(TCP(ulp)->th_off << 2))) == NULL)
+ goto pullup_failed;
+ }
dst_port = TCP(ulp)->th_dport;
src_port = TCP(ulp)->th_sport;
/* save flags for dynamic rules */
More information about the freebsd-ipfw
mailing list