[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200220152020.13056-4-kuniyu@amazon.co.jp>
Date: Fri, 21 Feb 2020 00:20:20 +0900
From: Kuniyuki Iwashima <kuniyu@...zon.co.jp>
To: <davem@...emloft.net>, <kuznet@....inr.ac.ru>,
<yoshfuji@...ux-ipv6.org>, <edumazet@...gle.com>
CC: <kuniyu@...zon.co.jp>, <kuni1840@...il.com>,
<netdev@...r.kernel.org>, <osa-contribution-log@...zon.com>
Subject: [PATCH net-next 3/3] tcp: Prevent port hijacking when ports are exhausted.
If all of the sockets bound to the same port have SO_REUSEADDR and
SO_REUSEPORT enabled, any other user can hijack the port by exhausting all
ephemeral ports, binding sockets to (addr, 0) and calling listen().
In this case, we should be able to bind sockets to the same port only if
the user has the first listening socket on the port or if the existing
socket is in TIME_WAIT.
Signed-off-by: Kuniyuki Iwashima <kuniyu@...zon.co.jp>
---
net/ipv4/inet_connection_sock.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index cddeab240ea6..a6d9ee19baeb 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -131,7 +131,7 @@ static int inet_csk_bind_conflict(const struct sock *sk,
{
struct sock *sk2;
bool reuse = sk->sk_reuse;
- bool reuseport = !!sk->sk_reuseport && reuseport_ok;
+ bool reuseport = !!sk->sk_reuseport;
kuid_t uid = sock_i_uid((struct sock *)sk);
/*
@@ -148,10 +148,16 @@ static int inet_csk_bind_conflict(const struct sock *sk,
sk->sk_bound_dev_if == sk2->sk_bound_dev_if)) {
if (reuse && sk2->sk_reuse &&
sk2->sk_state != TCP_LISTEN) {
- if (!relax &&
+ if ((!relax ||
+ (!reuseport_ok &&
+ reuseport && sk2->sk_reuseport &&
+ !rcu_access_pointer(sk->sk_reuseport_cb) &&
+ (sk2->sk_state != TCP_TIME_WAIT &&
+ !uid_eq(uid, sock_i_uid(sk2))))) &&
inet_rcv_saddr_equal(sk, sk2, true))
break;
- } else if (!reuseport || !sk2->sk_reuseport ||
+ } else if (!reuseport_ok ||
+ !reuseport || !sk2->sk_reuseport ||
rcu_access_pointer(sk->sk_reuseport_cb) ||
(sk2->sk_state != TCP_TIME_WAIT &&
!uid_eq(uid, sock_i_uid(sk2)))) {
--
2.17.2 (Apple Git-113)
Powered by blists - more mailing lists