* [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions
@ 2024-10-07 21:34 Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails Ignat Korchagin
` (8 more replies)
0 siblings, 9 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:34 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
Some protocol family create() implementations have an error path after
allocating the sk object and calling sock_init_data(). sock_init_data()
attaches the allocated sk object to the sock object, provided by the
caller.
If the create() implementation errors out after calling sock_init_data(),
it releases the allocated sk object, but the caller ends up having a
dangling sk pointer in its sock object on return. Subsequent manipulations
on this sock object may try to access the sk pointer, because it is not
NULL thus creating a use-after-free scenario.
While the first patch in the series should be enough to handle this
scenario Eric Dumazet suggested that it would be a good idea to refactor
the code for the af_packet implementation to avoid the error path, which
leaves a dangling pointer, because it may be better for some tools like
kmemleak. I went a bit further and tried to actually fix all the
implementations, which could potentially leave a dangling sk pointer.
Changes in V2:
* reverted the change introduced in 6cd4a78d962b ("net: do not leave a
dangling sk pointer, when socket creation fails")
* added optional commits to all pf->create implementaions to clear the
sk pointer on error after sock_init_data()
Ignat Korchagin (8):
net: explicitly clear the sk pointer, when pf->create fails
af_packet: avoid erroring out after sock_init_data() in
packet_create()
Bluetooth: L2CAP: do not leave dangling sk pointer on error in
l2cap_sock_create()
Bluetooth: RFCOMM: avoid leaving dangling sk pointer in
rfcomm_sock_alloc()
net: af_can: do not leave a dangling sk pointer in can_create()
net: ieee802154: do not leave a dangling sk pointer in
ieee802154_create()
net: inet: do not leave a dangling sk pointer in inet_create()
inet6: do not leave a dangling sk pointer in inet6_create()
net/bluetooth/l2cap_sock.c | 1 +
net/bluetooth/rfcomm/sock.c | 10 +++++-----
net/can/af_can.c | 1 +
net/core/sock.c | 3 ---
net/ieee802154/socket.c | 12 +++++++-----
net/ipv4/af_inet.c | 22 ++++++++++------------
net/ipv6/af_inet6.c | 22 ++++++++++------------
net/packet/af_packet.c | 12 ++++++------
net/socket.c | 7 ++++++-
9 files changed, 46 insertions(+), 44 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
@ 2024-10-07 21:34 ` Ignat Korchagin
2024-10-07 21:47 ` Kuniyuki Iwashima
2024-10-08 0:20 ` Jakub Kicinski
2024-10-07 21:34 ` [PATCH v2 2/8] af_packet: avoid erroring out after sock_init_data() in packet_create() Ignat Korchagin
` (7 subsequent siblings)
8 siblings, 2 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:34 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin, stable
We have recently noticed the exact same KASAN splat as in commit
6cd4a78d962b ("net: do not leave a dangling sk pointer, when socket
creation fails"). The problem is that commit did not fully address the
problem, as some pf->create implementations do not use sk_common_release
in their error paths.
For example, we can use the same reproducer as in the above commit, but
changing ping to arping. arping uses AF_PACKET socket and if packet_create
fails, it will just sk_free the allocated sk object.
While we could chase all the pf->create implementations and make sure they
NULL the freed sk object on error from the socket, we can't guarantee
future protocols will not make the same mistake.
So it is easier to just explicitly NULL the sk pointer upon return from
pf->create in __sock_create. We do know that pf->create always releases the
allocated sk object on error, so if the pointer is not NULL, it is
definitely dangling.
Fixes: 6cd4a78d962b ("net: do not leave a dangling sk pointer, when socket creation fails")
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Cc: stable@vger.kernel.org
---
net/core/sock.c | 3 ---
net/socket.c | 7 ++++++-
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c
index 039be95c40cf..e6e04081949c 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3819,9 +3819,6 @@ void sk_common_release(struct sock *sk)
sk->sk_prot->unhash(sk);
- if (sk->sk_socket)
- sk->sk_socket->sk = NULL;
-
/*
* In this point socket cannot receive new packets, but it is possible
* that some packets are in flight because some CPU runs receiver and
diff --git a/net/socket.c b/net/socket.c
index 601ad74930ef..042451f01c65 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1574,8 +1574,13 @@ int __sock_create(struct net *net, int family, int type, int protocol,
rcu_read_unlock();
err = pf->create(net, sock, protocol, kern);
- if (err < 0)
+ if (err < 0) {
+ /* ->create should release the allocated sock->sk object on error
+ * but it may leave the dangling pointer
+ */
+ sock->sk = NULL;
goto out_module_put;
+ }
/*
* Now to bump the refcnt of the [loadable] module that owns this
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 2/8] af_packet: avoid erroring out after sock_init_data() in packet_create()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails Ignat Korchagin
@ 2024-10-07 21:34 ` Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 3/8] Bluetooth: L2CAP: do not leave dangling sk pointer on error in l2cap_sock_create() Ignat Korchagin
` (6 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:34 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
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>
---
net/packet/af_packet.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index a705ec214254..97774bd4b6cb 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -3421,17 +3421,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;
@@ -3463,7 +3463,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;
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 3/8] Bluetooth: L2CAP: do not leave dangling sk pointer on error in l2cap_sock_create()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 2/8] af_packet: avoid erroring out after sock_init_data() in packet_create() Ignat Korchagin
@ 2024-10-07 21:34 ` Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 4/8] Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc() Ignat Korchagin
` (5 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:34 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
bt_sock_alloc() allocates the sk object and attaches it to the provided
sock object. On error l2cap_sock_alloc() frees the sk object, but the
dangling pointer is still attached to the sock object, which may create
use-after-free in other code.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
---
net/bluetooth/l2cap_sock.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index ba437c6f6ee5..18e89e764f3b 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1886,6 +1886,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
chan = l2cap_chan_create();
if (!chan) {
sk_free(sk);
+ sock->sk = NULL;
return NULL;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 4/8] Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
` (2 preceding siblings ...)
2024-10-07 21:34 ` [PATCH v2 3/8] Bluetooth: L2CAP: do not leave dangling sk pointer on error in l2cap_sock_create() Ignat Korchagin
@ 2024-10-07 21:34 ` Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create() Ignat Korchagin
` (4 subsequent siblings)
8 siblings, 0 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:34 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
bt_sock_alloc() attaches allocated sk object to the provided sock object.
If rfcomm_dlc_alloc() fails, we release the sk object, but leave the
dangling pointer in the sock object, which may cause use-after-free.
Fix this by swapping calls to bt_sock_alloc() and rfcomm_dlc_alloc().
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
---
net/bluetooth/rfcomm/sock.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 37d63d768afb..0d0c4311da57 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -274,13 +274,13 @@ static struct sock *rfcomm_sock_alloc(struct net *net, struct socket *sock,
struct rfcomm_dlc *d;
struct sock *sk;
- sk = bt_sock_alloc(net, sock, &rfcomm_proto, proto, prio, kern);
- if (!sk)
+ d = rfcomm_dlc_alloc(prio);
+ if (!d)
return NULL;
- d = rfcomm_dlc_alloc(prio);
- if (!d) {
- sk_free(sk);
+ sk = bt_sock_alloc(net, sock, &rfcomm_proto, proto, prio, kern);
+ if (!sk) {
+ rfcomm_dlc_free(d);
return NULL;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
` (3 preceding siblings ...)
2024-10-07 21:34 ` [PATCH v2 4/8] Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc() Ignat Korchagin
@ 2024-10-07 21:34 ` Ignat Korchagin
2024-10-08 2:37 ` Vincent MAILHOL
2024-10-07 21:35 ` [PATCH v2 6/8] net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() Ignat Korchagin
` (3 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:34 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
On error can_create() frees the allocated sk object, but sock_init_data()
has already attached it to the provided sock object. This will leave a
dangling sk pointer in the sock object and may cause use-after-free later.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
---
net/can/af_can.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 707576eeeb58..01f3fbb3b67d 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -171,6 +171,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
/* release sk on errors */
sock_orphan(sk);
sock_put(sk);
+ sock->sk = NULL;
}
errout:
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 6/8] net: ieee802154: do not leave a dangling sk pointer in ieee802154_create()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
` (4 preceding siblings ...)
2024-10-07 21:34 ` [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create() Ignat Korchagin
@ 2024-10-07 21:35 ` Ignat Korchagin
2024-10-08 8:12 ` Miquel Raynal
2024-10-07 21:35 ` [PATCH v2 7/8] net: inet: do not leave a dangling sk pointer in inet_create() Ignat Korchagin
` (2 subsequent siblings)
8 siblings, 1 reply; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:35 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
sock_init_data() attaches the allocated sk object to the provided sock
object. If ieee802154_create() fails later, the allocated sk object is
freed, but the dangling pointer remains in the provided sock object, which
may allow use-after-free.
Clear the sk pointer in the sock object on error.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
---
net/ieee802154/socket.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/net/ieee802154/socket.c b/net/ieee802154/socket.c
index 990a83455dcf..18d267921bb5 100644
--- a/net/ieee802154/socket.c
+++ b/net/ieee802154/socket.c
@@ -1043,19 +1043,21 @@ static int ieee802154_create(struct net *net, struct socket *sock,
if (sk->sk_prot->hash) {
rc = sk->sk_prot->hash(sk);
- if (rc) {
- sk_common_release(sk);
- goto out;
- }
+ if (rc)
+ goto out_sk_release;
}
if (sk->sk_prot->init) {
rc = sk->sk_prot->init(sk);
if (rc)
- sk_common_release(sk);
+ goto out_sk_release;
}
out:
return rc;
+out_sk_release:
+ sk_common_release(sk);
+ sock->sk = NULL;
+ goto out;
}
static const struct net_proto_family ieee802154_family_ops = {
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 7/8] net: inet: do not leave a dangling sk pointer in inet_create()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
` (5 preceding siblings ...)
2024-10-07 21:35 ` [PATCH v2 6/8] net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() Ignat Korchagin
@ 2024-10-07 21:35 ` Ignat Korchagin
2024-10-07 21:35 ` [PATCH v2 8/8] inet6: do not leave a dangling sk pointer in inet6_create() Ignat Korchagin
2024-10-07 21:57 ` [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Kuniyuki Iwashima
8 siblings, 0 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:35 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
sock_init_data() attaches the allocated sk object to the provided sock
object. If inet_create() fails later, the sk object is freed, but the
sock object retains the dangling pointer, which may create use-after-free
later.
Clear the sk pointer in the sock object on error.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
---
net/ipv4/af_inet.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index b24d74616637..8095e82de808 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -376,32 +376,30 @@ static int inet_create(struct net *net, struct socket *sock, int protocol,
inet->inet_sport = htons(inet->inet_num);
/* Add to protocol hash chains. */
err = sk->sk_prot->hash(sk);
- if (err) {
- sk_common_release(sk);
- goto out;
- }
+ if (err)
+ goto out_sk_release;
}
if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk);
- if (err) {
- sk_common_release(sk);
- goto out;
- }
+ if (err)
+ goto out_sk_release;
}
if (!kern) {
err = BPF_CGROUP_RUN_PROG_INET_SOCK(sk);
- if (err) {
- sk_common_release(sk);
- goto out;
- }
+ if (err)
+ goto out_sk_release;
}
out:
return err;
out_rcu_unlock:
rcu_read_unlock();
goto out;
+out_sk_release:
+ sk_common_release(sk);
+ sock->sk = NULL;
+ goto out;
}
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v2 8/8] inet6: do not leave a dangling sk pointer in inet6_create()
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
` (6 preceding siblings ...)
2024-10-07 21:35 ` [PATCH v2 7/8] net: inet: do not leave a dangling sk pointer in inet_create() Ignat Korchagin
@ 2024-10-07 21:35 ` Ignat Korchagin
2024-10-07 21:57 ` [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Kuniyuki Iwashima
8 siblings, 0 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-07 21:35 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan
Cc: kernel-team, kuniyu, alibuda, Ignat Korchagin
sock_init_data() attaches the allocated sk pointer to the provided sock
object. If inet6_create() fails later, the sk object is released, but the
sock object retains the dangling sk pointer, which may cause use-after-free
later.
Clear the sock sk pointer on error.
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
---
net/ipv6/af_inet6.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index ba69b86f1c7d..f60ec8b0f8ea 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -252,31 +252,29 @@ static int inet6_create(struct net *net, struct socket *sock, int protocol,
*/
inet->inet_sport = htons(inet->inet_num);
err = sk->sk_prot->hash(sk);
- if (err) {
- sk_common_release(sk);
- goto out;
- }
+ if (err)
+ goto out_sk_release;
}
if (sk->sk_prot->init) {
err = sk->sk_prot->init(sk);
- if (err) {
- sk_common_release(sk);
- goto out;
- }
+ if (err)
+ goto out_sk_release;
}
if (!kern) {
err = BPF_CGROUP_RUN_PROG_INET_SOCK(sk);
- if (err) {
- sk_common_release(sk);
- goto out;
- }
+ if (err)
+ goto out_sk_release;
}
out:
return err;
out_rcu_unlock:
rcu_read_unlock();
goto out;
+out_sk_release:
+ sk_common_release(sk);
+ sock->sk = NULL;
+ goto out;
}
static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
--
2.39.5
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails
2024-10-07 21:34 ` [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails Ignat Korchagin
@ 2024-10-07 21:47 ` Kuniyuki Iwashima
2024-10-08 0:20 ` Jakub Kicinski
1 sibling, 0 replies; 15+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-07 21:47 UTC (permalink / raw)
To: ignat
Cc: alex.aring, alibuda, davem, dsahern, edumazet, johan.hedberg,
kernel-team, kuba, kuniyu, linux-bluetooth, linux-can,
linux-kernel, linux-wpan, luiz.dentz, marcel, miquel.raynal, mkl,
netdev, pabeni, socketcan, stable, stefan, willemdebruijn.kernel
From: Ignat Korchagin <ignat@cloudflare.com>
Date: Mon, 7 Oct 2024 22:34:55 +0100
> We have recently noticed the exact same KASAN splat as in commit
> 6cd4a78d962b ("net: do not leave a dangling sk pointer, when socket
> creation fails"). The problem is that commit did not fully address the
> problem, as some pf->create implementations do not use sk_common_release
> in their error paths.
>
> For example, we can use the same reproducer as in the above commit, but
> changing ping to arping. arping uses AF_PACKET socket and if packet_create
> fails, it will just sk_free the allocated sk object.
>
> While we could chase all the pf->create implementations and make sure they
> NULL the freed sk object on error from the socket, we can't guarantee
> future protocols will not make the same mistake.
>
> So it is easier to just explicitly NULL the sk pointer upon return from
> pf->create in __sock_create. We do know that pf->create always releases the
> allocated sk object on error, so if the pointer is not NULL, it is
> definitely dangling.
>
> Fixes: 6cd4a78d962b ("net: do not leave a dangling sk pointer, when socket creation fails")
> Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
` (7 preceding siblings ...)
2024-10-07 21:35 ` [PATCH v2 8/8] inet6: do not leave a dangling sk pointer in inet6_create() Ignat Korchagin
@ 2024-10-07 21:57 ` Kuniyuki Iwashima
8 siblings, 0 replies; 15+ messages in thread
From: Kuniyuki Iwashima @ 2024-10-07 21:57 UTC (permalink / raw)
To: ignat
Cc: alex.aring, alibuda, davem, dsahern, edumazet, johan.hedberg,
kernel-team, kuba, kuniyu, linux-bluetooth, linux-can,
linux-kernel, linux-wpan, luiz.dentz, marcel, miquel.raynal, mkl,
netdev, pabeni, socketcan, stefan, willemdebruijn.kernel
> [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions
For the future patches, please specify the target tree, net or net-next.
From: Ignat Korchagin <ignat@cloudflare.com>
Date: Mon, 7 Oct 2024 22:34:54 +0100
> Some protocol family create() implementations have an error path after
> allocating the sk object and calling sock_init_data(). sock_init_data()
> attaches the allocated sk object to the sock object, provided by the
> caller.
>
> If the create() implementation errors out after calling sock_init_data(),
> it releases the allocated sk object, but the caller ends up having a
> dangling sk pointer in its sock object on return. Subsequent manipulations
> on this sock object may try to access the sk pointer, because it is not
> NULL thus creating a use-after-free scenario.
>
> While the first patch in the series should be enough to handle this
> scenario Eric Dumazet suggested that it would be a good idea to refactor
> the code for the af_packet implementation to avoid the error path, which
> leaves a dangling pointer, because it may be better for some tools like
> kmemleak. I went a bit further and tried to actually fix all the
> implementations, which could potentially leave a dangling sk pointer.
I feel patch 2-8 are net-next materials as the first patch is enough
to fix the issue.
Also, once all protocols have moved sock_init_data() after the last
failure point, we can change the patch 1's part to
err = pf->create(net, sock, protocol, kern);
if (err) {
DEBUG_NET_WARN_ON_ONCE(sock->sk);
goto out_module_put;
}
for the future protocols.
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails
2024-10-07 21:34 ` [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails Ignat Korchagin
2024-10-07 21:47 ` Kuniyuki Iwashima
@ 2024-10-08 0:20 ` Jakub Kicinski
1 sibling, 0 replies; 15+ messages in thread
From: Jakub Kicinski @ 2024-10-08 0:20 UTC (permalink / raw)
To: Ignat Korchagin
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, netdev, linux-kernel,
Marcel Holtmann, Johan Hedberg, Luiz Augusto von Dentz,
Oliver Hartkopp, Marc Kleine-Budde, Alexander Aring,
Stefan Schmidt, Miquel Raynal, David Ahern, Willem de Bruijn,
linux-bluetooth, linux-can, linux-wpan, kernel-team, kuniyu,
alibuda, stable
On Mon, 7 Oct 2024 22:34:55 +0100 Ignat Korchagin wrote:
> diff --git a/net/socket.c b/net/socket.c
> index 601ad74930ef..042451f01c65 100644
> --- a/net/socket.c
> +++ b/net/socket.c
> @@ -1574,8 +1574,13 @@ int __sock_create(struct net *net, int family, int type, int protocol,
> rcu_read_unlock();
>
> err = pf->create(net, sock, protocol, kern);
> - if (err < 0)
> + if (err < 0) {
> + /* ->create should release the allocated sock->sk object on error
> + * but it may leave the dangling pointer
> + */
> + sock->sk = NULL;
> goto out_module_put;
> + }
This chunk is already in net, as part of the fix you posted earlier.
Please resend the cleanup portion with the other patches for net-next
on Friday (IOW after net -> net-next merge).
--
pw-bot: cr
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create()
2024-10-07 21:34 ` [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create() Ignat Korchagin
@ 2024-10-08 2:37 ` Vincent MAILHOL
2024-10-08 6:52 ` Ignat Korchagin
0 siblings, 1 reply; 15+ messages in thread
From: Vincent MAILHOL @ 2024-10-08 2:37 UTC (permalink / raw)
To: Ignat Korchagin
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan,
kernel-team, kuniyu, alibuda
Hi Ignat,
Thanks for the patch.
On Tue. 8 Oct. 2024 at 06:37, Ignat Korchagin <ignat@cloudflare.com> wrote:
> On error can_create() frees the allocated sk object, but sock_init_data()
> has already attached it to the provided sock object. This will leave a
> dangling sk pointer in the sock object and may cause use-after-free later.
I was about to suggest that this should be backported to stable, but
after reading the cover letter, I now understand that this patch is
more an improvement to avoid false positives on kmemleak & Cie. Maybe
the description could be a bit more nuanced? After patch 1/8 of this
series, it seems that the use-after-free is not possible anymore.
> Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
See above comment as notwithstanding. This said:
Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
> ---
> net/can/af_can.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/can/af_can.c b/net/can/af_can.c
> index 707576eeeb58..01f3fbb3b67d 100644
> --- a/net/can/af_can.c
> +++ b/net/can/af_can.c
> @@ -171,6 +171,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
> /* release sk on errors */
> sock_orphan(sk);
> sock_put(sk);
> + sock->sk = NULL;
> }
>
> errout:
> --
> 2.39.5
>
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create()
2024-10-08 2:37 ` Vincent MAILHOL
@ 2024-10-08 6:52 ` Ignat Korchagin
0 siblings, 0 replies; 15+ messages in thread
From: Ignat Korchagin @ 2024-10-08 6:52 UTC (permalink / raw)
To: Vincent MAILHOL
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, Miquel Raynal, David Ahern,
Willem de Bruijn, linux-bluetooth, linux-can, linux-wpan,
kernel-team, kuniyu, alibuda
On Tue, Oct 8, 2024 at 3:38 AM Vincent MAILHOL
<mailhol.vincent@wanadoo.fr> wrote:
>
> Hi Ignat,
>
> Thanks for the patch.
>
> On Tue. 8 Oct. 2024 at 06:37, Ignat Korchagin <ignat@cloudflare.com> wrote:
> > On error can_create() frees the allocated sk object, but sock_init_data()
> > has already attached it to the provided sock object. This will leave a
> > dangling sk pointer in the sock object and may cause use-after-free later.
>
> I was about to suggest that this should be backported to stable, but
> after reading the cover letter, I now understand that this patch is
> more an improvement to avoid false positives on kmemleak & Cie. Maybe
> the description could be a bit more nuanced? After patch 1/8 of this
> series, it seems that the use-after-free is not possible anymore.
If we go with Kuniyuki's suggestion in the cover email to replace the
explicit NULL with DEBUG_NET_WARN_ON_ONCE(sock->sk) in __sock_create()
then use-after-free would be possible again except we will easily
catch it. But I will review the description, when I respin the patches
to net-next as requested by Jakub.
> > Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
>
> See above comment as notwithstanding. This said:
>
> Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr>
Thank you.
>
> > ---
> > net/can/af_can.c | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/net/can/af_can.c b/net/can/af_can.c
> > index 707576eeeb58..01f3fbb3b67d 100644
> > --- a/net/can/af_can.c
> > +++ b/net/can/af_can.c
> > @@ -171,6 +171,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
> > /* release sk on errors */
> > sock_orphan(sk);
> > sock_put(sk);
> > + sock->sk = NULL;
> > }
> >
> > errout:
> > --
> > 2.39.5
> >
> >
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 6/8] net: ieee802154: do not leave a dangling sk pointer in ieee802154_create()
2024-10-07 21:35 ` [PATCH v2 6/8] net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() Ignat Korchagin
@ 2024-10-08 8:12 ` Miquel Raynal
0 siblings, 0 replies; 15+ messages in thread
From: Miquel Raynal @ 2024-10-08 8:12 UTC (permalink / raw)
To: Ignat Korchagin
Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
netdev, linux-kernel, Marcel Holtmann, Johan Hedberg,
Luiz Augusto von Dentz, Oliver Hartkopp, Marc Kleine-Budde,
Alexander Aring, Stefan Schmidt, David Ahern, Willem de Bruijn,
linux-bluetooth, linux-can, linux-wpan, kernel-team, kuniyu,
alibuda
Hi Ignat,
ignat@cloudflare.com wrote on Mon, 7 Oct 2024 22:35:00 +0100:
> sock_init_data() attaches the allocated sk object to the provided sock
> object. If ieee802154_create() fails later, the allocated sk object is
> freed, but the dangling pointer remains in the provided sock object, which
> may allow use-after-free.
>
> Clear the sk pointer in the sock object on error.
>
> Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Thanks,
Miquèl
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-10-08 8:12 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-07 21:34 [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 1/8] net: explicitly clear the sk pointer, when pf->create fails Ignat Korchagin
2024-10-07 21:47 ` Kuniyuki Iwashima
2024-10-08 0:20 ` Jakub Kicinski
2024-10-07 21:34 ` [PATCH v2 2/8] af_packet: avoid erroring out after sock_init_data() in packet_create() Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 3/8] Bluetooth: L2CAP: do not leave dangling sk pointer on error in l2cap_sock_create() Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 4/8] Bluetooth: RFCOMM: avoid leaving dangling sk pointer in rfcomm_sock_alloc() Ignat Korchagin
2024-10-07 21:34 ` [PATCH v2 5/8] net: af_can: do not leave a dangling sk pointer in can_create() Ignat Korchagin
2024-10-08 2:37 ` Vincent MAILHOL
2024-10-08 6:52 ` Ignat Korchagin
2024-10-07 21:35 ` [PATCH v2 6/8] net: ieee802154: do not leave a dangling sk pointer in ieee802154_create() Ignat Korchagin
2024-10-08 8:12 ` Miquel Raynal
2024-10-07 21:35 ` [PATCH v2 7/8] net: inet: do not leave a dangling sk pointer in inet_create() Ignat Korchagin
2024-10-07 21:35 ` [PATCH v2 8/8] inet6: do not leave a dangling sk pointer in inet6_create() Ignat Korchagin
2024-10-07 21:57 ` [PATCH v2 0/8] do not leave dangling sk pointers in pf->create functions Kuniyuki Iwashima
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).