* [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid
@ 2023-02-04 17:39 Pietro Borrello
2023-02-04 17:39 ` [PATCH net-next v3 1/3] net: add sock_init_data_uid() Pietro Borrello
` (3 more replies)
0 siblings, 4 replies; 8+ messages in thread
From: Pietro Borrello @ 2023-02-04 17:39 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lorenzo Colitti
Cc: Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel, Pietro Borrello
sock_init_data() assumes that the `struct socket` passed in input is
contained in a `struct socket_alloc` allocated with sock_alloc().
However, tap_open() and tun_chr_open() pass a `struct socket` embedded
in a `struct tap_queue` and `struct tun_file` respectively, both
allocated with sk_alloc().
This causes a type confusion when issuing a container_of() with
SOCK_INODE() in sock_init_data() which results in assigning a wrong
sk_uid to the `struct sock` in input.
Due to the type confusion, both sockets happen to have their uid set
to 0, i.e. root.
While it will be often correct, as tuntap devices require
CAP_NET_ADMIN, it may not always be the case.
Not sure how widespread is the impact of this, it seems the socket uid
may be used for network filtering and routing, thus tuntap sockets may
be incorrectly managed.
Additionally, it seems a socket with an incorrect uid may be returned
to the vhost driver when issuing a get_socket() on a tuntap device in
vhost_net_set_backend().
Fix the bugs by adding and using sock_init_data_uid(), which
explicitly takes a uid as argument.
Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
---
Changes in v3:
- Fix the bug by defining and using sock_init_data_uid()
- Link to v2: https://lore.kernel.org/r/20230131-tuntap-sk-uid-v2-0-29ec15592813@diag.uniroma1.it
Changes in v2:
- Shorten and format comments
- Link to v1: https://lore.kernel.org/r/20230131-tuntap-sk-uid-v1-0-af4f9f40979d@diag.uniroma1.it
---
Pietro Borrello (3):
net: add sock_init_data_uid()
tun: tun_chr_open(): correctly initialize socket uid
tap: tap_open(): correctly initialize socket uid
drivers/net/tap.c | 2 +-
drivers/net/tun.c | 2 +-
include/net/sock.h | 7 ++++++-
net/core/sock.c | 15 ++++++++++++---
4 files changed, 20 insertions(+), 6 deletions(-)
---
base-commit: 6d796c50f84ca79f1722bb131799e5a5710c4700
change-id: 20230131-tuntap-sk-uid-78efc80f4b82
Best regards,
--
Pietro Borrello <borrello@diag.uniroma1.it>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH net-next v3 1/3] net: add sock_init_data_uid()
2023-02-04 17:39 [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid Pietro Borrello
@ 2023-02-04 17:39 ` Pietro Borrello
2023-02-06 8:28 ` Eric Dumazet
2023-02-04 17:39 ` [PATCH net-next v3 2/3] tun: tun_chr_open(): correctly initialize socket uid Pietro Borrello
` (2 subsequent siblings)
3 siblings, 1 reply; 8+ messages in thread
From: Pietro Borrello @ 2023-02-04 17:39 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lorenzo Colitti
Cc: Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel, Pietro Borrello
Add sock_init_data_uid() to explicitly initialize the socket uid.
To initialise the socket uid, sock_init_data() assumes a the struct
socket* sock is always embedded in a struct socket_alloc, used to
access the corresponding inode uid. This may not be true.
Examples are sockets created in tun_chr_open() and tap_open().
Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
---
include/net/sock.h | 7 ++++++-
net/core/sock.c | 15 ++++++++++++---
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index dcd72e6285b2..937e842dc930 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -1956,7 +1956,12 @@ void sk_common_release(struct sock *sk);
* Default socket callbacks and setup code
*/
-/* Initialise core socket variables */
+/* Initialise core socket variables using an explicit uid. */
+void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid);
+
+/* Initialise core socket variables.
+ * Assumes struct socket *sock is embedded in a struct socket_alloc.
+ */
void sock_init_data(struct socket *sock, struct sock *sk);
/*
diff --git a/net/core/sock.c b/net/core/sock.c
index f954d5893e79..9f51ee851a85 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3379,7 +3379,7 @@ void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
}
EXPORT_SYMBOL(sk_stop_timer_sync);
-void sock_init_data(struct socket *sock, struct sock *sk)
+void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid)
{
sk_init_common(sk);
sk->sk_send_head = NULL;
@@ -3399,11 +3399,10 @@ void sock_init_data(struct socket *sock, struct sock *sk)
sk->sk_type = sock->type;
RCU_INIT_POINTER(sk->sk_wq, &sock->wq);
sock->sk = sk;
- sk->sk_uid = SOCK_INODE(sock)->i_uid;
} else {
RCU_INIT_POINTER(sk->sk_wq, NULL);
- sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0);
}
+ sk->sk_uid = uid;
rwlock_init(&sk->sk_callback_lock);
if (sk->sk_kern_sock)
@@ -3462,6 +3461,16 @@ void sock_init_data(struct socket *sock, struct sock *sk)
refcount_set(&sk->sk_refcnt, 1);
atomic_set(&sk->sk_drops, 0);
}
+EXPORT_SYMBOL(sock_init_data_uid);
+
+void sock_init_data(struct socket *sock, struct sock *sk)
+{
+ kuid_t uid = sock ?
+ SOCK_INODE(sock)->i_uid :
+ make_kuid(sock_net(sk)->user_ns, 0);
+
+ sock_init_data_uid(sock, sk, uid);
+}
EXPORT_SYMBOL(sock_init_data);
void lock_sock_nested(struct sock *sk, int subclass)
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v3 2/3] tun: tun_chr_open(): correctly initialize socket uid
2023-02-04 17:39 [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid Pietro Borrello
2023-02-04 17:39 ` [PATCH net-next v3 1/3] net: add sock_init_data_uid() Pietro Borrello
@ 2023-02-04 17:39 ` Pietro Borrello
2023-02-06 8:29 ` Eric Dumazet
2023-02-04 17:39 ` [PATCH net-next v3 3/3] tap: tap_open(): " Pietro Borrello
2023-02-06 10:20 ` [PATCH net-next v3 0/3] tuntap: " patchwork-bot+netdevbpf
3 siblings, 1 reply; 8+ messages in thread
From: Pietro Borrello @ 2023-02-04 17:39 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lorenzo Colitti
Cc: Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel, Pietro Borrello
sock_init_data() assumes that the `struct socket` passed in input is
contained in a `struct socket_alloc` allocated with sock_alloc().
However, tun_chr_open() passes a `struct socket` embedded in a `struct
tun_file` allocated with sk_alloc().
This causes a type confusion when issuing a container_of() with
SOCK_INODE() in sock_init_data() which results in assigning a wrong
sk_uid to the `struct sock` in input.
On default configuration, the type confused field overlaps with the
high 4 bytes of `struct tun_struct __rcu *tun` of `struct tun_file`,
NULL at the time of call, which makes the uid of all tun sockets 0,
i.e., the root one.
Fix the assignment by using sock_init_data_uid().
Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
---
drivers/net/tun.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a7d17c680f4a..745131b2d6db 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -3448,7 +3448,7 @@ static int tun_chr_open(struct inode *inode, struct file * file)
tfile->socket.file = file;
tfile->socket.ops = &tun_socket_ops;
- sock_init_data(&tfile->socket, &tfile->sk);
+ sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid);
tfile->sk.sk_write_space = tun_sock_write_space;
tfile->sk.sk_sndbuf = INT_MAX;
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH net-next v3 3/3] tap: tap_open(): correctly initialize socket uid
2023-02-04 17:39 [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid Pietro Borrello
2023-02-04 17:39 ` [PATCH net-next v3 1/3] net: add sock_init_data_uid() Pietro Borrello
2023-02-04 17:39 ` [PATCH net-next v3 2/3] tun: tun_chr_open(): correctly initialize socket uid Pietro Borrello
@ 2023-02-04 17:39 ` Pietro Borrello
2023-02-06 8:30 ` Eric Dumazet
2023-02-06 10:20 ` [PATCH net-next v3 0/3] tuntap: " patchwork-bot+netdevbpf
3 siblings, 1 reply; 8+ messages in thread
From: Pietro Borrello @ 2023-02-04 17:39 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Lorenzo Colitti
Cc: Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel, Pietro Borrello
sock_init_data() assumes that the `struct socket` passed in input is
contained in a `struct socket_alloc` allocated with sock_alloc().
However, tap_open() passes a `struct socket` embedded in a `struct
tap_queue` allocated with sk_alloc().
This causes a type confusion when issuing a container_of() with
SOCK_INODE() in sock_init_data() which results in assigning a wrong
sk_uid to the `struct sock` in input.
On default configuration, the type confused field overlaps with
padding bytes between `int vnet_hdr_sz` and `struct tap_dev __rcu
*tap` in `struct tap_queue`, which makes the uid of all tap sockets 0,
i.e., the root one.
Fix the assignment by using sock_init_data_uid().
Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
---
drivers/net/tap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index a2be1994b389..8941aa199ea3 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -533,7 +533,7 @@ static int tap_open(struct inode *inode, struct file *file)
q->sock.state = SS_CONNECTED;
q->sock.file = file;
q->sock.ops = &tap_socket_ops;
- sock_init_data(&q->sock, &q->sk);
+ sock_init_data_uid(&q->sock, &q->sk, inode->i_uid);
q->sk.sk_write_space = tap_sock_write_space;
q->sk.sk_destruct = tap_sock_destruct;
q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
--
2.25.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 1/3] net: add sock_init_data_uid()
2023-02-04 17:39 ` [PATCH net-next v3 1/3] net: add sock_init_data_uid() Pietro Borrello
@ 2023-02-06 8:28 ` Eric Dumazet
0 siblings, 0 replies; 8+ messages in thread
From: Eric Dumazet @ 2023-02-06 8:28 UTC (permalink / raw)
To: Pietro Borrello
Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Lorenzo Colitti,
Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel
On Sat, Feb 4, 2023 at 6:39 PM Pietro Borrello
<borrello@diag.uniroma1.it> wrote:
>
> Add sock_init_data_uid() to explicitly initialize the socket uid.
> To initialise the socket uid, sock_init_data() assumes a the struct
> socket* sock is always embedded in a struct socket_alloc, used to
> access the corresponding inode uid. This may not be true.
> Examples are sockets created in tun_chr_open() and tap_open().
>
> Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
> Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
> ---
Reviewed-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 2/3] tun: tun_chr_open(): correctly initialize socket uid
2023-02-04 17:39 ` [PATCH net-next v3 2/3] tun: tun_chr_open(): correctly initialize socket uid Pietro Borrello
@ 2023-02-06 8:29 ` Eric Dumazet
0 siblings, 0 replies; 8+ messages in thread
From: Eric Dumazet @ 2023-02-06 8:29 UTC (permalink / raw)
To: Pietro Borrello
Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Lorenzo Colitti,
Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel
On Sat, Feb 4, 2023 at 6:39 PM Pietro Borrello
<borrello@diag.uniroma1.it> wrote:
>
> sock_init_data() assumes that the `struct socket` passed in input is
> contained in a `struct socket_alloc` allocated with sock_alloc().
> However, tun_chr_open() passes a `struct socket` embedded in a `struct
> tun_file` allocated with sk_alloc().
> This causes a type confusion when issuing a container_of() with
> SOCK_INODE() in sock_init_data() which results in assigning a wrong
> sk_uid to the `struct sock` in input.
> On default configuration, the type confused field overlaps with the
> high 4 bytes of `struct tun_struct __rcu *tun` of `struct tun_file`,
> NULL at the time of call, which makes the uid of all tun sockets 0,
> i.e., the root one.
> Fix the assignment by using sock_init_data_uid().
>
> Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
> Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
> ---
Reviewed-by: Eric Dumazet <edumazet@google.com>
Thanks.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 3/3] tap: tap_open(): correctly initialize socket uid
2023-02-04 17:39 ` [PATCH net-next v3 3/3] tap: tap_open(): " Pietro Borrello
@ 2023-02-06 8:30 ` Eric Dumazet
0 siblings, 0 replies; 8+ messages in thread
From: Eric Dumazet @ 2023-02-06 8:30 UTC (permalink / raw)
To: Pietro Borrello
Cc: David S. Miller, Jakub Kicinski, Paolo Abeni, Lorenzo Colitti,
Stephen Hemminger, Cristiano Giuffrida, Bos, H.J., Jakob Koschel,
netdev, linux-kernel
On Sat, Feb 4, 2023 at 6:39 PM Pietro Borrello
<borrello@diag.uniroma1.it> wrote:
>
> sock_init_data() assumes that the `struct socket` passed in input is
> contained in a `struct socket_alloc` allocated with sock_alloc().
> However, tap_open() passes a `struct socket` embedded in a `struct
> tap_queue` allocated with sk_alloc().
> This causes a type confusion when issuing a container_of() with
> SOCK_INODE() in sock_init_data() which results in assigning a wrong
> sk_uid to the `struct sock` in input.
> On default configuration, the type confused field overlaps with
> padding bytes between `int vnet_hdr_sz` and `struct tap_dev __rcu
> *tap` in `struct tap_queue`, which makes the uid of all tap sockets 0,
> i.e., the root one.
> Fix the assignment by using sock_init_data_uid().
>
> Fixes: 86741ec25462 ("net: core: Add a UID field to struct sock.")
> Signed-off-by: Pietro Borrello <borrello@diag.uniroma1.it>
> ---
Reviewed-by: Eric Dumazet <edumazet@google.com>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid
2023-02-04 17:39 [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid Pietro Borrello
` (2 preceding siblings ...)
2023-02-04 17:39 ` [PATCH net-next v3 3/3] tap: tap_open(): " Pietro Borrello
@ 2023-02-06 10:20 ` patchwork-bot+netdevbpf
3 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+netdevbpf @ 2023-02-06 10:20 UTC (permalink / raw)
To: Pietro Borrello
Cc: davem, edumazet, kuba, pabeni, lorenzo, stephen, c.giuffrida,
h.j.bos, jkl820.git, netdev, linux-kernel
Hello:
This series was applied to netdev/net-next.git (master)
by David S. Miller <davem@davemloft.net>:
On Sat, 04 Feb 2023 17:39:19 +0000 you wrote:
> sock_init_data() assumes that the `struct socket` passed in input is
> contained in a `struct socket_alloc` allocated with sock_alloc().
> However, tap_open() and tun_chr_open() pass a `struct socket` embedded
> in a `struct tap_queue` and `struct tun_file` respectively, both
> allocated with sk_alloc().
> This causes a type confusion when issuing a container_of() with
> SOCK_INODE() in sock_init_data() which results in assigning a wrong
> sk_uid to the `struct sock` in input.
>
> [...]
Here is the summary with links:
- [net-next,v3,1/3] net: add sock_init_data_uid()
https://git.kernel.org/netdev/net-next/c/584f3742890e
- [net-next,v3,2/3] tun: tun_chr_open(): correctly initialize socket uid
https://git.kernel.org/netdev/net-next/c/a096ccca6e50
- [net-next,v3,3/3] tap: tap_open(): correctly initialize socket uid
https://git.kernel.org/netdev/net-next/c/66b2c338adce
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-02-06 10:20 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-04 17:39 [PATCH net-next v3 0/3] tuntap: correctly initialize socket uid Pietro Borrello
2023-02-04 17:39 ` [PATCH net-next v3 1/3] net: add sock_init_data_uid() Pietro Borrello
2023-02-06 8:28 ` Eric Dumazet
2023-02-04 17:39 ` [PATCH net-next v3 2/3] tun: tun_chr_open(): correctly initialize socket uid Pietro Borrello
2023-02-06 8:29 ` Eric Dumazet
2023-02-04 17:39 ` [PATCH net-next v3 3/3] tap: tap_open(): " Pietro Borrello
2023-02-06 8:30 ` Eric Dumazet
2023-02-06 10:20 ` [PATCH net-next v3 0/3] tuntap: " patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox