diff options
author | YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> | 2013-02-07 05:18:22 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-02-07 12:40:27 -0500 |
commit | edb27228db22654a59711135a5f7a20fb49a1016 (patch) | |
tree | c541fc4f604ba4b75b9de21ac0ea2af5bcb8e9b9 /net | |
parent | d4c38fa87d2b05be5daafb6a92b6ad15b66da8cb (diff) |
netfilter: ip6t_NPT: Ensure to check lower part of prefixes are zero
RFC 6296 points that address bits that are not part of the prefix
has to be zeroed.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/netfilter/ip6t_NPT.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/net/ipv6/netfilter/ip6t_NPT.c b/net/ipv6/netfilter/ip6t_NPT.c index 87b759c11da5..83acc1405a18 100644 --- a/net/ipv6/netfilter/ip6t_NPT.c +++ b/net/ipv6/netfilter/ip6t_NPT.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
10 | #include <linux/skbuff.h> | 10 | #include <linux/skbuff.h> |
11 | #include <linux/ipv6.h> | 11 | #include <linux/ipv6.h> |
12 | #include <net/ipv6.h> | ||
12 | #include <linux/netfilter.h> | 13 | #include <linux/netfilter.h> |
13 | #include <linux/netfilter_ipv6.h> | 14 | #include <linux/netfilter_ipv6.h> |
14 | #include <linux/netfilter_ipv6/ip6t_NPT.h> | 15 | #include <linux/netfilter_ipv6/ip6t_NPT.h> |
@@ -18,11 +19,20 @@ static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) | |||
18 | { | 19 | { |
19 | struct ip6t_npt_tginfo *npt = par->targinfo; | 20 | struct ip6t_npt_tginfo *npt = par->targinfo; |
20 | __wsum src_sum = 0, dst_sum = 0; | 21 | __wsum src_sum = 0, dst_sum = 0; |
22 | struct in6_addr pfx; | ||
21 | unsigned int i; | 23 | unsigned int i; |
22 | 24 | ||
23 | if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) | 25 | if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) |
24 | return -EINVAL; | 26 | return -EINVAL; |
25 | 27 | ||
28 | /* Ensure that LSB of prefix is zero */ | ||
29 | ipv6_addr_prefix(&pfx, &npt->src_pfx.in6, npt->src_pfx_len); | ||
30 | if (!ipv6_addr_equal(&pfx, &npt->src_pfx.in6)) | ||
31 | return -EINVAL; | ||
32 | ipv6_addr_prefix(&pfx, &npt->dst_pfx.in6, npt->dst_pfx_len); | ||
33 | if (!ipv6_addr_equal(&pfx, &npt->dst_pfx.in6)) | ||
34 | return -EINVAL; | ||
35 | |||
26 | for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { | 36 | for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { |
27 | src_sum = csum_add(src_sum, | 37 | src_sum = csum_add(src_sum, |
28 | (__force __wsum)npt->src_pfx.in6.s6_addr16[i]); | 38 | (__force __wsum)npt->src_pfx.in6.s6_addr16[i]); |