Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b55b76b2 authored by Duan Jiong's avatar Duan Jiong Committed by David S. Miller
Browse files

ipv6:introduce function to find route for redirect



RFC 4861 says that the IP source address of the Redirect is the
same as the current first-hop router for the specified ICMP
Destination Address, so the gateway should be taken into
consideration when we find the route for redirect.

There was once a check in commit
a6279458 ("NDISC: Search over
all possible rules on receipt of redirect.") and the check
went away in commit b94f1c09
("ipv6: Use icmpv6_notify() to propagate redirect, instead of
rt6_redirect()").

The bug is only "exploitable" on layer-2 because the source
address of the redirect is checked to be a valid link-local
address but it makes spoofing a lot easier in the same L2
domain nonetheless.

Thanks very much for Hannes's help.

Signed-off-by: default avatarDuan Jiong <duanj.fnst@cn.fujitsu.com>
Acked-by: default avatarHannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 60cad4e6
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -628,7 +628,7 @@ static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
		return;

	if (type == NDISC_REDIRECT)
		ip6_redirect(skb, net, 0, 0);
		ip6_redirect(skb, net, skb->dev->ifindex, 0);
	else
		ip6_update_pmtu(skb, net, info, 0, 0);
	xfrm_state_put(x);
+1 −1
Original line number Diff line number Diff line
@@ -447,7 +447,7 @@ static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
		return;

	if (type == NDISC_REDIRECT)
		ip6_redirect(skb, net, 0, 0);
		ip6_redirect(skb, net, skb->dev->ifindex, 0);
	else
		ip6_update_pmtu(skb, net, info, 0, 0);
	xfrm_state_put(x);
+1 −1
Original line number Diff line number Diff line
@@ -92,7 +92,7 @@ static void icmpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
	if (type == ICMPV6_PKT_TOOBIG)
		ip6_update_pmtu(skb, net, info, 0, 0);
	else if (type == NDISC_REDIRECT)
		ip6_redirect(skb, net, 0, 0);
		ip6_redirect(skb, net, skb->dev->ifindex, 0);

	if (!(type & ICMPV6_INFOMSG_MASK))
		if (icmp6->icmp6_type == ICMPV6_ECHO_REQUEST)
+1 −1
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
		return;

	if (type == NDISC_REDIRECT)
		ip6_redirect(skb, net, 0, 0);
		ip6_redirect(skb, net, skb->dev->ifindex, 0);
	else
		ip6_update_pmtu(skb, net, info, 0, 0);
	xfrm_state_put(x);
+2 −1
Original line number Diff line number Diff line
@@ -1367,7 +1367,8 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
		return;

	if (!ndopts.nd_opts_rh) {
		ip6_redirect_no_header(skb, dev_net(skb->dev), 0, 0);
		ip6_redirect_no_header(skb, dev_net(skb->dev),
					skb->dev->ifindex, 0);
		return;
	}

Loading