mirror of https://gitee.com/openkylin/linux.git
netfilter: xt_iprange: Incorrect xt_iprange boundary check for IPv6
iprange_ipv6_sub was substracting 2 unsigned ints and then casting the result to int to find out whether they are lt, eq or gt each other, this doesn't work if the full 32 bits of each part can be used in IPv6 addresses. Patch should remedy that without significant performance penalties. Also number of ntohl calls can be reduced this way (Jozsef Kadlecsik). Signed-off-by: Thomas Jacob <jacob@internet24.de> Signed-off-by: Patrick McHardy <kaber@trash.net>
This commit is contained in:
parent
c71caf4114
commit
08b5194b5d
|
@ -53,15 +53,13 @@ iprange_mt4(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
}
|
||||
|
||||
static inline int
|
||||
iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
|
||||
iprange_ipv6_lt(const struct in6_addr *a, const struct in6_addr *b)
|
||||
{
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
for (i = 0; i < 4; ++i) {
|
||||
r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]);
|
||||
if (r != 0)
|
||||
return r;
|
||||
if (a->s6_addr32[i] != b->s6_addr32[i])
|
||||
return ntohl(a->s6_addr32[i]) < ntohl(b->s6_addr32[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -75,15 +73,15 @@ iprange_mt6(const struct sk_buff *skb, struct xt_action_param *par)
|
|||
bool m;
|
||||
|
||||
if (info->flags & IPRANGE_SRC) {
|
||||
m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0;
|
||||
m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0;
|
||||
m = iprange_ipv6_lt(&iph->saddr, &info->src_min.in6);
|
||||
m |= iprange_ipv6_lt(&info->src_max.in6, &iph->saddr);
|
||||
m ^= !!(info->flags & IPRANGE_SRC_INV);
|
||||
if (m)
|
||||
return false;
|
||||
}
|
||||
if (info->flags & IPRANGE_DST) {
|
||||
m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0;
|
||||
m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0;
|
||||
m = iprange_ipv6_lt(&iph->daddr, &info->dst_min.in6);
|
||||
m |= iprange_ipv6_lt(&info->dst_max.in6, &iph->daddr);
|
||||
m ^= !!(info->flags & IPRANGE_DST_INV);
|
||||
if (m)
|
||||
return false;
|
||||
|
|
Loading…
Reference in New Issue