diff options
author | Ignat Korchagin <ignat@cloudflare.com> | 2024-10-14 16:38:00 +0100 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2024-10-15 18:43:07 -0700 |
commit | 46f2a11cb82b657fd15bab1c47821b635e03838b (patch) | |
tree | c672257cfcad494edf338ce282f75958e35d672d | |
parent | 397006ba5d918f9b74e734867e8fddbc36dc2282 (diff) | |
download | linux-46f2a11cb82b657fd15bab1c47821b635e03838b.tar.gz linux-46f2a11cb82b657fd15bab1c47821b635e03838b.tar.bz2 linux-46f2a11cb82b657fd15bab1c47821b635e03838b.zip |
af_packet: avoid erroring out after sock_init_data() in packet_create()
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: Eric Dumazet <edumazet@google.com>
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20241014153808.51894-2-ignat@cloudflare.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rw-r--r-- | net/packet/af_packet.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 2ff4b251842d..886c0dd47b66 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -3422,17 +3422,17 @@ 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; - err = packet_alloc_pending(po); - if (err) - goto out2; - packet_cached_dev_reset(po); sk->sk_destruct = packet_sock_destruct; @@ -3464,7 +3464,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, sock_prot_inuse_add(net, &packet_proto, 1); return 0; -out2: +out_sk_free: sk_free(sk); out: return err; |