Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bdfc38a authored by Eric Dumazet's avatar Eric Dumazet Committed by Sasha Levin
Browse files

sock_diag: annotate data-races around sock_diag_handlers[family]



[ Upstream commit efd402537673f9951992aea4ef0f5ff51d858f4b ]

__sock_diag_cmd() and sock_diag_bind() read sock_diag_handlers[family]
without a lock held.

Use READ_ONCE()/WRITE_ONCE() annotations to avoid potential issues.

Fixes: 8ef874bf ("sock_diag: Move the sock_ code to net/core/")
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarGuillaume Nault <gnault@redhat.com>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 76ac9c14
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -188,7 +188,7 @@ int sock_diag_register(const struct sock_diag_handler *hndl)
	if (sock_diag_handlers[hndl->family])
		err = -EBUSY;
	else
		sock_diag_handlers[hndl->family] = hndl;
		WRITE_ONCE(sock_diag_handlers[hndl->family], hndl);
	mutex_unlock(&sock_diag_table_mutex);

	return err;
@@ -204,7 +204,7 @@ void sock_diag_unregister(const struct sock_diag_handler *hnld)

	mutex_lock(&sock_diag_table_mutex);
	BUG_ON(sock_diag_handlers[family] != hnld);
	sock_diag_handlers[family] = NULL;
	WRITE_ONCE(sock_diag_handlers[family], NULL);
	mutex_unlock(&sock_diag_table_mutex);
}
EXPORT_SYMBOL_GPL(sock_diag_unregister);
@@ -222,7 +222,7 @@ static int __sock_diag_cmd(struct sk_buff *skb, struct nlmsghdr *nlh)
		return -EINVAL;
	req->sdiag_family = array_index_nospec(req->sdiag_family, AF_MAX);

	if (sock_diag_handlers[req->sdiag_family] == NULL)
	if (READ_ONCE(sock_diag_handlers[req->sdiag_family]) == NULL)
		sock_load_diag_module(req->sdiag_family, 0);

	mutex_lock(&sock_diag_table_mutex);
@@ -281,12 +281,12 @@ static int sock_diag_bind(struct net *net, int group)
	switch (group) {
	case SKNLGRP_INET_TCP_DESTROY:
	case SKNLGRP_INET_UDP_DESTROY:
		if (!sock_diag_handlers[AF_INET])
		if (!READ_ONCE(sock_diag_handlers[AF_INET]))
			sock_load_diag_module(AF_INET, 0);
		break;
	case SKNLGRP_INET6_TCP_DESTROY:
	case SKNLGRP_INET6_UDP_DESTROY:
		if (!sock_diag_handlers[AF_INET6])
		if (!READ_ONCE(sock_diag_handlers[AF_INET6]))
			sock_load_diag_module(AF_INET6, 0);
		break;
	}