From 8092705059fbbd545ec6afbc14183d5522956bb7 Mon Sep 17 00:00:00 2001 From: Daniel Hartmeier Date: Sun, 5 Dec 2004 12:15:43 +0000 Subject: [PATCH] IPv6 packets can contain headers (like options) before the TCP/UDP/ICMP6 header. pf finds the first TCP/UDP/ICMP6 header to filter by traversing the header chain. In the case where headers are skipped, the protocol checksum verification used the wrong length (included the skipped headers), leading to incorrectly mismatching checksums. Such IPv6 packets with headers were silently dropped. Discovered by: Bernhard Schmidt MFC after: 1 week --- sys/contrib/pf/net/pf.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c index d29be54ed8d..99958c7eb74 100644 --- a/sys/contrib/pf/net/pf.c +++ b/sys/contrib/pf/net/pf.c @@ -6334,7 +6334,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) goto done; } if (dir == PF_IN && pf_check_proto_cksum(m, off, - ntohs(h->ip6_plen), IPPROTO_TCP, AF_INET6)) { + ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), + IPPROTO_TCP, AF_INET6)) { action = PF_DROP; goto done; } @@ -6372,7 +6373,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) goto done; } if (dir == PF_IN && uh.uh_sum && pf_check_proto_cksum(m, - off, ntohs(h->ip6_plen), IPPROTO_UDP, AF_INET6)) { + off, ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), + IPPROTO_UDP, AF_INET6)) { action = PF_DROP; goto done; } @@ -6411,7 +6413,8 @@ pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0) goto done; } if (dir == PF_IN && pf_check_proto_cksum(m, off, - ntohs(h->ip6_plen), IPPROTO_ICMPV6, AF_INET6)) { + ntohs(h->ip6_plen) - (off - sizeof(struct ip6_hdr)), + IPPROTO_ICMPV6, AF_INET6)) { action = PF_DROP; goto done; }