From 6d381634d213580d40d431e7664dfb45f641b884 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 24 Oct 2006 16:15:10 -0700 Subject: [NETFILTER]: Fix ip6_tables extension header bypass bug As reported by Mark Dowd , ip6_tables is susceptible to a fragmentation attack causing false negatives on extension header matches. When extension headers occur in the non-first fragment after the fragment header (possibly with an incorrect nexthdr value in the fragment header) a rule looking for this extension header will never match. Drop fragments that are at offset 0 and don't contain the final protocol header regardless of the ruleset, since this should not happen normally. Since all extension headers are before the protocol header this makes sure an extension header is either not present or in the first fragment, where we can properly parse it. With help from Yasuyuki KOZAKAI . Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/netfilter/ip6t_hbh.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'net/ipv6/netfilter/ip6t_hbh.c') diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index d32a205e3af2..3f25babe0440 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c @@ -65,9 +65,14 @@ match(const struct sk_buff *skb, u8 _opttype, *tp = NULL; u8 _optlen, *lp = NULL; unsigned int optlen; + int err; - if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) + err = ipv6_find_hdr(skb, &ptr, match->data, NULL); + if (err < 0) { + if (err != -ENOENT) + *hotdrop = 1; return 0; + } oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); if (oh == NULL) { -- cgit v1.2.3