Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Mar 2011 14:34:53 -0400
From:      Karim Fodil-Lemelin <kfl@xiplink.com>
To:        freebsd-ipfw@freebsd.org
Subject:   ipfw tcpopt_match and m_pullup()
Message-ID:  <4D8A3D4D.5080606@xiplink.com>

next in thread | raw e-mail | index | archive | help
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 */




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4D8A3D4D.5080606>