Commit 39545023 authored by Matt Johnston's avatar Matt Johnston Committed by Paolo Abeni
Browse files

net: mctp: Prevent duplicate binds



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: default avatarMatt Johnston <matt@codeconstruct.com.au>
Link: https://patch.msgid.link/20250710-mctp-bind-v4-2-8ec2f6460c56@codeconstruct.com.au


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 3558ab79
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -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)