From: Duncan Eastoe <deas...@vyatta.att-mail.com> If setsockopt(IP_MULTICAST_IF) or setsockopt(IPV6_MULTICAST_IF) is called on a socket which is not bound to a VRF then we should ensure that the output device chosen is also not bound to a VRF master.
This avoids inadvertently sending traffic out of the wrong interface. This can be particularly problematic for IP_MULTICAST_IF since the interface lookup can be performed by address as well as ifindex. If there are interfaces with the same address, one unbound and one bound to a VRF, then the interface bound to the VRF may be chosen when the sockopt is called on an unbound socket. Signed-off-by: Duncan Eastoe <deas...@vyatta.att-mail.com> Signed-off-by: Mike Manning <mmann...@vyatta.att-mail.com> --- net/ipv4/ip_sockglue.c | 3 +++ net/ipv6/ipv6_sockglue.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index c0fe5ad996f2..026971314c43 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c @@ -892,6 +892,9 @@ static int do_ip_setsockopt(struct sock *sk, int level, dev_put(dev); err = -EINVAL; + if (!sk->sk_bound_dev_if && midx) + break; + if (sk->sk_bound_dev_if && mreq.imr_ifindex != sk->sk_bound_dev_if && (!midx || midx != sk->sk_bound_dev_if)) diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index c0cac9cc3a28..7dfbc797b130 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -626,6 +626,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, rcu_read_unlock(); + if (!sk->sk_bound_dev_if && midx) + goto e_inval; + if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val && (!midx || midx != sk->sk_bound_dev_if)) -- 2.11.0