Commit afe628c5 authored by Ignat Korchagin's avatar Ignat Korchagin Committed by Zhang Changzhong
Browse files

af_packet: avoid erroring out after sock_init_data() in packet_create()

stable inclusion
from stable-v5.10.231
commit 1dc1e1db927056cb323296e2294a855cd003dfe7
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBEANY
CVE: CVE-2024-56606

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1dc1e1db927056cb323296e2294a855cd003dfe7



--------------------------------

[ Upstream commit 46f2a11cb82b657fd15bab1c47821b635e03838b ]

After sock_init_data() the allocated sk object is attached to the provided
sock object. On error, packet_create() frees the sk object leaving the
dangling pointer in the sock object on return. Some other code may try
to use this pointer and cause use-after-free.

Suggested-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarIgnat Korchagin <ignat@cloudflare.com>
Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20241014153808.51894-2-ignat@cloudflare.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parent ed8467e7
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -3321,18 +3321,18 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
	if (sock->type == SOCK_PACKET)
		sock->ops = &packet_ops_spkt;

	po = pkt_sk(sk);
	err = packet_alloc_pending(po);
	if (err)
		goto out_sk_free;

	sock_init_data(sock, sk);

	po = pkt_sk(sk);
	init_completion(&po->skb_completion);
	sk->sk_family = PF_PACKET;
	po->num = proto;
	po->xmit = dev_queue_xmit;

	err = packet_alloc_pending(po);
	if (err)
		goto out2;

	packet_cached_dev_reset(po);

	sk->sk_destruct = packet_sock_destruct;
@@ -3367,7 +3367,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
	preempt_enable();

	return 0;
out2:
out_sk_free:
	sk_free(sk);
out:
	return err;