Skip to content

Commit 86741ec

Browse files
lcolittidavem330
authored andcommitted
net: core: Add a UID field to struct sock.
Protocol sockets (struct sock) don't have UIDs, but most of the time, they map 1:1 to userspace sockets (struct socket) which do. Various operations such as the iptables xt_owner match need access to the "UID of a socket", and do so by following the backpointer to the struct socket. This involves taking sk_callback_lock and doesn't work when there is no socket because userspace has already called close(). Simplify this by adding a sk_uid field to struct sock whose value matches the UID of the corresponding struct socket. The semantics are as follows: 1. Whenever sk_socket is non-null: sk_uid is the same as the UID in sk_socket, i.e., matches the return value of sock_i_uid. Specifically, the UID is set when userspace calls socket(), fchown(), or accept(). 2. When sk_socket is NULL, sk_uid is defined as follows: - For a socket that no longer has a sk_socket because userspace has called close(): the previous UID. - For a cloned socket (e.g., an incoming connection that is established but on which userspace has not yet called accept): the UID of the socket it was cloned from. - For a socket that has never had an sk_socket: UID 0 inside the user namespace corresponding to the network namespace the socket belongs to. Kernel sockets created by sock_create_kern are a special case of #1 and sk_uid is the user that created them. For kernel sockets created at network namespace creation time, such as the per-processor ICMP and TCP sockets, this is the user that created the network namespace. Signed-off-by: Lorenzo Colitti <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 0d53072 commit 86741ec

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

include/net/sock.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,7 @@ struct sock {
419419
u32 sk_max_ack_backlog;
420420
__u32 sk_priority;
421421
__u32 sk_mark;
422+
kuid_t sk_uid;
422423
struct pid *sk_peer_pid;
423424
const struct cred *sk_peer_cred;
424425
long sk_rcvtimeo;
@@ -1664,13 +1665,19 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
16641665
sk->sk_wq = parent->wq;
16651666
parent->sk = sk;
16661667
sk_set_socket(sk, parent);
1668+
sk->sk_uid = SOCK_INODE(parent)->i_uid;
16671669
security_sock_graft(sk, parent);
16681670
write_unlock_bh(&sk->sk_callback_lock);
16691671
}
16701672

16711673
kuid_t sock_i_uid(struct sock *sk);
16721674
unsigned long sock_i_ino(struct sock *sk);
16731675

1676+
static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk)
1677+
{
1678+
return sk ? sk->sk_uid : make_kuid(net->user_ns, 0);
1679+
}
1680+
16741681
static inline u32 net_tx_rndhash(void)
16751682
{
16761683
u32 v = prandom_u32();

net/core/sock.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2460,8 +2460,11 @@ void sock_init_data(struct socket *sock, struct sock *sk)
24602460
sk->sk_type = sock->type;
24612461
sk->sk_wq = sock->wq;
24622462
sock->sk = sk;
2463-
} else
2463+
sk->sk_uid = SOCK_INODE(sock)->i_uid;
2464+
} else {
24642465
sk->sk_wq = NULL;
2466+
sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0);
2467+
}
24652468

24662469
rwlock_init(&sk->sk_callback_lock);
24672470
lockdep_set_class_and_name(&sk->sk_callback_lock,

net/socket.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,22 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
518518
return used;
519519
}
520520

521+
int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
522+
{
523+
int err = simple_setattr(dentry, iattr);
524+
525+
if (!err) {
526+
struct socket *sock = SOCKET_I(d_inode(dentry));
527+
528+
sock->sk->sk_uid = iattr->ia_uid;
529+
}
530+
531+
return err;
532+
}
533+
521534
static const struct inode_operations sockfs_inode_ops = {
522535
.listxattr = sockfs_listxattr,
536+
.setattr = sockfs_setattr,
523537
};
524538

525539
/**

0 commit comments

Comments
 (0)