Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'tuntap-socket-uid'

Pietro Borrello says:

====================
tuntap: correctly initialize socket uid

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
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+20 -6
+1 -1
drivers/net/tap.c
··· 533 533 q->sock.state = SS_CONNECTED; 534 534 q->sock.file = file; 535 535 q->sock.ops = &tap_socket_ops; 536 - sock_init_data(&q->sock, &q->sk); 536 + sock_init_data_uid(&q->sock, &q->sk, inode->i_uid); 537 537 q->sk.sk_write_space = tap_sock_write_space; 538 538 q->sk.sk_destruct = tap_sock_destruct; 539 539 q->flags = IFF_VNET_HDR | IFF_NO_PI | IFF_TAP;
+1 -1
drivers/net/tun.c
··· 3448 3448 tfile->socket.file = file; 3449 3449 tfile->socket.ops = &tun_socket_ops; 3450 3450 3451 - sock_init_data(&tfile->socket, &tfile->sk); 3451 + sock_init_data_uid(&tfile->socket, &tfile->sk, inode->i_uid); 3452 3452 3453 3453 tfile->sk.sk_write_space = tun_sock_write_space; 3454 3454 tfile->sk.sk_sndbuf = INT_MAX;
+6 -1
include/net/sock.h
··· 1956 1956 * Default socket callbacks and setup code 1957 1957 */ 1958 1958 1959 - /* Initialise core socket variables */ 1959 + /* Initialise core socket variables using an explicit uid. */ 1960 + void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid); 1961 + 1962 + /* Initialise core socket variables. 1963 + * Assumes struct socket *sock is embedded in a struct socket_alloc. 1964 + */ 1960 1965 void sock_init_data(struct socket *sock, struct sock *sk); 1961 1966 1962 1967 /*
+12 -3
net/core/sock.c
··· 3383 3383 } 3384 3384 EXPORT_SYMBOL(sk_stop_timer_sync); 3385 3385 3386 - void sock_init_data(struct socket *sock, struct sock *sk) 3386 + void sock_init_data_uid(struct socket *sock, struct sock *sk, kuid_t uid) 3387 3387 { 3388 3388 sk_init_common(sk); 3389 3389 sk->sk_send_head = NULL; ··· 3403 3403 sk->sk_type = sock->type; 3404 3404 RCU_INIT_POINTER(sk->sk_wq, &sock->wq); 3405 3405 sock->sk = sk; 3406 - sk->sk_uid = SOCK_INODE(sock)->i_uid; 3407 3406 } else { 3408 3407 RCU_INIT_POINTER(sk->sk_wq, NULL); 3409 - sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0); 3410 3408 } 3409 + sk->sk_uid = uid; 3411 3410 3412 3411 rwlock_init(&sk->sk_callback_lock); 3413 3412 if (sk->sk_kern_sock) ··· 3464 3465 smp_wmb(); 3465 3466 refcount_set(&sk->sk_refcnt, 1); 3466 3467 atomic_set(&sk->sk_drops, 0); 3468 + } 3469 + EXPORT_SYMBOL(sock_init_data_uid); 3470 + 3471 + void sock_init_data(struct socket *sock, struct sock *sk) 3472 + { 3473 + kuid_t uid = sock ? 3474 + SOCK_INODE(sock)->i_uid : 3475 + make_kuid(sock_net(sk)->user_ns, 0); 3476 + 3477 + sock_init_data_uid(sock, sk, uid); 3467 3478 } 3468 3479 EXPORT_SYMBOL(sock_init_data); 3469 3480