add ip6_tables fixes
svn path=/dists/trunk/linux-2.6/; revision=7652
This commit is contained in:
parent
87aff8ee57
commit
8061cb107f
|
@ -26,8 +26,9 @@ linux-2.6 (2.6.18-4) UNRELEASED; urgency=low
|
|||
* Bump build-dependency on kernel-package to 10.063.
|
||||
* [sparc64] Add davem fix memory corruption in pci_4u_free_consistent().
|
||||
* [sparc64] Add davem fix central/FHC bus handling on Ex000 systems.
|
||||
* [ip6_tables] Add patches for protocol and extension header bypass bug.
|
||||
|
||||
-- maximilian attems <maks@sternwelten.at> Thu, 26 Oct 2006 21:58:59 +0200
|
||||
-- maximilian attems <maks@sternwelten.at> Thu, 26 Oct 2006 22:20:34 +0200
|
||||
|
||||
linux-2.6 (2.6.18-3) unstable; urgency=low
|
||||
|
||||
|
|
|
@ -0,0 +1,174 @@
|
|||
From git-commits-head-owner@vger.kernel.org Wed Oct 25 14:13:09 2006
|
||||
Date: Wed, 25 Oct 2006 05:59:05 GMT
|
||||
Message-Id: <200610250559.k9P5x5tk014073@hera.kernel.org>
|
||||
From: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
|
||||
To: git-commits-head@vger.kernel.org
|
||||
Subject: [NETFILTER]: Fix ip6_tables extension header bypass bug
|
||||
|
||||
commit 6d381634d213580d40d431e7664dfb45f641b884
|
||||
tree a8680dd059e9a4e115d17e54d4a8dcea4d196a3e
|
||||
parent 51d8b1a65291a6956b79374b6adbbadc2263bcf6
|
||||
author Patrick McHardy <kaber@trash.net> 1161731710 -0700
|
||||
committer David S. Miller <davem@davemloft.net> 1161731710 -0700
|
||||
|
||||
[NETFILTER]: Fix ip6_tables extension header bypass bug
|
||||
|
||||
As reported by Mark Dowd <Mark_Dowd@McAfee.com>, 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 <yasuyuki.kozakai@toshiba.co.jp>.
|
||||
Fixed reject in ip6t_hbh.c for stable. -maks
|
||||
|
||||
Signed-off-by: Patrick McHardy <kaber@trash.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: maximilian attems <maks@sternwelten.at>
|
||||
|
||||
net/ipv6/netfilter/ip6_tables.c | 11 +++++++----
|
||||
net/ipv6/netfilter/ip6t_ah.c | 7 ++++++-
|
||||
net/ipv6/netfilter/ip6t_frag.c | 7 ++++++-
|
||||
net/ipv6/netfilter/ip6t_hbh.c | 7 ++++++-
|
||||
net/ipv6/netfilter/ip6t_rt.c | 7 ++++++-
|
||||
5 files changed, 31 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
|
||||
index f0328c7..53bf977 100644
|
||||
--- a/net/ipv6/netfilter/ip6_tables.c
|
||||
+++ b/net/ipv6/netfilter/ip6_tables.c
|
||||
@@ -1440,6 +1440,9 @@ static void __exit ip6_tables_fini(void)
|
||||
* If target header is found, its offset is set in *offset and return protocol
|
||||
* number. Otherwise, return -1.
|
||||
*
|
||||
+ * If the first fragment doesn't contain the final protocol header or
|
||||
+ * NEXTHDR_NONE it is considered invalid.
|
||||
+ *
|
||||
* Note that non-1st fragment is special case that "the protocol number
|
||||
* of last header" is "next header" field in Fragment header. In this case,
|
||||
* *offset is meaningless and fragment offset is stored in *fragoff if fragoff
|
||||
@@ -1463,12 +1466,12 @@ int ipv6_find_hdr(const struct sk_buff *
|
||||
if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) {
|
||||
if (target < 0)
|
||||
break;
|
||||
- return -1;
|
||||
+ return -ENOENT;
|
||||
}
|
||||
|
||||
hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
|
||||
if (hp == NULL)
|
||||
- return -1;
|
||||
+ return -EBADMSG;
|
||||
if (nexthdr == NEXTHDR_FRAGMENT) {
|
||||
unsigned short _frag_off, *fp;
|
||||
fp = skb_header_pointer(skb,
|
||||
@@ -1477,7 +1480,7 @@ int ipv6_find_hdr(const struct sk_buff *
|
||||
sizeof(_frag_off),
|
||||
&_frag_off);
|
||||
if (fp == NULL)
|
||||
- return -1;
|
||||
+ return -EBADMSG;
|
||||
|
||||
_frag_off = ntohs(*fp) & ~0x7;
|
||||
if (_frag_off) {
|
||||
@@ -1488,7 +1491,7 @@ int ipv6_find_hdr(const struct sk_buff *
|
||||
*fragoff = _frag_off;
|
||||
return hp->nexthdr;
|
||||
}
|
||||
- return -1;
|
||||
+ return -ENOENT;
|
||||
}
|
||||
hdrlen = 8;
|
||||
} else if (nexthdr == NEXTHDR_AUTH)
|
||||
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
|
||||
index ec1b160..4648664 100644
|
||||
--- a/net/ipv6/netfilter/ip6t_ah.c
|
||||
+++ b/net/ipv6/netfilter/ip6t_ah.c
|
||||
@@ -54,9 +54,14 @@ match(const struct sk_buff *skb,
|
||||
const struct ip6t_ah *ahinfo = matchinfo;
|
||||
unsigned int ptr;
|
||||
unsigned int hdrlen = 0;
|
||||
+ int err;
|
||||
|
||||
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0)
|
||||
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
|
||||
+ if (err < 0) {
|
||||
+ if (err != -ENOENT)
|
||||
+ *hotdrop = 1;
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
|
||||
if (ah == NULL) {
|
||||
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
|
||||
index 78d9c8b..cd22eaa 100644
|
||||
--- a/net/ipv6/netfilter/ip6t_frag.c
|
||||
+++ b/net/ipv6/netfilter/ip6t_frag.c
|
||||
@@ -52,9 +52,14 @@ match(const struct sk_buff *skb,
|
||||
struct frag_hdr _frag, *fh;
|
||||
const struct ip6t_frag *fraginfo = matchinfo;
|
||||
unsigned int ptr;
|
||||
+ int err;
|
||||
|
||||
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0)
|
||||
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
|
||||
+ if (err < 0) {
|
||||
+ if (err != -ENOENT)
|
||||
+ *hotdrop = 1;
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
|
||||
if (fh == NULL) {
|
||||
--- a/net/ipv6/netfilter/ip6t_hbh.c.orig 2006-10-26 22:11:31.000000000 +0200
|
||||
+++ b/net/ipv6/netfilter/ip6t_hbh.c 2006-10-26 22:13:06.000000000 +0200
|
||||
@@ -72,11 +72,15 @@ match(const struct sk_buff *skb,
|
||||
unsigned int optlen;
|
||||
|
||||
#if HOPBYHOP
|
||||
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL) < 0)
|
||||
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_HOP, NULL);
|
||||
#else
|
||||
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL) < 0)
|
||||
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_DEST, NULL);
|
||||
#endif
|
||||
+ if (err < 0) {
|
||||
+ if (err != -ENOENT)
|
||||
+ *hotdrop = 1;
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
|
||||
if (oh == NULL) {
|
||||
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
|
||||
index bcb2e16..54d7d14 100644
|
||||
--- a/net/ipv6/netfilter/ip6t_rt.c
|
||||
+++ b/net/ipv6/netfilter/ip6t_rt.c
|
||||
@@ -58,9 +58,14 @@ match(const struct sk_buff *skb,
|
||||
unsigned int hdrlen = 0;
|
||||
unsigned int ret = 0;
|
||||
struct in6_addr *ap, _addr;
|
||||
+ int err;
|
||||
|
||||
- if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0)
|
||||
+ err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
|
||||
+ if (err < 0) {
|
||||
+ if (err != -ENOENT)
|
||||
+ *hotdrop = 1;
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
|
||||
if (rh == NULL) {
|
||||
-
|
||||
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
From git-commits-head-owner@vger.kernel.org Tue Jun 6 18:56:24 2006
|
||||
Message-Id: <200610250559.k9P5x4BG014065@hera.kernel.org>
|
||||
From: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
|
||||
To: git-commits-head@vger.kernel.org
|
||||
Subject: [NETFILTER]: Fix ip6_tables protocol bypass bug
|
||||
|
||||
commit 51d8b1a65291a6956b79374b6adbbadc2263bcf6
|
||||
tree d6b8cbd6628c11d1c3e9c8c8e9ca048acf723a71
|
||||
parent 2fab22f2d3290ff7c602fe62f22e825c48e97a06
|
||||
author Patrick McHardy <kaber@trash.net> 1161731644 -0700
|
||||
committer David S. Miller <davem@davemloft.net> 1161731644 -0700
|
||||
|
||||
[NETFILTER]: Fix ip6_tables protocol bypass bug
|
||||
|
||||
As reported by Mark Dowd <Mark_Dowd@McAfee.com>, ip6_tables is susceptible
|
||||
to a fragmentation attack causing false negatives on protocol matches.
|
||||
|
||||
When the protocol header doesn't follow the fragment header immediately,
|
||||
the fragment header contains the protocol number of the next extension
|
||||
header. When the extension header and the protocol header are sent in
|
||||
a second fragment a rule like "ip6tables .. -p udp -j DROP" 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.
|
||||
|
||||
With help from Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>.
|
||||
|
||||
Signed-off-by: Patrick McHardy <kaber@trash.net>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
|
||||
net/ipv6/netfilter/ip6_tables.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
|
||||
index 4ab368f..f0328c7 100644
|
||||
--- a/net/ipv6/netfilter/ip6_tables.c
|
||||
+++ b/net/ipv6/netfilter/ip6_tables.c
|
||||
@@ -111,7 +111,7 @@ ip6_packet_match(const struct sk_buff *s
|
||||
const char *outdev,
|
||||
const struct ip6t_ip6 *ip6info,
|
||||
unsigned int *protoff,
|
||||
- int *fragoff)
|
||||
+ int *fragoff, int *hotdrop)
|
||||
{
|
||||
size_t i;
|
||||
unsigned long ret;
|
||||
@@ -169,9 +169,11 @@ #define FWINV(bool,invflg) ((bool) ^ !!(
|
||||
unsigned short _frag_off;
|
||||
|
||||
protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off);
|
||||
- if (protohdr < 0)
|
||||
+ if (protohdr < 0) {
|
||||
+ if (_frag_off == 0)
|
||||
+ *hotdrop = 1;
|
||||
return 0;
|
||||
-
|
||||
+ }
|
||||
*fragoff = _frag_off;
|
||||
|
||||
dprintf("Packet protocol %hi ?= %s%hi.\n",
|
||||
@@ -290,7 +292,7 @@ ip6t_do_table(struct sk_buff **pskb,
|
||||
IP_NF_ASSERT(e);
|
||||
IP_NF_ASSERT(back);
|
||||
if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6,
|
||||
- &protoff, &offset)) {
|
||||
+ &protoff, &offset, &hotdrop)) {
|
||||
struct ip6t_entry_target *t;
|
||||
|
||||
if (IP6T_MATCH_ITERATE(e, do_match,
|
||||
-
|
||||
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
|
||||
the body of a message to majordomo@vger.kernel.org
|
||||
More majordomo info at http://vger.kernel.org/majordomo-info.html
|
||||
|
|
@ -9,3 +9,5 @@
|
|||
+ bugfix/net-r8169-hotplug_loop.patch
|
||||
+ bugfix/sparc/mem_corruption-pci_4u_free_consistent.patch
|
||||
+ bugfix/sparc/central_fhc_bus-Ex000.patch
|
||||
+ bugfix/net-ip6_tables_extension_header-bypass.patch
|
||||
+ bugfix/net-ip6_tables_protocol-bypass.patch
|
||||
|
|
Loading…
Reference in New Issue