]>
Commit | Line | Data |
---|---|---|
49b6d164 AD |
1 | From patchwork Mon Jun 18 19:30:37 2018 |
2 | Content-Type: text/plain; charset="utf-8" | |
3 | MIME-Version: 1.0 | |
4 | Content-Transfer-Encoding: 7bit | |
5 | Subject: [net] net/tcp: Fix socket lookups with SO_BINDTODEVICE | |
6 | X-Patchwork-Submitter: dsahern@kernel.org | |
7 | X-Patchwork-Id: 931179 | |
8 | X-Patchwork-Delegate: davem@davemloft.net | |
9 | Message-Id: <20180618193037.3365-1-dsahern@kernel.org> | |
10 | To: netdev@vger.kernel.org | |
11 | Cc: davem@davemloft.net, lberger@labn.net, | |
12 | renato@opensourcerouting.org, David Ahern <dsahern@gmail.com> | |
13 | Date: Mon, 18 Jun 2018 12:30:37 -0700 | |
14 | From: dsahern@kernel.org | |
15 | List-Id: <netdev.vger.kernel.org> | |
16 | ||
17 | From: David Ahern <dsahern@gmail.com> | |
18 | ||
19 | Similar to 69678bcd4d2d ("udp: fix SO_BINDTODEVICE"), TCP socket lookups | |
20 | need to fail if dev_match is not true. Currently, a packet to a given port | |
21 | can match a socket bound to device when it should not. In the VRF case, | |
22 | this causes the lookup to hit a VRF socket and not a global socket | |
23 | resulting in a response trying to go through the VRF when it should it. | |
24 | ||
25 | Fixes: 3fa6f616a7a4d ("net: ipv4: add second dif to inet socket lookups") | |
26 | Fixes: 4297a0ef08572 ("net: ipv6: add second dif to inet6 socket lookups") | |
27 | Reported-by: Lou Berger <lberger@labn.net> | |
28 | Diagnosed-by: Renato Westphal <renato@opensourcerouting.org> | |
29 | Tested-by: Renato Westphal <renato@opensourcerouting.org> | |
30 | Signed-off-by: David Ahern <dsahern@gmail.com> | |
31 | --- | |
32 | net/ipv4/inet_hashtables.c | 4 ++-- | |
33 | net/ipv6/inet6_hashtables.c | 4 ++-- | |
34 | 2 files changed, 4 insertions(+), 4 deletions(-) | |
35 | ||
36 | diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c | |
37 | index 31ff46daae97..3647167c8fa3 100644 | |
38 | --- a/net/ipv4/inet_hashtables.c | |
39 | +++ b/net/ipv4/inet_hashtables.c | |
40 | @@ -243,9 +243,9 @@ static inline int compute_score(struct sock *sk, struct net *net, | |
41 | bool dev_match = (sk->sk_bound_dev_if == dif || | |
42 | sk->sk_bound_dev_if == sdif); | |
43 | ||
44 | - if (exact_dif && !dev_match) | |
45 | + if (!dev_match) | |
46 | return -1; | |
47 | - if (sk->sk_bound_dev_if && dev_match) | |
48 | + if (sk->sk_bound_dev_if) | |
49 | score += 4; | |
50 | } | |
51 | if (sk->sk_incoming_cpu == raw_smp_processor_id()) | |
52 | diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c | |
53 | index 2febe26de6a1..595ad408dba0 100644 | |
54 | --- a/net/ipv6/inet6_hashtables.c | |
55 | +++ b/net/ipv6/inet6_hashtables.c | |
56 | @@ -113,9 +113,9 @@ static inline int compute_score(struct sock *sk, struct net *net, | |
57 | bool dev_match = (sk->sk_bound_dev_if == dif || | |
58 | sk->sk_bound_dev_if == sdif); | |
59 | ||
60 | - if (exact_dif && !dev_match) | |
61 | + if (!dev_match) | |
62 | return -1; | |
63 | - if (sk->sk_bound_dev_if && dev_match) | |
64 | + if (sk->sk_bound_dev_if) | |
65 | score++; | |
66 | } | |
67 | if (sk->sk_incoming_cpu == raw_smp_processor_id()) |