net: Return errno in sk->sk_prot->get_port().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Fri, 18 Nov 2022 18:25:06 +0000 (10:25 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:13 +0000 (13:32 +0100)
[ Upstream commit 7a7160edf1bfde25422262fb26851cef65f695d3 ]

We assume the correct errno is -EADDRINUSE when sk->sk_prot->get_port()
fails, so some ->get_port() functions return just 1 on failure and the
callers return -EADDRINUSE instead.

However, mptcp_get_port() can return -EINVAL.  Let's not ignore the error.

Note the only exception is inet_autobind(), all of whose callers return
-EAGAIN instead.

Fixes: cec37a6e41aa ("mptcp: Handle MP_CAPABLE options for outgoing connections")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/ipv4/af_inet.c
net/ipv4/inet_connection_sock.c
net/ipv4/ping.c
net/ipv4/udp.c
net/ipv6/af_inet6.c

index 0da6794..92d4237 100644 (file)
@@ -522,9 +522,9 @@ int __inet_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
        /* Make sure we are allowed to bind here. */
        if (snum || !(inet->bind_address_no_port ||
                      (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
-               if (sk->sk_prot->get_port(sk, snum)) {
+               err = sk->sk_prot->get_port(sk, snum);
+               if (err) {
                        inet->inet_saddr = inet->inet_rcv_saddr = 0;
-                       err = -EADDRINUSE;
                        goto out_release_sock;
                }
                if (!(flags & BIND_FROM_BPF)) {
index 4e84ed2..4a34bc7 100644 (file)
@@ -471,11 +471,11 @@ int inet_csk_get_port(struct sock *sk, unsigned short snum)
        bool reuse = sk->sk_reuse && sk->sk_state != TCP_LISTEN;
        bool found_port = false, check_bind_conflict = true;
        bool bhash_created = false, bhash2_created = false;
+       int ret = -EADDRINUSE, port = snum, l3mdev;
        struct inet_bind_hashbucket *head, *head2;
        struct inet_bind2_bucket *tb2 = NULL;
        struct inet_bind_bucket *tb = NULL;
        bool head2_lock_acquired = false;
-       int ret = 1, port = snum, l3mdev;
        struct net *net = sock_net(sk);
 
        l3mdev = inet_sk_bound_l3mdev(sk);
@@ -1186,7 +1186,7 @@ int inet_csk_listen_start(struct sock *sk)
 {
        struct inet_connection_sock *icsk = inet_csk(sk);
        struct inet_sock *inet = inet_sk(sk);
-       int err = -EADDRINUSE;
+       int err;
 
        reqsk_queue_alloc(&icsk->icsk_accept_queue);
 
@@ -1202,7 +1202,8 @@ int inet_csk_listen_start(struct sock *sk)
         * after validation is complete.
         */
        inet_sk_state_store(sk, TCP_LISTEN);
-       if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
+       err = sk->sk_prot->get_port(sk, inet->inet_num);
+       if (!err) {
                inet->inet_sport = htons(inet->inet_num);
 
                sk_dst_reset(sk);
index 04b4ec0..409ec2a 100644 (file)
@@ -143,7 +143,7 @@ next_port:
 
 fail:
        spin_unlock(&ping_table.lock);
-       return 1;
+       return -EADDRINUSE;
 }
 EXPORT_SYMBOL_GPL(ping_get_port);
 
index 83fdd2b..2eaf47e 100644 (file)
@@ -235,7 +235,7 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
        struct udp_table *udptable = sk->sk_prot->h.udp_table;
        struct udp_hslot *hslot, *hslot2;
        struct net *net = sock_net(sk);
-       int error = 1;
+       int error = -EADDRINUSE;
 
        if (!snum) {
                DECLARE_BITMAP(bitmap, PORTS_PER_CHAIN);
index 0241910..7b0cd54 100644 (file)
@@ -409,10 +409,10 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
        /* Make sure we are allowed to bind here. */
        if (snum || !(inet->bind_address_no_port ||
                      (flags & BIND_FORCE_ADDRESS_NO_PORT))) {
-               if (sk->sk_prot->get_port(sk, snum)) {
+               err = sk->sk_prot->get_port(sk, snum);
+               if (err) {
                        sk->sk_ipv6only = saved_ipv6only;
                        inet_reset_saddr(sk);
-                       err = -EADDRINUSE;
                        goto out;
                }
                if (!(flags & BIND_FROM_BPF)) {