• Kuniyuki Iwashima's avatar
    tcp: Forbid to bind more than one sockets haveing SO_REUSEADDR and SO_REUSEPORT per EUID. · 33575921
    Kuniyuki Iwashima authored
    If there is no TCP_LISTEN socket on a ephemeral port, we can bind multiple
    sockets having SO_REUSEADDR to the same port. Then if all sockets bound to
    the port have also SO_REUSEPORT enabled and have the same EUID, all of them
    can be listened. This is not safe.
    
    Let's say, an application has root privilege and binds sockets to an
    ephemeral port with both of SO_REUSEADDR and SO_REUSEPORT. When none of
    sockets is not listened yet, a malicious user can use sudo, exhaust
    ephemeral ports, and bind sockets to the same ephemeral port, so he or she
    can call listen and steal the port.
    
    To prevent this issue, we must not bind more than one sockets that have the
    same EUID and both of SO_REUSEADDR and SO_REUSEPORT.
    
    On the other hand, if the sockets have different EUIDs, the issue above does
    not occur. After sockets with different EUIDs are bound to the same port and
    one of them is listened, no more socket can be listened. This is because the
    condition below is evaluated true and listen() for the second socket fails.
    
    			} 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)))) {
    				if (inet_rcv_saddr_equal(sk, sk2, true))
    					break;
    			}
    
    Therefore, on the same port, we cannot do listen() for multiple sockets with
    different EUIDs and any other listen syscalls fail, so the problem does not
    happen. In this case, we can still call connect() for other sockets that
    cannot be listened, so we have to succeed to call bind() in order to fully
    utilize 4-tuples.
    
    Summarizing the above, we should be able to bind only one socket having
    SO_REUSEADDR and SO_REUSEPORT per EUID.
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.co.jp>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    33575921
inet_connection_sock.c 31.1 KB