mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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. [Backport of net-next 86741ec25462e4c8cdce6df2f41ead05568c7d5e] Bug: 16355602 Change-Id: I73e1a57dfeedf672f4c2dfc9ce6867838b55974b Signed-off-by: Lorenzo Colitti <lorenzo@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Kevin F. Haggerty <haggertk@lineageos.org>
This commit is contained in:
parent
941eda2515
commit
d3cd043531
3 changed files with 25 additions and 1 deletions
|
@ -374,6 +374,7 @@ struct sock {
|
||||||
void *sk_security;
|
void *sk_security;
|
||||||
#endif
|
#endif
|
||||||
__u32 sk_mark;
|
__u32 sk_mark;
|
||||||
|
kuid_t sk_uid;
|
||||||
u32 sk_classid;
|
u32 sk_classid;
|
||||||
struct cg_proto *sk_cgrp;
|
struct cg_proto *sk_cgrp;
|
||||||
void (*sk_state_change)(struct sock *sk);
|
void (*sk_state_change)(struct sock *sk);
|
||||||
|
@ -1592,6 +1593,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
|
||||||
sk->sk_wq = parent->wq;
|
sk->sk_wq = parent->wq;
|
||||||
parent->sk = sk;
|
parent->sk = sk;
|
||||||
sk_set_socket(sk, parent);
|
sk_set_socket(sk, parent);
|
||||||
|
sk->sk_uid = SOCK_INODE(parent)->i_uid;
|
||||||
security_sock_graft(sk, parent);
|
security_sock_graft(sk, parent);
|
||||||
write_unlock_bh(&sk->sk_callback_lock);
|
write_unlock_bh(&sk->sk_callback_lock);
|
||||||
}
|
}
|
||||||
|
@ -1599,6 +1601,11 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
|
||||||
int sock_i_uid(struct sock *sk);
|
int sock_i_uid(struct sock *sk);
|
||||||
unsigned long sock_i_ino(struct sock *sk);
|
unsigned long sock_i_ino(struct sock *sk);
|
||||||
|
|
||||||
|
static inline kuid_t sock_net_uid(const struct net *net, const struct sock *sk)
|
||||||
|
{
|
||||||
|
return sk ? sk->sk_uid : make_kuid(net->user_ns, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static inline struct dst_entry *
|
static inline struct dst_entry *
|
||||||
__sk_dst_get(struct sock *sk)
|
__sk_dst_get(struct sock *sk)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2093,8 +2093,11 @@ void sock_init_data(struct socket *sock, struct sock *sk)
|
||||||
sk->sk_type = sock->type;
|
sk->sk_type = sock->type;
|
||||||
sk->sk_wq = sock->wq;
|
sk->sk_wq = sock->wq;
|
||||||
sock->sk = sk;
|
sock->sk = sk;
|
||||||
} else
|
sk->sk_uid = SOCK_INODE(sock)->i_uid;
|
||||||
|
} else {
|
||||||
sk->sk_wq = NULL;
|
sk->sk_wq = NULL;
|
||||||
|
sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0);
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_init(&sk->sk_dst_lock);
|
spin_lock_init(&sk->sk_dst_lock);
|
||||||
rwlock_init(&sk->sk_callback_lock);
|
rwlock_init(&sk->sk_callback_lock);
|
||||||
|
|
14
net/socket.c
14
net/socket.c
|
@ -521,9 +521,23 @@ static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sockfs_setattr(struct dentry *dentry, struct iattr *iattr)
|
||||||
|
{
|
||||||
|
int err = simple_setattr(dentry, iattr);
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
struct socket *sock = SOCKET_I(dentry->d_inode);
|
||||||
|
|
||||||
|
sock->sk->sk_uid = iattr->ia_uid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct inode_operations sockfs_inode_ops = {
|
static const struct inode_operations sockfs_inode_ops = {
|
||||||
.getxattr = sockfs_getxattr,
|
.getxattr = sockfs_getxattr,
|
||||||
.listxattr = sockfs_listxattr,
|
.listxattr = sockfs_listxattr,
|
||||||
|
.setattr = sockfs_setattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue