Commit 0318fb80 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()

mainline inclusion
from mainline-v6.13-rc1
commit 46f2a11cb82b657fd15bab1c47821b635e03838b
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBJZ2Y
CVE: CVE-2024-56606

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=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>
Conflicts:
	net/packet/af_packet.c
[commit 89ed5b51 ("af_packet: Block execution of tasks waiting for
transmit to complete in AF_PACKET") not merged]
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
parent df354167
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -3276,18 +3276,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;
@@ -3322,7 +3322,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;