summaryrefslogtreecommitdiffstats
path: root/net/ipv6/mip6.c
diff options
context:
space:
mode:
authorArnaud Ebalard <arno@natisbad.org>2010-07-16 02:38:44 +0200
committerDavid S. Miller <davem@davemloft.net>2010-07-19 00:04:33 +0200
commitd9a9dc66eb8a8fd85c8546247e7e1d6023d0eb0f (patch)
treecedd329461bcfeaad782b574912dbe68dd28d00a /net/ipv6/mip6.c
parentibmveth: lost IRQ while closing/opening device leads to service loss (diff)
downloadlinux-d9a9dc66eb8a8fd85c8546247e7e1d6023d0eb0f.tar.xz
linux-d9a9dc66eb8a8fd85c8546247e7e1d6023d0eb0f.zip
IPv6: fix CoA check in RH2 input handler (mip6_rthdr_input())
The input handler for Type 2 Routing Header (mip6_rthdr_input()) checks if the CoA in the packet matches the CoA in the XFRM state. Current check is buggy: it compares the adddress in the Type 2 Routing Header, i.e. the HoA, against the expected CoA in the state. The comparison should be made against the address in the destination field of the IPv6 header. The bug remained unnoticed because the main (and possibly only current) user of the code (UMIP MIPv6 Daemon) initializes the XFRM state with the unspecified address, i.e. explicitly allows everything. Yoshifuji-san, can you ack that one? Signed-off-by: Arnaud Ebalard <arno@natisbad.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/mip6.c')
-rw-r--r--net/ipv6/mip6.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 2794b6002836..d6e9599d0705 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -347,11 +347,12 @@ static const struct xfrm_type mip6_destopt_type =
static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
{
+ struct ipv6hdr *iph = ipv6_hdr(skb);
struct rt2_hdr *rt2 = (struct rt2_hdr *)skb->data;
int err = rt2->rt_hdr.nexthdr;
spin_lock(&x->lock);
- if (!ipv6_addr_equal(&rt2->addr, (struct in6_addr *)x->coaddr) &&
+ if (!ipv6_addr_equal(&iph->daddr, (struct in6_addr *)x->coaddr) &&
!ipv6_addr_any((struct in6_addr *)x->coaddr))
err = -ENOENT;
spin_unlock(&x->lock);