Date: Thu, 20 Apr 2017 09:05:53 +0000 (UTC) From: Kristof Provost <kp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r317186 - in head/sys: netinet6 netpfil/pf Message-ID: <201704200905.v3K95rRT097206@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kp Date: Thu Apr 20 09:05:53 2017 New Revision: 317186 URL: https://svnweb.freebsd.org/changeset/base/317186 Log: pf: Fix possible incorrect IPv6 fragmentation When forwarding pf tracks the size of the largest fragment in a fragmented packet, and refragments based on this size. It failed to ensure that this size was a multiple of 8 (as is required for all but the last fragment), so it could end up generating incorrect fragments. For example, if we received an 8 byte and 12 byte fragment pf would emit a first fragment with 12 bytes of payload and the final fragment would claim to be at offset 8 (not 12). We now assert that the fragment size is a multiple of 8 in ip6_fragment(), so other users won't make the same mistake. Reported by: Antonios Atlasis <aatlasis at secfu net> MFC after: 3 days Modified: head/sys/netinet6/ip6_output.c head/sys/netpfil/pf/pf_norm.c Modified: head/sys/netinet6/ip6_output.c ============================================================================== --- head/sys/netinet6/ip6_output.c Thu Apr 20 09:01:31 2017 (r317185) +++ head/sys/netinet6/ip6_output.c Thu Apr 20 09:05:53 2017 (r317186) @@ -226,6 +226,8 @@ ip6_fragment(struct ifnet *ifp, struct m int error; int tlen = m0->m_pkthdr.len; + KASSERT(( mtu % 8 == 0), ("Fragment length must be a multiple of 8")); + m = m0; ip6 = mtod(m, struct ip6_hdr *); mnext = &m->m_nextpkt; Modified: head/sys/netpfil/pf/pf_norm.c ============================================================================== --- head/sys/netpfil/pf/pf_norm.c Thu Apr 20 09:01:31 2017 (r317185) +++ head/sys/netpfil/pf/pf_norm.c Thu Apr 20 09:05:53 2017 (r317186) @@ -762,6 +762,10 @@ pf_refragment6(struct ifnet *ifp, struct hdr->ip6_nxt = IPPROTO_FRAGMENT; } + /* The MTU must be a multiple of 8 bytes, or we risk doing the + * fragmentation wrong. */ + maxlen = maxlen & ~7; + /* * Maxlen may be less than 8 if there was only a single * fragment. As it was fragmented before, add a fragment
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704200905.v3K95rRT097206>