]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
net: mctp: Prevent duplicate binds
authorMatt Johnston <matt@codeconstruct.com.au>
Thu, 10 Jul 2025 08:55:55 +0000 (16:55 +0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 15 Jul 2025 10:08:39 +0000 (12:08 +0200)
Disallow bind() calls that have the same arguments as existing bound
sockets.  Previously multiple sockets could bind() to the same
type/local address, with an arbitrary socket receiving matched messages.

This is only a partial fix, a future commit will define precedence order
for MCTP_ADDR_ANY versus specific EID bind(), which are allowed to exist
together.

Signed-off-by: Matt Johnston <matt@codeconstruct.com.au>
Link: https://patch.msgid.link/20250710-mctp-bind-v4-2-8ec2f6460c56@codeconstruct.com.au
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/mctp/af_mctp.c

index aef74308c18e3273008cb84aabe23ff700d0f842..0d073bc32ec17905ac0118d1aa653a46d829b150 100644 (file)
@@ -73,7 +73,6 @@ static int mctp_bind(struct socket *sock, struct sockaddr *addr, int addrlen)
 
        lock_sock(sk);
 
-       /* TODO: allow rebind */
        if (sk_hashed(sk)) {
                rc = -EADDRINUSE;
                goto out_release;
@@ -611,15 +610,36 @@ static void mctp_sk_close(struct sock *sk, long timeout)
 static int mctp_sk_hash(struct sock *sk)
 {
        struct net *net = sock_net(sk);
+       struct sock *existing;
+       struct mctp_sock *msk;
+       int rc;
+
+       msk = container_of(sk, struct mctp_sock, sk);
 
        /* Bind lookup runs under RCU, remain live during that. */
        sock_set_flag(sk, SOCK_RCU_FREE);
 
        mutex_lock(&net->mctp.bind_lock);
+
+       /* Prevent duplicate binds. */
+       sk_for_each(existing, &net->mctp.binds) {
+               struct mctp_sock *mex =
+                       container_of(existing, struct mctp_sock, sk);
+
+               if (mex->bind_type == msk->bind_type &&
+                   mex->bind_addr == msk->bind_addr &&
+                   mex->bind_net == msk->bind_net) {
+                       rc = -EADDRINUSE;
+                       goto out;
+               }
+       }
+
        sk_add_node_rcu(sk, &net->mctp.binds);
-       mutex_unlock(&net->mctp.bind_lock);
+       rc = 0;
 
-       return 0;
+out:
+       mutex_unlock(&net->mctp.bind_lock);
+       return rc;
 }
 
 static void mctp_sk_unhash(struct sock *sk)